Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 108487 Details for
Bug 133099
Providing the ability to record user's interactions with GEF objects in a GEF editor
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Patch manifesting refactorings to org.eclipse.tptp.test.auto.gui (not including added icons)
AGR_PATCH_26_07_08.txt (text/plain), 1.01 MB, created by
Alexander Nyßen
on 2008-07-26 15:30:21 EDT
(
hide
)
Description:
Patch manifesting refactorings to org.eclipse.tptp.test.auto.gui (not including added icons)
Filename:
MIME Type:
Creator:
Alexander Nyßen
Created:
2008-07-26 15:30:21 EDT
Size:
1.01 MB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.tptp.test.auto.gui >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ToggleStructuredCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/ToggleStructuredCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 ToggleStructuredCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/ToggleStructuredCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/ToggleStructuredCommand.java 26 Jul 2008 19:22:03 -0000 >@@ -16,84 +16,84 @@ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > import org.w3c.dom.Node; > > public abstract class ToggleStructuredCommand extends AbstractStructuredCommand { >+ > protected boolean itemState; > > /** > * @param wid > */ >- public ToggleStructuredCommand(MacroCommandShell parent, WidgetIdentifier wid) { >- super(parent, wid); >+ public ToggleStructuredCommand(MacroCommandShell parent) { >+ super(parent); > } >- >- >+ > /** > * There are more incomming events, merge them appropriately > * >- * @param e The event to be merged with this command >+ * @param e >+ * The event to be merged with this command > */ >- public boolean mergeEvent(Event e) >- { >+ public boolean mergeEvent(Event e) throws Exception { > ArrayList itemMatches = super.getItems(); >- >- if (e.item != null && itemState == getItemState(e.item)) >- { >+ >+ if (e.item != null && itemState == getItemState(e.item)) { > itemMatches.add(super.getItemAttributes(e.item)); > return true; > } >- >+ > return false; > } >- >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >- super.load(node, lineTable); >- String att = MacroUtil.getAttribute(node, MacroConstants.VALUE_ATTRIBUTE); >- this.itemState = att!=null && att.equals(MacroConstants.TRUE_VALUE); >- } >- >- protected void writeAdditionalAttributes(StringBuffer sb) >- { >- MacroUtil.addAttribute(sb, >- new String[]{MacroConstants.VALUE_ATTRIBUTE}, >- new String[]{itemState?MacroConstants.TRUE_VALUE:MacroConstants.FALSE_VALUE}, >- false, false); >+ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, >+ lineTable); >+ String att = MacroUtil.getAttribute(node, >+ MacroConstants.VALUE_ATTRIBUTE); >+ this.itemState = att != null && att.equals(MacroConstants.TRUE_VALUE); >+ } >+ >+ protected void writeAdditionalAttributes(StringBuffer sb) { >+ MacroUtil.addAttribute(sb, >+ new String[] {MacroConstants.VALUE_ATTRIBUTE}, >+ new String[] {itemState >+ ? MacroConstants.TRUE_VALUE >+ : MacroConstants.FALSE_VALUE}, >+ false, >+ false); > } > >- > public boolean getValue() { > return itemState; > } >- >+ > /** >- * Overwirte this method to indicate that if there are two toggle commands >- * with different values, then they are not the same. >+ * Overwirte this method to indicate that if there are two toggle commands with different values, then they are not the same. > * >- * @param obj The object that this object will be comapred against >+ * @param obj >+ * The object that this object will be comapred against > */ >- public boolean equals (Object obj) >- { >+ public boolean equals(Object obj) { > if (!(obj instanceof ToggleStructuredCommand) || !super.equals(obj)) > return false; >- >- ToggleStructuredCommand compareWithObj = (ToggleStructuredCommand)obj; >+ >+ ToggleStructuredCommand compareWithObj = (ToggleStructuredCommand) obj; > if (compareWithObj.getValue() == this.getValue()) > return true; >- >+ > return false; > } >- >+ > /** >- * Returns the state of the item (e.g. whether it is check/unchecked, expanded/ >- * collapsed, and etc...) >+ * Returns the state of the item (e.g. whether it is check/unchecked, expanded/ collapsed, and etc...) > * >- * @param item The item for which its state is being queried >+ * @param item >+ * The item for which its state is being queried > * @return The state of the item > */ >- public abstract boolean getItemState (Widget item); >+ public abstract boolean getItemState(Widget item); > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/MouseEventCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/MouseEventCommand.java,v >retrieving revision 1.2 >diff -u -r1.2 MouseEventCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/MouseEventCommand.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/MouseEventCommand.java 26 Jul 2008 19:22:01 -0000 >@@ -11,167 +11,168 @@ > *******************************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.commands; > >-import java.util.ArrayList; > import java.util.Hashtable; > > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > import org.eclipse.ui.PlatformUI; > import org.w3c.dom.Node; > > /** >- * A concrete extension of PositionBasedCommand used to represent SWT.MouseUp and SWT.MouseDown >- * events. >+ * A concrete extension of PositionBasedCommand used to represent SWT.MouseUp >+ * and SWT.MouseDown and SWT.MouseMove events. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen (refactored and added mouse move event support) > */ >-public class MouseEventCommand extends PositionBasedCommand >-{ >- public static final String TYPE0 = "mouse-up"; >- public static final String TYPE1 = "mouse-down"; >- public static final String TYPE2 = "mouse-click"; >- >- private String type; /* The type of this command (either TYPE0 or TYPE1) */ >- private int button; /* The mouse button that was pressed or released */ >- private Point coordinates; /* Keep track of the coordinates */ >- >+public class MouseEventCommand extends PositionBasedCommand { >+ >+ private Point coordinates; /* Keep track of the coordinates */ >+ > private static Point lastCoordinates; >- >- public MouseEventCommand(MacroCommandShell parent) >- { >- super(parent, WidgetIdentifier.NULL_IDENTIFIER); >+ >+ public MouseEventCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public void processEvent(Event event) throws Exception { >+ super.processEvent(event); >+ coordinates = PlatformUI.getWorkbench().getDisplay() >+ .getCursorLocation(); >+ } >+ >+ protected String determineType(Event e) { >+ String type = null; >+ if (e.type == SWT.MouseUp) { >+ type = MOUSE_UP; >+ } else if (e.type == SWT.MouseDown) { >+ type = MOUSE_DOWN; >+ } else if (e.type == SWT.MouseMove) { >+ type = MOUSE_MOVE; >+ } > return type; > } > >- public void processEvent(Event e) >- { >- coordinates = PlatformUI.getWorkbench().getDisplay().getCursorLocation(); >- button = e.button; >- >- if (e.type == SWT.MouseUp) >- { >- /* Defect #: 110726 -- If the previous event was a mouse down event at the same >- * exact location, then replace the two of them with the mouse click event */ >- ArrayList commands = getParent().getCommands(); >- int commandSize; >- if (commands != null && (commandSize = commands.size()) > 0) >- { >- Object lastCommand = commands.get(commandSize - 1); >- if (lastCommand instanceof MouseEventCommand) >- { >- Point lastCommandCoordinates = ((MouseEventCommand)lastCommand).getCoordinates(); >- if (lastCommandCoordinates.equals(coordinates)) >- { >- type = TYPE2; >- commands.remove(commandSize - 1); >- return; >- } >- } >- } >- >- type = TYPE0; >- } >- else if (e.type == SWT.MouseDown) >- type = TYPE1; >- } >- >- public int getDetail() >- { >- return button; >+ protected Integer determineDetail(Event e) { >+ if (e.button > 0) { >+ return new Integer(e.button); >+ } else { >+ return null; >+ } >+ } >+ >+ public boolean mergeEvent(Event e) throws Exception { >+ /* >+ * Defect #: 110726 -- If the previous event was a mouse down event at >+ * the same exact location, then replace the two of them with the mouse >+ * click event (ANy: As merging of position based commands is now >+ * supported, this defect can be handled here more elegantly) >+ */ >+ if (e.type == SWT.MouseUp >+ && type != null >+ && type.equals(MOUSE_DOWN) >+ && coordinates != null >+ && coordinates.equals(PlatformUI.getWorkbench().getDisplay() >+ .getCursorLocation()) >+ && (detail == null || detail.intValue() == e.button)) { >+ type = MOUSE_CLICK; >+ return true; >+ } >+ // if the last command was a mouse move command, and this one as well, >+ // the >+ // last may be ignored. >+ else if (e.type == SWT.MouseMove && type != null >+ && type.equals(MOUSE_MOVE)) { >+ coordinates = PlatformUI.getWorkbench().getDisplay() >+ .getCursorLocation(); >+ return true; >+ } else { >+ return super.mergeEvent(e); >+ } > } > >- public Event[] constructSWTEvents() >- { >+ public Event[] constructSWTEvents() { > Event[] mouseEvents; >- if (type.equals(TYPE2)) >+ if (type.equals(MOUSE_CLICK)) > mouseEvents = new Event[2]; > else > mouseEvents = new Event[1]; >- >- Event mouseUpEvent = new Event(), >- mouseDownEvent= new Event(); >- >- mouseUpEvent.type = SWT.MouseUp; >- mouseDownEvent.type = SWT.MouseDown; >- >- mouseUpEvent.button = button; >- mouseDownEvent.button = button; >- >- if (type.equals(TYPE0)) >- mouseEvents[0] = mouseUpEvent; >- >- else if (type.equals(TYPE1)) >- mouseEvents[0] = mouseDownEvent; >- >- else if (type.equals(TYPE2)) >- { >- mouseEvents[0] = mouseDownEvent; >- mouseEvents[1] = mouseUpEvent; >+ >+ if (type.equals(MOUSE_UP)) { >+ mouseEvents[0] = new Event(); >+ mouseEvents[0].type = SWT.MouseUp; >+ mouseEvents[0].button = detail.intValue(); >+ } else if (type.equals(MOUSE_DOWN)) { >+ mouseEvents[0] = new Event(); >+ mouseEvents[0].type = SWT.MouseDown; >+ mouseEvents[0].button = detail.intValue(); >+ } else if (type.equals(MOUSE_CLICK)) { >+ mouseEvents[0] = new Event(); >+ mouseEvents[0].type = SWT.MouseDown; >+ mouseEvents[0].button = detail.intValue(); >+ mouseEvents[1] = new Event(); >+ mouseEvents[1].type = SWT.MouseUp; >+ mouseEvents[1].button = detail.intValue(); >+ } else if (type.equals(MOUSE_MOVE)) { >+ mouseEvents[0] = new Event(); >+ mouseEvents[0].type = SWT.MouseMove; >+ mouseEvents[0].x = coordinates.x; >+ mouseEvents[0].y = coordinates.y; > } >- >+ > return mouseEvents; > } >- > >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); >- >- type = MacroUtil.getAttribute(node, "type"); >+ >+ // load coordinates > int x = Integer.parseInt(MacroUtil.getAttribute(node, "x-coord")); > int y = Integer.parseInt(MacroUtil.getAttribute(node, "y-coord")); >- button = Integer.parseInt(MacroUtil.getAttribute(node, "detail")); >- coordinates = new Point (x, y); >+ coordinates = new Point(x, y); > } >- >- public void write(int indent, StringBuffer sb, boolean close, boolean end) >- { >- super.write(indent, sb, close, end); >- MacroUtil.addAttribute(sb, >- new String[] { >- MacroConstants.X_COORD_ATTRIBUTE, >- MacroConstants.Y_COORD_ATTRIBUTE, >- }, >- new String[] { >- String.valueOf(coordinates.x), >- String.valueOf(coordinates.y), >- } >- , true, true); >+ >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ super.write(indent, sb, false, false); >+ MacroUtil.addAttribute(sb, new String[] { >+ MacroConstants.X_COORD_ATTRIBUTE, >+ MacroConstants.Y_COORD_ATTRIBUTE, }, >+ new String[] { String.valueOf(coordinates.x), >+ String.valueOf(coordinates.y), }, true, true); > } >- >+ > /** > * Plays back this command > */ >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- /* It's important not to move the cursor if the last command had the same cursor position as this one */ >- if (lastCoordinates == null || !lastCoordinates.equals(coordinates)) >- { >+ public boolean playback(final Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ /* >+ * It's important not to move the cursor if the last command had the >+ * same cursor position as this one >+ */ >+ if (lastCoordinates == null || !lastCoordinates.equals(coordinates)) { > display.setCursorLocation(coordinates.x, coordinates.y); > } > lastCoordinates = coordinates; > return super.playback(display, parent, monitor); > } >- >- public boolean equals (Object obj) >- { >+ >+ public boolean equals(Object obj) { > if (!(obj instanceof MouseEventCommand)) > return false; >- >- MouseEventCommand mouseEvent = (MouseEventCommand)obj; >- if (this.type.equals(mouseEvent.getType()) && this.button == mouseEvent.getButton() && this.coordinates.equals(mouseEvent.getCoordinates())) >+ >+ MouseEventCommand mouseEvent = (MouseEventCommand) obj; >+ if (this.type.equals(mouseEvent.getType()) >+ && this.detail == mouseEvent.getDetail() >+ && this.coordinates.equals(mouseEvent.getCoordinates())) > return true; > return false; > } >@@ -180,12 +181,8 @@ > return coordinates; > } > >- public int getButton() { >- return button; >- } >- >- public static void init() >- { >+ // TODO: This is ugly, it has to be removed >+ public static void init() { > lastCoordinates = null; > } > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/MacroCommandShell.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/MacroCommandShell.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/MacroCommandShell.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/MacroCommandShell.java 3 May 2007 01:49:31 -0000 1.6 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,1493 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2007 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import java.util.ArrayList; >-import java.util.Hashtable; >-import java.util.Vector; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.Path; >-import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.SubProgressMonitor; >-import org.eclipse.jface.dialogs.MessageDialog; >-import org.eclipse.jface.window.Window; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.SWTException; >-import org.eclipse.swt.custom.CCombo; >-import org.eclipse.swt.custom.CTabFolder; >-import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Combo; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Display; >-import org.eclipse.swt.widgets.Event; >-import org.eclipse.swt.widgets.List; >-import org.eclipse.swt.widgets.Listener; >-import org.eclipse.swt.widgets.MenuItem; >-import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.TabFolder; >-import org.eclipse.swt.widgets.Table; >-import org.eclipse.swt.widgets.Text; >-import org.eclipse.swt.widgets.ToolItem; >-import org.eclipse.swt.widgets.Tree; >-import org.eclipse.swt.widgets.TreeItem; >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IPlayable; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWritable; >-import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction; >-import org.eclipse.tptp.test.auto.gui.internal.macro.Macro; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound; >-import org.w3c.dom.Node; >-import org.w3c.dom.NodeList; >- >-/** >- * Keeps track of the macro commands while they are being captured. >- */ >-public class MacroCommandShell extends AbstractMacroInstruction >-{ >- /* The commands of this macro shell */ >- private ArrayList commands; >- >- /* The expected return code */ >- private int expectedReturnCode; >- >- /* The last event received */ >- private transient Event lastEvent; >- >- /* The display object */ >- private transient Display display; >- >- /* The shell that this macro command shell represents */ >- private transient Shell shell; >- >- /* The reference id of the macro shell object */ >- private String referenceId; >- >- /* The title of the shell that this macro command shell represents */ >- private String shellTitle; >- >- private transient Window window; >- >- /* Indicates user interaction -- Set when a key up event is received */ >- private transient boolean isKeyPressed; >- >- /* Indicates user interaction -- Set when a mouse up event is received */ >- private transient boolean isMousePressed; >- >- /* Stores an event that is only acknowledged followed by user interaction. */ >- private transient Event toBeAckEvent; >- >- /* Set when the stored event in toBeAckEvent is acknowledged */ >- private transient boolean ackEvent; >- >- /* Set when there is a listener registered with this MacroCommandShell */ >- private transient boolean isListenerRegistered; >- >- /* Stores the time for which a command was last created in */ >- private long lastCommandCreationTime; >- >- /* A queue of nested shell waiting to be activated (this is used during playback) */ >- private static Vector nestedShellQueue; >- >- /* Last index of the nested shell queue */ >- private static int lastNestedShellInx; >- >- /* Stores the last command line executed */ >- private static int lastCommandLineExecuted; >- >- /* Mutual lock used to block when a command is being executed. This lock is used to forcefully wake up >- * the thread that this object is running in if the command has caused a stall */ >- private Boolean mutualLock; >- >- /* A mutual lock shared across multiple instances of this class -- It's general purpose is to lock shared static resources */ >- private static Boolean mutualGlobalLock; >- >- /* The parent of this macro command shell. This is null if this macro shell command is the root */ >- private MacroCommandShell parent; >- >- /* The index of the command being executed -- this will correspond to the last command index if isComplete = true */ >- private int currentCommandInx; >- >- /* Indicates if all the commands of this shell has been completed */ >- private boolean isComplete; >- >- /* Indicates that the process needs to be interrupted -- due to an error */ >- private static boolean interruptProcess; >- >- /* Set to true when process has been terminated */ >- private static boolean processTerminated; >- >- /* The exception causing the interruption */ >- private static Throwable interruptedException; >- >- /* A central container for all macro command operation being played */ >- private static Vector macroCommandsBeingPlayed; >- >- /* A central container for all instances of this class */ >- private static Vector macroCommandShellContainer; >- >- >- /* A central repository for all macro command shells */ >- static >- { >- nestedShellQueue = new Vector(); >- macroCommandsBeingPlayed = new Vector(); >- macroCommandShellContainer = new Vector(); >- mutualGlobalLock = new Boolean(true); >- } >- >- >- public MacroCommandShell(MacroCommandShell parent) >- { >- this(parent, null, null); >- } >- >- public MacroCommandShell(MacroCommandShell parent, Shell shell, WidgetIdentifier wid) >- { >- setWidgetId(wid); >- commands = new ArrayList(); >- this.shell = shell; >- this.shellTitle = shell == null || shell.isDisposed() ? null : shell.getText(); >- hookWindow(false); >- expectedReturnCode = -1; >- isListenerRegistered = false; >- mutualLock = new Boolean(true); >- this.parent = parent; >- isComplete = false; >- macroCommandShellContainer.add (this); >- } >- >- private void hookWindow(boolean playback) >- { >- if (shell != null) >- { >- if (!playback) >- doHookWindow(); >- else >- display.syncExec(new Runnable() >- { >- public void run() >- { >- doHookWindow(); >- } >- }); >- } >- } >- >- private void doHookWindow() >- { >- Object data = shell.getData(); >- if (data != null && data instanceof Window) >- this.window = (Window) data; >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable) >- */ >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >- super.load(node, lineTable); >- >- /* If the corresponding shell of this command is referenced then attempt to find >- * the corresponding object in the object mine. */ >- setCorrespondingObject(MacroObjectLocator.lookupReferenceId(null, node, lineTable)); >- boolean useObjectMine = getCorrespondingObject() != null; >- setWidgetId(new WidgetIdentifier( >- null, >- new Path(useObjectMine ? getCorrespondingObject().getObjectId() : MacroUtil.getAttribute(node, MacroConstants.ID_ATTRIBUTE)), >- useObjectMine ? getCorrespondingObject().getResolverId() : MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE))); >- String codeId = MacroUtil.getAttribute(node, MacroConstants.RETURN_CODE_ATTRIBUTE); >- if (codeId != null) >- { >- try >- { >- expectedReturnCode = new Integer(codeId).intValue(); >- } catch (NumberFormatException e) >- { >- } >- } >- NodeList children = node.getChildNodes(); >- for (int i = 0; i < children.getLength(); i++) >- { >- Node child = children.item(i); >- if (child.getNodeType() == Node.ELEMENT_NODE) >- { >- String name = child.getNodeName(); >- if (name.equals(MacroConstants.COMMAND_ELEMENT)) >- processCommand(child, lineTable); >- else if (name.equals(MacroConstants.SHELL_ELEMENT)) >- processShell(child, lineTable); >- } >- } >- } >- >- /** >- * Used to process the node that is passed in as argument, the lineTable hashtable indicates >- * the range of line numbers that the node corresponds to in the macro script >- * >- * @param node The node to be processed >- * @param lineTable The line number range that the node corresponds to in the script. >- */ >- private void processCommand(Node node, Hashtable lineTable) throws CoreException >- { >- IUIObject commandObject = MacroObjectLocator.lookupReferenceId(getCorrespondingObject(), node, lineTable); >- boolean isObjectFound = commandObject != null; >- >- String cid = isObjectFound ? commandObject.getContextId() : MacroUtil.getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE); >- String wid = isObjectFound ? commandObject.getObjectId() : MacroUtil.getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE); >- String rid = isObjectFound ? commandObject.getResolverId() : MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE); >- String type = MacroUtil.getAttribute(node, MacroConstants.TYPE_ATTRIBUTE); >- if (type == null) >- return; >- AbstractMacroCommand command = null; >- WidgetIdentifier wi = (wid != null && cid != null) ? new WidgetIdentifier(new Path(cid), new Path(wid), rid) : null; >- >- >- if (type.equals(ModifyCommand.TYPE)) >- command = new ModifyCommand(this, wi); >- >- else if (type.equals(BooleanSelectionCommand.TYPE)) >- command = new BooleanSelectionCommand(this, wi); >- >- else if (type.equals(StructuredSelectionCommand.ITEM_SELECT) || type.equals(StructuredSelectionCommand.DEFAULT_SELECT)) >- command = new StructuredSelectionCommand(this, wi, type); >- >- else if (type.equals(ExpansionCommand.TYPE)) >- command = new ExpansionCommand(this, wi); >- >- else if (type.equals(CheckCommand.TYPE)) >- command = new CheckCommand(this, wi); >- >- else if (type.equals(FocusCommand.TYPE)) >- command = new FocusCommand(this, wi); >- >- else if (type.equals(ChoiceSelectionCommand.TYPE)) >- command = new ChoiceSelectionCommand(this, wi); >- >- else if (type.equals(WaitCommand.TYPE)) >- command = new WaitCommand(this); >- >- /* The verification command */ >- else if (type.equals(VerificationCommand.TYPE)) >- command = new VerificationCommand(this, new VerificationMetaData()); >- >- /* The close workbench part command */ >- else if (type.equals(CloseWorkbenchPartCommand.TYPE)) >- command = new CloseWorkbenchPartCommand(this, wi); >- >- /* Mouse events */ >- else if (type.equals(MouseEventCommand.TYPE0) || type.equals(MouseEventCommand.TYPE1) || type.equals(MouseEventCommand.TYPE2)) >- command = new MouseEventCommand (this); >- >- /* Key events */ >- else if (type.equals(KeyEventCommand.TYPE0) || type.equals(KeyEventCommand.TYPE1) || type.equals(KeyEventCommand.TYPE2)) >- command = new KeyEventCommand (this); >- >- if (command != null) >- { >- command.setCorrespondingObject(commandObject); >- command.load(node, lineTable); >- commands.add(command); >- } >- } >- >- >- private void processShell(Node node, Hashtable lineTable) throws CoreException >- { >- MacroCommandShell shell = new MacroCommandShell(this); >- shell.load(node, lineTable); >- commands.add(shell); >- } >- >- >- public void addCommandShell(MacroCommandShell cshell) >- { >- commands.add(cshell); >- } >- >- public void write(int indent, StringBuffer sb) >- { >- /* If this shell command doesn't have any commands, then exit */ >- if (commands == null || commands.size() <= 0) >- return; >- >- /* <shell */ >- MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, false, false); >- boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn() && getWidgetId().getReferenceId() != null; >- MacroUtil.addAttribute(sb, >- new String[] { MacroConstants.DESCRIPTIVE_ATTRIBUTE, >- MacroConstants.RESOLVER_ATTRIBUTE, >- MacroConstants.ID_ATTRIBUTE, >- MacroConstants.REFERENCE_ID_ATTRIBUTE, >- MacroConstants.RETURN_CODE_ATTRIBUTE}, >- new String[] { getDescriptiveField(), >- objectMineInUse ? null : getWidgetId().getResolverId(), >- objectMineInUse ? null : getWidgetId().getObjectId().toString(), >- objectMineInUse ? getWidgetId().getReferenceId() : null, >- String.valueOf(expectedReturnCode)}, false, true >- ); >- int cindent = indent + 1; >- for (int i = 0; i < commands.size(); i++) >- { >- IWritable writable = (IWritable) commands.get(i); >- writable.writeStart(cindent, sb); >- writable.write(cindent, sb); >- writable.writeFinish(cindent, sb); >- } >- MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, true, true); >- } >- >- public String getDescriptiveField() >- { >- return shellTitle == null ? null : MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(shellTitle, AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND)); >- } >- >- public void addEvent(Event event) >- { >- if (event.widget instanceof Control) >- { >- if (((Control) event.widget).isVisible() == false) >- return; >- } >- >- AbstractMacroCommand command = null; >- if (event.detail == MacroManager.POSITION_BASED_EVENT) >- command = createPositionBasedCommand(event); >- else >- command = createCommand(event); >- >- if (command != null) >- { >- AbstractMacroCommand lastCommand = getLastCommand(); >- >- /* Take out the last command if it is a focus command and the command just passed in implicitly does a focus */ >- if (lastCommand != null && >- (lastCommand.getWidgetId() != null && lastCommand.getWidgetId().equals(command.getWidgetId()) && lastCommand.getType().equals(FocusCommand.TYPE) && isFocusCommand(command.getType()))) >- { >- // focus followed by select or modify - focus implied >- commands.remove(lastCommand); >- } >- >- /* Modify the last event accordinggly */ >- if (ackEvent) >- { >- ackEvent = false; >- lastEvent = toBeAckEvent; >- toBeAckEvent = null; >- } >- else >- { >- lastEvent = event; >- } >- >- /* Add the artificial wait time if required */ >- if (MacroManager.getInstance().isArtificialWaitOn() && lastCommandCreationTime > 0) >- { >- long currentTime = System.currentTimeMillis(); >- long difference = currentTime - lastCommandCreationTime; >- command.setTimeDifference(difference); >- } >- >- lastCommandCreationTime = System.currentTimeMillis(); >- >- /* Ali M.: The following block of code provides a workaround for a limitation that >- * exists for CloseWorkbenchPartCommand. We are only able to capture this event >- * after the entire part has been disposed. Things would be ideal if this event >- * could be captured right after the user clicks on the close button of the part */ >- if (command instanceof CloseWorkbenchPartCommand) >- { >- int commandSize = commands.size(); >- if (commandSize > 0) >- { >- /* If the last command corresponds to the message dialog that prompts the >- * user to save an editor, then store it after the close command */ >- Object lastCommandStored = commands.get(commandSize - 1); >- if (lastCommandStored instanceof MacroCommandShell && /* If the last stored command is a shell */ >- ((CloseWorkbenchPartCommand)command).getWidgetId().getContextId().equals(MacroConstants.EDITOR_VALUE) && /* If the part is an editor */ >- ((MacroCommandShell)lastCommandStored).getWidgetId().getObjectId().equals(MessageDialog.class.getName())) /* If the shell is a MessageDialog */ >- >- { >- commands.add(commandSize - 1 , command); >- return; >- } >- } >- >- } >- /* Added for defect 164197 in order to add an item-expansion to the parent whenever the >- * child is selected in a case where the parent has been pre-expanded. >- * Liz D. >- */ >- if (command instanceof StructuredSelectionCommand && event.widget instanceof Tree){ >- >- StructuredSelectionCommand s = (StructuredSelectionCommand)command; >- >- TreeItem[] items = (TreeItem [])s.getItemsForEvent(event); >- for (int i=0; i<items.length; i++) >- { >- TreeItem selectedItem = (TreeItem) items[i]; >- >- while(selectedItem.getParentItem()!=null) >- { >- TreeItem parent = selectedItem.getParentItem(); >- if (parent.getExpanded()== true) >- {//necessary so that we only apply this in the case where the parent is already expanded >- Event expansionEvent = new Event(); >- expansionEvent.widget = parent; >- expansionEvent.item = parent; >- ExpansionCommand parentExpand = new ExpansionCommand(this, command.getWidgetId()); >- parentExpand.processEvent(expansionEvent, true); >- commands.add(parentExpand); >- } >- selectedItem = parent; >- }// end while >- } >- } >- >- commands.add(command);} >- >- } >- >- >- /** >- * Adds a wait command for as long as the last command is not already a wait (i.e. >- * duplicate addition of wait commands are avoided through this method) >- */ >- public void addPause() >- { >- WaitCommand command = new WaitCommand(this); >- >- Object lastCommand = null; >- int commandSize = commands.size(); >- boolean isLastCommandWait = false; >- >- if (commandSize <= 0) >- return; >- >- lastCommand = commands.get (commandSize - 1); >- int lastCmdInx = 2; >- >- /* Avoid MacroCommandShells that have no commands (since these will not be included >- * as part of the macro) */ >- while (lastCommand instanceof MacroCommandShell && ((MacroCommandShell)lastCommand).getCommands().size() <= 0) >- { >- if (commandSize - lastCmdInx >= 0) >- lastCommand = commands.get (commandSize - lastCmdInx); >- else >- { >- lastCommand = null; >- break; >- } >- >- lastCmdInx++; >- } >- >- AbstractMacroCommand lastMacroCommand = null; >- if (lastCommand instanceof AbstractMacroCommand) >- lastMacroCommand = (AbstractMacroCommand)lastCommand; >- >- isLastCommandWait = lastMacroCommand != null && lastMacroCommand.getType() == WaitCommand.TYPE; >- if (commands.size() > 0 && !isLastCommandWait) >- { >- commands.add(command); >- } >- } >- >- public void addVerificationCommand (VerificationCommand command) >- { >- commands.add(command); >- } >- >- public void extractExpectedReturnCode() >- { >- if (window != null) >- expectedReturnCode = window.getReturnCode(); >- } >- >- public boolean matchesReturnCode() >- { >- if (window != null) >- { >- return window.getReturnCode() == expectedReturnCode; >- } >- return true; >- } >- >- private boolean isFocusCommand(String type) >- { >- return type.equals(BooleanSelectionCommand.TYPE) || type.equals(StructuredSelectionCommand.ITEM_SELECT) || type.equals(StructuredSelectionCommand.DEFAULT_SELECT) || type.equals(ExpansionCommand.TYPE) || type.equals(CheckCommand.TYPE) || type.equals(ModifyCommand.TYPE); >- } >- >- /** >- * Handles position-based events >- */ >- protected AbstractMacroCommand createPositionBasedCommand (Event event) >- { >- AbstractMacroCommand command = null; >- >- switch (event.type) >- { >- case SWT.MouseUp: >- case SWT.MouseDown: >- case SWT.MouseDoubleClick: >- command = new MouseEventCommand (this); >- break; >- >- case SWT.KeyUp: >- case SWT.KeyDown: >- command = new KeyEventCommand (this); >- break; >- >- } >- >- if (command != null) >- command.processEvent (event); >- return command; >- } >- >- >- /** >- * Handles object-based events >- */ >- protected AbstractMacroCommand createCommand(Event event) >- { >- /* A quick way to get out if we're only getting key up or mouse events that have been detected before */ >- if ((isKeyPressed && event.type == SWT.KeyUp) || (isMousePressed && event.type == SWT.MouseUp)) >- return null; >- >- AbstractMacroCommand lastCommand = getLastCommand(); >- if (lastEvent != null && lastEvent.widget != null && lastEvent.widget.equals(event.widget)) >- { >- if (lastEvent.type == event.type || (lastEvent.type == SWT.Selection && event.type == SWT.DefaultSelection)) >- { >- if (lastCommand != null && lastCommand.mergeEvent(event)) >- return null; >- } >- } >- >- AbstractMacroCommand command = null; >- >- /* Check to see if we are a drop-down menu selection */ >- if (lastCommand != null && lastCommand.getType() == BooleanSelectionCommand.TYPE && >- ((BooleanSelectionCommand)lastCommand).getDetail() == SWT.DROP_DOWN) >- { >- ((BooleanSelectionCommand)lastCommand).setItemSelected (event); >- return null; >- } >- >- >- WidgetIdentifier wi = MacroUtil.getWidgetIdentifier(event.widget); >- if (wi == null) >- wi = MacroUtil.getCustomEventIdentifier(event); >- if (wi == null) >- return null; >- >- >- switch (event.type) >- { >- case SWT.Modify: >- if (!isEditable(event.widget)) >- return null; >- >- /* This block of code is used to avoid displaying the browse native dialog when the user clicks >- * a browse button - it doesn't cover all cases */ >- if (lastEvent != null && lastEvent.type == SWT.Selection && lastEvent.widget instanceof Button) >- { >- String text = ((Button)lastEvent.widget).getText(); >- if (text != null) >- { >- text = text.replaceAll("\\&", ""); >- text = text.toLowerCase(); >- if (text.indexOf(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BROWSE) != -1) >- { >- ArrayList commands = this.getCommands(); >- int size = 0; >- if (commands != null && (size = commands.size()) > 0) >- { >- commands.remove(size - 1); >- command = new ModifyCommand(this, MacroUtil.getWidgetIdentifier(event.widget)); >- break; >- } >- } >- } >- } >- >- /* Only acknowledge modifies that are followed by a key up event */ >- toBeAckEvent = event; >- break; >- >- case SWT.Selection: >- case SWT.DefaultSelection: >- command = createSelectionCommand(wi, event); >- break; >- >- case SWT.FocusIn: >- /** >- * Ali M.: While recording, the SWT display listener has the tendency to report >- * focus events on controls that are actually not visible to the user. When the >- * macro is played back, the control cannot be located. To avoid this problem >- * we only acknowledge focus events that are followed by a mouse up or key up event (i.e. >- * The user explicitly focuses on the control). >- */ >- toBeAckEvent = event; >- break; >- >- case SWT.Expand: >- case SWT.Collapse: >- command = new ExpansionCommand(this, wi); >- >- break; >- >- case SWT.KeyUp: >- isKeyPressed = true; >- if (toBeAckEvent != null && toBeAckEvent.type == SWT.Modify) >- { >- command = new ModifyCommand(this, MacroUtil.getWidgetIdentifier(toBeAckEvent.widget)); >- ackEvent = true; >- break; >- } >- >- case SWT.MouseUp: >- isMousePressed = true; >- if (toBeAckEvent != null && toBeAckEvent.type == SWT.FocusIn) >- { >- command = new FocusCommand(this, MacroUtil.getWidgetIdentifier(toBeAckEvent.widget)); >- ackEvent = true; >- } >- break; >- case Macro.WORKBENCH_PART_CLOSED: >- /* 110810 -- Create the close workbench command only if there is only one frame >- * in our shell stack */ >- if (MacroManager.getInstance().getCurrentMacro().getShellStackSize() == 1) >- command = new CloseWorkbenchPartCommand (this, wi); >- break; >- } >- >- if (event.type != SWT.KeyUp) >- isKeyPressed = false; >- else if (event.type != SWT.MouseUp) >- isMousePressed = false; >- >- >- if (command != null) >- { >- /* Lookup the widget of this command. If it already exists in our object mine, then >- * have it referenced by setting the reference id of the command. */ >- IObjectMine objectMine = MacroManager.getInstance().getObjectMine(); >- IUIObject uiObject = null; >- WidgetIdentifier commandWidgetIdentifier = command.getWidgetId(); >- boolean needsDescriptiveField = false; >- try >- { >- IUIObject activeObject = objectMine.getActiveObject(); >- uiObject = objectMine.lookupUIObject(activeObject, commandWidgetIdentifier.getContextId() == null ? null : commandWidgetIdentifier.getContextId().toString(), commandWidgetIdentifier.getObjectId().toString()); >- >- /* The object is not registered with the object mine - register it */ >- if (uiObject == null) >- { >- needsDescriptiveField = true; >- uiObject = UIObject.createInstance(objectMine, command, activeObject); >- objectMine.registerObject(uiObject); >- } >- commandWidgetIdentifier.setReferenceId(uiObject.getReferenceId()); >- } >- >- /* We can't afford to show an error message in case of an unexpected error during >- * registeration. We'll ignore the error and not make use of the object mine. */ >- catch (UIObjectNotFound e) >- { >- /* Should not happen */ >- } catch (IDCollisionException e) >- { >- /* Should not happen */ >- } catch (CoreException e) >- { >- /* Should not happen */ >- } >- >- command.processEvent(event); >- >- if (needsDescriptiveField && uiObject != null) >- { >- uiObject.setDescriptive(command.getObjectClassName(event.widget) + (command.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING : ": " + command.getDescriptiveField())); >- } >- } >- >- /* Ensure that redundant commands are not created */ >- if (lastCommand != null && command != null && command.isRepeatRedundant() && command.equals(lastCommand)) >- { >- return null; >- } >- return command; >- } >- >- private boolean isEditable(Widget widget) >- { >- if (widget instanceof Control) >- { >- Control control = (Control) widget; >- if (!control.isEnabled()) >- return false; >- if (control instanceof Text) >- return ((Text) control).getEditable(); >- if (control instanceof Combo || control instanceof CCombo) >- return ((control.getStyle() & SWT.READ_ONLY) == 0); >- if (control instanceof StyledText) >- return ((StyledText) control).getEditable(); >- } >- return true; >- } >- >- private AbstractMacroCommand createSelectionCommand(WidgetIdentifier wid, Event event) >- { >- if (event.widget instanceof MenuItem || event.widget instanceof ToolItem || (event.widget instanceof Button >- /* A CCombo will cause a button selection followed by a combo selection. >- * We need to ignore the button selection */ >- && !(event.widget instanceof Control && ((Control)event.widget).getParent() instanceof CCombo))) >- { >- if (event.x != 0 || event.y != 0 || event.detail != 0) >- return new BooleanSelectionCommand(this, wid, new Point (event.x, event.y), event.detail); >- return new BooleanSelectionCommand(this, wid); >- } >- >- if (event.widget instanceof Tree || event.widget instanceof Table || event.widget instanceof List) >- { >- if (event.detail == SWT.CHECK) >- return new CheckCommand(this, wid); >- String type = event.type == SWT.DefaultSelection ? StructuredSelectionCommand.DEFAULT_SELECT : StructuredSelectionCommand.ITEM_SELECT; >- return new StructuredSelectionCommand(this, wid, type); >- } >- >- if (event.widget instanceof TabFolder || event.widget instanceof CTabFolder) >- return new ChoiceSelectionCommand(this, wid); >- >- if (event.widget instanceof Combo || event.widget instanceof CCombo) >- return new ChoiceSelectionCommand(this, wid); >- >- return null; >- } >- >- >- private AbstractMacroCommand getLastCommand() >- { >- if (commands.size() > 0) >- { >- Object item = commands.get(commands.size() - 1); >- if (item instanceof AbstractMacroCommand) >- return (AbstractMacroCommand) item; >- } >- return null; >- } >- >- public boolean isDisposed() >- { >- return this.shell != null && this.shell.isDisposed(); >- } >- >- public void close() >- { >- if (this.shell != null && !this.shell.isDisposed()) >- this.shell.close(); >- } >- >- public boolean tracks(Shell shell) >- { >- if (this.shell != null && this.shell.equals(shell)) >- return true; >- return false; >- } >- >- public boolean playback(final Display display, Composite parent, final IProgressMonitor monitor) throws CoreException >- { >- if (parent instanceof Shell) >- { >- this.shell = (Shell) parent; >- this.display = display; >- hookWindow(true); >- } >- >- NestedShell nestedShell = null; >- int commandSize = commands.size(); >- monitor.beginTask("", commandSize); >- final int commandTimeOut; >- >- int potentialTimeoutValue = MacroManager.getInstance().getCommandTimeoutThreshold(); >- if (MacroManager.getInstance().getCommandTimeoutThreshold() > 0) >- commandTimeOut = potentialTimeoutValue; >- else >- commandTimeOut = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD; >- >- for (int i = 0; i < commandSize; i++) >- { >- currentCommandInx = i; >- checkForInterruptions(); >- Object c = commands.get(i); >- final IPlayable playable = (IPlayable) c; >- >- /* If this is the last command of this macro command shell, then take out its entry in the shell queue */ >- if (isLastCommand(i)) >- { >- if (getNestedShellQueue() != null && getNestedShellQueue().size() > 0) >- { >- if (lastNestedShellInx > 0) >- lastNestedShellInx--; >- removeNestedShell(0); >- } >- } >- >- /* If this command is a nested shell, then we need to wait until it completes before proceeding to the next command. */ >- if (c instanceof MacroCommandShell) >- { >- MacroCommandShell nestedCommandShell = (MacroCommandShell)c; >- //System.out.println("NESTED SHELL WAIT: " + nestedCommandShell.getId()); >- Object lastNestedCommand = null; >- Object currentNestedCommand = null; >- synchronized (nestedCommandShell) >- { >- /* Give each command in the nested shell a maximum of commandTimeOut to execute */ >- while (!nestedCommandShell.isComplete() && (currentNestedCommand == null || lastNestedCommand != currentNestedCommand) && !interruptProcess) >- { >- try >- { >- nestedCommandShell.wait(commandTimeOut); >- lastNestedCommand = currentNestedCommand; >- currentNestedCommand = nestedCommandShell.getCommandBeingExecuted(); >- } catch (InterruptedException e) >- { >- /* Handled by next set of code */ >- } >- } >- >- /* Indicate an error if the nested shell never completed */ >- if (!nestedCommandShell.isComplete()) >- { >- synchronized (mutualGlobalLock) >- { >- interruptProcess = true; >- if (interruptedException == null) >- interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_NEST_TOUT, nestedCommandShell.getWidgetId().getObjectId().toString()), null)); >- } >- >- continue; /* Interrupt the normal flow */ >- } >- //System.out.println("NESTED SHELL FINISH: " + nestedCommandShell.getId()); >- } >- } >- >- if (i < commandSize - 1) >- { >- /* Ali M.: We need to iterate through all the shell commands and register listeners >- * before it's too late. It's not sufficient to just register a listener with the >- * next command */ >- int counter = 1; >- IPlayable next = (IPlayable) commands.get(i + counter); >- while (next instanceof MacroCommandShell) >- { >- /* This command will open a new shell. Add a listener before it is too late */ >- MacroCommandShell nestedCommand = (MacroCommandShell) next; >- >- if (!nestedCommand.isListenerRegistered()) >- { >- nestedShell = new NestedShell(display, nestedCommand, new SubProgressMonitor(monitor, 1)); >- final NestedShell fnestedShell = nestedShell; >- >- >- /* If this is a child of the previous shell, then it takes precedence. If it's a sibling, then it >- * should go to the end of the queue. */ >- nestedCommand.setListenerRegistered(true); >- if (nestedShellQueue.size() > 0 && ((NestedShell)nestedShellQueue.get(0)).isParent(nestedCommand)) >- { >- addNestedShell(0, fnestedShell); >- lastNestedShellInx = 0; >- } >- else >- { >- if (nestedShellQueue.size() > 0) >- addNestedShell(++lastNestedShellInx, fnestedShell); >- else >- addNestedShell(fnestedShell); >- } >- >- display.syncExec(new Runnable() >- { >- public void run() >- { >- //System.out.println("ADDED"); >- display.addFilter(SWT.Activate, fnestedShell); >- } >- }); >- } >- counter++; >- next = (i + counter <= commandSize - 1 ? (IPlayable) commands.get(i + counter) : null); >- } >- } >- if (playable instanceof AbstractMacroCommand) >- { >- final boolean last = i == commandSize - 1; >- >- >- class WakeUpOperaion implements Runnable >- { >- private AbstractMacroCommand command; >- private boolean invalidate; >- >- public WakeUpOperaion (AbstractMacroCommand command) >- { >- this.command = command; >- invalidate = false; >- } >- >- public void run() >- { >- if (!invalidate && MacroCommandShell.lastCommandLineExecuted == command.getStartLine()) >- { >- /* Ali M.: A command just timed-out. We need to indicate the error >- * and wakeup the thread */ >- synchronized (mutualGlobalLock) >- { >- interruptProcess = true; >- if (interruptedException == null) >- interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, command.toString()), null)); >- } >- >- synchronized (mutualLock) >- { >- mutualLock.notify(); >- } >- } >- } >- >- public void invalidate() >- { >- this.invalidate = true; >- } >- >- } >- WakeUpOperaion wakeupOpt = null; >- if (i < commandSize - 1) >- { >- wakeupOpt = new WakeUpOperaion ((AbstractMacroCommand)playable); >- final Runnable wakeupOperation = wakeupOpt; >- display.asyncExec( >- new Runnable() >- { >- public void run() >- { >- display.timerExec(commandTimeOut, wakeupOperation); >- }; >- >- } >- ); >- } >- >- >- class RunCommandOperation implements Runnable >- { >- private boolean isComplete; >- >- public void run() >- { >- try >- { >- if (!macroCommandsBeingPlayed.contains(this)) >- macroCommandsBeingPlayed.add(this); >- >- lastCommandLineExecuted = ((AbstractMacroCommand)playable).getStartLine(); >- playInGUIThread(display, playable, last, monitor); >- >- macroCommandsBeingPlayed.remove(this); >- isComplete = true; >- synchronized (mutualLock) >- { >- mutualLock.notify(); >- } >- } >- catch (Throwable e) >- { >- macroCommandsBeingPlayed.remove(this); >- synchronized (mutualGlobalLock) >- { >- interruptProcess = true; >- if (interruptedException == null) >- interruptedException = e; >- } >- isComplete = true; >- synchronized (mutualLock) >- { >- mutualLock.notify(); >- } >- } >- } >- >- public boolean isComplete() >- { >- return isComplete; >- } >- >- } >- >- RunCommandOperation runCommandOpt = new RunCommandOperation(); >- >- >- /* Run the command */ >- synchronized (mutualLock) >- { >- new Thread(runCommandOpt).start(); >- long start = System.currentTimeMillis(); >- long wakeUpTime = start; >- long timeToSleep = commandTimeOut; >- try >- { >- while (!runCommandOpt.isComplete() && timeToSleep > 0 && !interruptProcess) >- { >- //System.out.println("WAITING on command: " + playable); >- mutualLock.wait(timeToSleep); >- wakeUpTime = System.currentTimeMillis(); >- timeToSleep = timeToSleep - (wakeUpTime - start); >- } >- } catch (InterruptedException e) >- { >- /* Doesn't need to be handled */ >- } >- >- /* Indicate an error if command didn't complete */ >- if (!runCommandOpt.isComplete()) >- { >- synchronized (mutualGlobalLock) >- { >- interruptProcess = true; >- if (interruptedException == null) >- interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, playable.toString()), null)); >- } >- } >- /* Otherwise invalidate the wake up operation that was suppose to wake this >- command up */ >- else if (wakeupOpt != null) >- wakeupOpt.invalidate(); >- >- //System.out.println("FINISHED WAITING on command: " + playable); >- } >- >- monitor.worked(1); >- } >- } >- >- checkForInterruptions(); >- shell = null; >- >- /* We made it out alive -- mark this as complete and wake any parents that are waiting upon our completion */ >- isComplete = true; >- synchronized(this) >- { >- this.notify(); >- } >- >- macroCommandShellContainer.remove(this); >- return true; >- } >- >- >- private boolean isComplete() >- { >- return isComplete; >- } >- >- private Object getCommandBeingExecuted() >- { >- if (commands == null || currentCommandInx >= commands.size()) >- return null; >- return commands.get(currentCommandInx); >- } >- >- private void checkForInterruptions() throws CoreException >- { >- if (interruptProcess) >- { >- /* Wake up all threads in case they are asleep */ >- if (!processTerminated) >- { >- processTerminated = true; >- interruptOperation(); >- MacroCommandShell.macroStopped(); >- MacroUtil.closeSecondaryShells(display); >- } >- >- for (int i = 0; i < macroCommandShellContainer.size(); i++) >- { >- synchronized (mutualLock) >- { >- mutualLock.notify(); >- } >- >- synchronized (macroCommandShellContainer.get(i)) >- { >- macroCommandShellContainer.get(i).notify(); >- } >- } >- >- /* Try to close all nested shells */ >- synchronized (mutualGlobalLock) >- { >- if (interruptedException instanceof CoreException) >- throw (CoreException)interruptedException; >- throw new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, interruptedException.getLocalizedMessage(), interruptedException)); >- } >- } >- >- } >- >- /** >- * A helper method that walks through all macro command shells and >- * interrupts their normal flow. >- */ >- private void interruptOperation() >- { >- MacroCommandShell currentMacroShell = this; >- while (currentMacroShell != null) >- { >- Boolean lock = currentMacroShell.mutualLock; >- synchronized(lock) >- { >- lock.notify(); >- } >- >- currentMacroShell = currentMacroShell.getParent(); >- } >- >- } >- >- private boolean isLastCommand(int index) >- { >- for (int i = index + 1; i < commands.size(); i++) >- { >- if (commands.get(i) instanceof AbstractMacroCommand) >- return false; >- } >- return true; >- } >- >- private void playInGUIThread(final Display display, final IPlayable playable, boolean last, final IProgressMonitor monitor) throws CoreException >- { >- final CoreException[] ex = new CoreException[1]; >- >- Runnable runnable = new Runnable() >- { >- public void run() >- { >- try >- { >- boolean status = playable.playback(display, MacroCommandShell.this.shell, monitor); >- >- /* Something went wrong playing this item */ >- if (!status) >- ex[0] = createPlaybackException(playable, null); >- else >- MacroUtil.processDisplayEvents(display); >- } >- catch (ClassCastException e) >- { >- ex[0] = createPlaybackException(playable, e); >- } >- catch (CoreException e) >- { >- ex[0] = e; >- } >- catch (SWTException e) >- { >- /* Don't handle */ >- } >- catch (Throwable error) >- { >- ex[0] = createPlaybackException(playable, error); >- } >- } >- }; >- >- if (playable instanceof WaitCommand) >- { >- playable.playback(display, this.shell, monitor); >- } >- else >- { >- display.syncExec(runnable); >- } >- >- try >- { >- Thread.sleep(100); >- } catch (InterruptedException e) >- { >- } >- >- if (ex[0] != null) >- throw ex[0]; >- >- } >- >- private CoreException createPlaybackException(IPlayable playable, Throwable th) >- { >- IStatus status = new Status(IStatus.ERROR, "org.eclipse.pde.ui.tests", IStatus.OK, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_COMMAND, playable.toString()), th); >- return new CoreException(status); >- } >- >- >- public ArrayList getCommands() >- { >- return commands; >- } >- >- public boolean isListenerRegistered() { >- return isListenerRegistered; >- } >- >- public void setListenerRegistered(boolean isListenerRegistered) { >- this.isListenerRegistered = isListenerRegistered; >- } >- >- public static Vector getNestedShellQueue() >- { >- return nestedShellQueue; >- } >- >- public static void addNestedShell(int inx, NestedShell nestedShell) >- { >- synchronized (nestedShellQueue) >- { >- if (inx >= 0) >- nestedShellQueue.add(inx, nestedShell); >- else >- nestedShellQueue.add(nestedShell); >- } >- } >- >- private static void addNestedShell(NestedShell fnestedShell) >- { >- addNestedShell (-1, fnestedShell); >- } >- >- >- public static void removeNestedShell(int inx) >- { >- synchronized (nestedShellQueue) >- { >- nestedShellQueue.remove(inx); >- } >- } >- >- >- public static void initializeForNewPlay() >- { >- nestedShellQueue.clear(); >- lastNestedShellInx = 0; >- interruptProcess = false; >- processTerminated = false; >- interruptedException = null; >- MouseEventCommand.init(); >- macroCommandsBeingPlayed.clear(); >- macroCommandShellContainer.clear(); >- } >- >- public Shell getShell() { >- return shell; >- } >- >- public void writeStart(int indent, StringBuffer sb) >- { >- /* Doesn't need to be implemented */ >- } >- >- public void writeFinish(int indent, StringBuffer sb) >- { >- /* Doesn't need to be implemented */ >- } >- >- public MacroCommandShell getParent() { >- return parent; >- } >- >- public void setParent(MacroCommandShell parent) { >- this.parent = parent; >- } >- >- public static void macroStopped() >- { >- /* Walk through nested shell listeners and remove them if any exists */ >- final Display display = GuiPlugin.getDefault().getWorkbench().getDisplay(); >- display.syncExec(new Runnable(){ >- >- public void run() { >- for (int i = 0, nestedShellListenerSize = nestedShellQueue.size(); i < nestedShellListenerSize; i++) >- { >- display.removeFilter(SWT.Activate, (NestedShell)nestedShellQueue.get(i)); >- } >- } >- }); >- } >- >- public static Vector getMacroCommandsBeingPlayed() { >- return macroCommandsBeingPlayed; >- } >- >- public String getReferenceId() >- { >- return referenceId; >- } >- >- public void setReferenceId(String referenceId) >- { >- this.referenceId = referenceId; >- } >- >- >- private static class NestedShell implements Listener, Runnable >- { >- private MacroCommandShell cshell; >- >- private Display display; >- >- private Shell nshell; >- >- private boolean released; >- >- private CoreException exception; >- >- private IProgressMonitor monitor; >- >- private boolean served; >- >- public NestedShell(Display display, MacroCommandShell cshell, IProgressMonitor monitor) >- { >- this.display = display; >- this.cshell = cshell; >- this.monitor = monitor; >- } >- >- public void handleEvent(Event e) >- { >- try >- { >- if (e.widget instanceof Shell) >- { >- // shell activated >- Shell shell = (Shell) e.widget; >- IPath path = new Path(MacroUtil.getShellId(shell, null).toString()); >- String sid = path.toString(); >- >- /* Debug */ >- //System.out.println(); >- //System.out.println(sid + " : " + cshell.getId()); >- //if (MacroCommandShell.getNestedShellQueue() != null && MacroCommandShell.getNestedShellQueue().size() > 0) >- //System.out.println("Is Served: " + ((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed()); >- //System.out.println(this + " : " + MacroCommandShell.getNestedShellQueue().get(0)); >- //System.out.println(); >- >- if (sid.equals(cshell.getWidgetId().getObjectId().toString()) && >- (MacroCommandShell.getNestedShellQueue() == null || >- MacroCommandShell.getNestedShellQueue().size() <= 0 || >- (!((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed() && this.equals(MacroCommandShell.getNestedShellQueue().get(0))))) >- { >- //System.out.println("REMOVED FILTER: " + cshell.getId()); >- shell.getDisplay().removeFilter(SWT.Activate, this); >- released = true; >- this.nshell = shell; >- >- /* We need to start this in a separate thread. MacroCommandShells should not be played in UI threads (otherwise wait commands >- * will not work properly) */ >- this.setServed(true); >- new Thread(this).start(); >- } >- } >- } >- catch (Throwable t) >- { >- //System.out.println("REMOVED filter"); >- /* Something unexpected has happened -- Remove this listener */ >- e.display.removeFilter(SWT.Activate, this); >- } >- } >- >- public void setServed(boolean served) >- { >- this.served = served; >- } >- >- public boolean isServed() >- { >- return served; >- } >- >- public boolean getResult() >- { >- return cshell.matchesReturnCode(); >- } >- >- public boolean isReleased() >- { >- return released; >- } >- >- public void run() >- { >- try >- { >- cshell.playback(display, nshell, monitor); >- } >- catch (CoreException e) >- { >- synchronized (mutualGlobalLock) >- { >- interruptProcess = true; >- if (interruptedException == null) >- interruptedException = e; >- } >- >- synchronized (cshell.mutualLock) >- { >- cshell.mutualLock.notify(); >- } >- } >- } >- >- public CoreException getException() >- { >- return exception; >- } >- >- public boolean isParent(MacroCommandShell macroCommandShell) >- { >- return macroCommandShell.getParent().equals(cshell); >- } >- } >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractStructuredCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractStructuredCommand.java,v >retrieving revision 1.3 >diff -u -r1.3 AbstractStructuredCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractStructuredCommand.java 18 Apr 2008 14:25:04 -0000 1.3 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractStructuredCommand.java 26 Jul 2008 19:21:58 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2006 IBM Corporation and others. > * 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 >@@ -17,11 +17,11 @@ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.hyades.test.common.util.XMLUtil; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Item; > import org.eclipse.swt.widgets.List; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.swt.widgets.Table; > import org.eclipse.swt.widgets.TableItem; > import org.eclipse.swt.widgets.Tree; >@@ -30,67 +30,65 @@ > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject; >-import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport; > import org.w3c.dom.Node; > import org.w3c.dom.NodeList; > > /** >- * An abstract structured command that other commands can optionally >- * extend. >+ * An abstract structured command that other commands can optionally extend. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ >-public abstract class AbstractStructuredCommand extends AbstractMacroCommand >-{ >- /** >- * The items that are associated with the structured selection. The list contains >- * Hashtable entries with the following content: >- * KEY = XML attribute of the item >- * VALUE = The value of the attribute >+public abstract class AbstractStructuredCommand extends ObjectBasedCommand { >+ >+ /** >+ * The items that are associated with the structured selection. The list >+ * contains Hashtable entries with the following content: KEY = XML >+ * attribute of the item VALUE = The value of the attribute > */ > protected ArrayList items; >- >- >+ > /** > * The constructor > * >- * @param parent The parent macro command shell owning this command >- * @param wid The widget identifier >+ * @param parent >+ * The parent macro command shell owning this command >+ * @param wid >+ * The widget identifier > */ >- public AbstractStructuredCommand(MacroCommandShell parent, WidgetIdentifier wid) >- { >- super(parent, wid); >+ public AbstractStructuredCommand(MacroCommandShell parent) { >+ super(parent); > items = new ArrayList(); > } > > /** > * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event) > */ >- public boolean mergeEvent(Event e) >- { >+ public boolean mergeEvent(Event e) throws Exception { > items.clear(); >- processEvent(e); >+ doProcessEvent(e); > return true; > } > >- > /** > * Returns the items that are embedded in the event passed in > * >- * @param event The event >+ * @param event >+ * The event > * @return The items of the event > */ >- protected Object[] getItemsForEvent(Event event) >- { >+ protected Object[] getItemsForEvent(Event event) { > Widget item = null; > if (event.item != null) > item = event.item; >@@ -101,246 +99,300 @@ > return null; > } > >- > /** > * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#processEvent(org.eclipse.swt.widgets.Event) > */ >- public void processEvent(Event event) >- { >+ public void doProcessEvent(Event event) { > Object[] eventItems = getItemsForEvent(event); > boolean isWidget = eventItems instanceof Widget[]; > boolean isString = false; >- >+ > if (!isWidget) > isString = eventItems instanceof String[]; > >- >- /* Populate the items instance variable according to the items of the event */ >- if (eventItems != null) >- { >+ /* >+ * Populate the items instance variable according to the items of the >+ * event >+ */ >+ if (eventItems != null) { > /* For every embedded item */ >- for (int i = 0; i < eventItems.length; i++) >- { >+ for (int i = 0; i < eventItems.length; i++) { > Map attributeValuePairs = null; >- >- if (isWidget) >- { >- attributeValuePairs = getItemAttributes((Widget)eventItems[i]); >- } >- else if (isString) >- { >- attributeValuePairs = getItemAttributes(null, new PrimitiveWidgetId((String)eventItems[i])); >+ >+ if (isWidget) { >+ attributeValuePairs = getItemAttributes((Widget) eventItems[i]); >+ } else if (isString) { >+ attributeValuePairs = getItemAttributes(null, >+ new PrimitiveUIObjectIdentifier( >+ (String) eventItems[i])); > } > >- if (attributeValuePairs != null) >- { >+ if (attributeValuePairs != null) { > items.add(attributeValuePairs); > } > } > } >- >+ > super.findDescriptiveField(eventItems); > } > >- > /** >- * Returns the item attributes that will be used to find and resolve the item >- * that is associated with this structured command. >+ * Returns the item attributes that will be used to find and resolve the >+ * item that is associated with this structured command. > * >- * @param item The item >- * @return A map indicating the item attributes and values; null if the item can't be resolved. >- */ >- protected Map getItemAttributes(Widget item) >- { >- MacroManager macroManager = MacroManager.getInstance(); >- IWidgetId id = macroManager.resolveWidget(item, null, MacroUtil.newCounter()); >- if (id == null) >- { >+ * @param item >+ * The item >+ * @return A map indicating the item attributes and values; null if the item >+ * can't be resolved. >+ */ >+ protected Map getItemAttributes(Widget item) { >+ IUIObjectIdentifier id = null; >+ try { >+ id = UIObjectResolver.resolve(null, new UIObject(item)); >+ } catch (CoreException e) { >+ e.printStackTrace(); >+ } >+ if (id == null) { > id = getDefaultItemAttributes(item); > } >- >- if (id != null) >- { >+ >+ if (id != null) { > return getItemAttributes(item, id); > } >- >- return null; >- } >- >- >- private IWidgetId getDefaultItemAttributes(Widget item) >- { >- Object data = item.getData(); >- >- String idStr = MacroConstants.EMPTY_STRING; >- if (data != null) >- idStr = data.getClass().getName(); >- >- /* Append index to id if it's a table or a tree item */ >- if (item instanceof TreeItem) >- { >- TreeItem treeItem = (TreeItem)item; >- idStr = idStr + findTreeItemInx(treeItem, MacroConstants.EMPTY_STRING); >- } >- else if (item instanceof TableItem) >- { >- TableItem tableItem = (TableItem)item; >- idStr = idStr + tableItem.getParent().indexOf(tableItem); >- } >- if (idStr.length() > 0) >- return new PrimitiveWidgetId(idStr); >- >+ > return null; > } > > /** >- * Returns the item attributes that will be used to find and resolve the item >- * that is associated with this structured command. >+ * Returns the item attributes that will be used to find and resolve the >+ * item that is associated with this structured command. > * >- * @param item The item >- * @param id The item id >- * @return A map indicating the item attributes and values; null if the item can't be resolved. >+ * @param item >+ * The item >+ * @param id >+ * The item id >+ * @return A map indicating the item attributes and values; null if the item >+ * can't be resolved. > */ >- protected Map getItemAttributes(Widget item, IWidgetId id) >- { >+ private Map getItemAttributes(Widget item, IUIObjectIdentifier id) { > Hashtable attributeValuePair = new Hashtable(); >- attributeValuePair.put(MacroConstants.PATH_ATTRIBUTE, id); >- >- IUIObject uiObject = findItemInObjectMine (item, id); >- if (uiObject != null) >- { >- attributeValuePair.put(MacroConstants.REFERENCE_ID_ATTRIBUTE, uiObject.getReferenceId()); >- } >- >- if (id.getResolverId() != null) >- { >- attributeValuePair.put(MacroConstants.RESOLVER_ATTRIBUTE, id.getResolverId()); >+ attributeValuePair.put(MacroConstants.WIDGET_ID_ATTRIBUTE, id); >+ >+ MacroObjectDescriptor uiObject = findItemInObjectMine(item, id); >+ if (uiObject != null) { >+ attributeValuePair.put(MacroConstants.REFERENCE_ID_ATTRIBUTE, >+ uiObject.getReferenceId()); >+ } >+ >+ if (id.getResolverId() != null) { >+ attributeValuePair.put(MacroConstants.RESOLVER_ID_ATTRIBUTE, id >+ .getResolverId()); > } > return attributeValuePair; > } >- > > /** >- * Attempts to find an item in the current object mine. If it's not found, >+ * Attempts to find an item in the current object mine. If it's not found, > * then it is registered. > * >- * @param item The item >- * @param id The item id >+ * @param item >+ * The item >+ * @param id >+ * The item id > * @return The object or null if it cannot be found or registered. > */ >- private IUIObject findItemInObjectMine (Widget item, IWidgetId id) >- { >- /* Determine if the item is already registered with the object mine */ >- IObjectMine objectMine = MacroManager.getInstance().getObjectMine(); >- IUIObject activeObject = getCorrespondingObject(); >- IUIObject objectItem = null; >- if (activeObject != null) >- { >- objectItem = objectMine.lookupUIObject(activeObject, null, id.toString()); >- /* It's not registered, register the object */ >- if (objectItem == null) >- { >- objectItem = new UIObject(activeObject); >- objectItem.setObjectId(id.toString()); >- objectItem.setReferenceId(objectMine.getUniqueReferenceId()); >- objectItem.setResolver(id.getResolverId()); >- String descriptiveField = getObjectClassName(item); >- if (descriptiveField == null) >- descriptiveField = MacroConstants.EMPTY_STRING; >- String itemText = getText(item); >- descriptiveField += itemText == null ? MacroConstants.EMPTY_STRING : ": " + itemText; >- objectItem.setDescriptive (XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField, DESCRIPTIVE_FIELD_BOUND)))); >- objectItem.setParent(activeObject); >- try >- { >- objectMine.registerObject(objectItem); >- } catch (Exception e) >- { >- objectItem = null; >- >- /* We can't show an error message because it will distrupt the record session, instead print to error stream */ >- System.err.println(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REG); >- e.printStackTrace(); >+ private MacroObjectDescriptor findItemInObjectMine(Widget item, >+ IUIObjectIdentifier id) { >+ if (useObjectMine()) { >+ /* Determine if the item is already registered with the object mine */ >+ MacroObjectDescriptorMine objectMine = MacroManager.getInstance() >+ .getObjectMine(); >+ MacroObjectDescriptor activeObject = getCorrespondingMacroObjectDescriptor(); >+ MacroObjectDescriptor objectItem = null; >+ if (activeObject != null) { >+ objectItem = objectMine.lookupMacroObjectDescriptor( >+ activeObject, null, id.getWidgetId(), id.getObjectId()); >+ /* It's not registered, register the object */ >+ if (objectItem == null) { >+ objectItem = new MacroObjectDescriptor(activeObject); >+ ((MacroObjectDescriptor) objectItem).setWidgetId(id >+ .getWidgetId()); >+ ((MacroObjectDescriptor) objectItem).setResolver(id >+ .getResolverId()); >+ ((MacroObjectDescriptor) objectItem).setObjectId(id >+ .getObjectId()); >+ String descriptiveField = getObjectClassName(item); >+ if (descriptiveField == null) >+ descriptiveField = MacroConstants.EMPTY_STRING; >+ String itemText = getText(item); >+ descriptiveField += itemText == null ? MacroConstants.EMPTY_STRING >+ : ": " + itemText; >+ ((MacroObjectDescriptor) objectItem).setDescriptive(XMLUtil >+ .useXMLSymbols(MacroUtil >+ .normalizeDescriptiveField(MacroUtil >+ .boundSize(descriptiveField, >+ DESCRIPTIVE_FIELD_BOUND)))); >+ ((MacroObjectDescriptor) objectItem) >+ .setParent(activeObject); >+ try { >+ objectMine >+ .registerObject((MacroObjectDescriptor) objectItem); >+ } catch (Exception e) { >+ objectItem = null; >+ >+ /* >+ * We can't show an error message because it will >+ * distrupt the record session, instead print to error >+ * stream >+ */ >+ System.err >+ .println(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REG); >+ e.printStackTrace(); >+ } > } > } >+ >+ return objectItem; >+ } else { >+ return null; > } >- >- return objectItem; > } >- >- >+ > /** >- * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#getCorrespondingObject() >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#getCorrespondingMacroObjectDescriptor() > */ >- public IUIObject getCorrespondingObject () >- { >- if (super.getCorrespondingObject() != null) >- return super.getCorrespondingObject(); >- >- IObjectMine objectMine = MacroManager.getInstance().getObjectMine(); >- IUIObject activeObject = objectMine.getActiveObject(); >- String contextId = getWidgetId().getContextId() == null ? null : getWidgetId().getContextId().toString(); >- super.setCorrespondingObject(activeObject == null ? null : objectMine.lookupUIObject(activeObject, contextId, getWidgetId().getObjectId().toString())); >- >- return super.getCorrespondingObject(); >+ public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() { >+ if (super.getCorrespondingMacroObjectDescriptor() != null) >+ return super.getCorrespondingMacroObjectDescriptor(); >+ >+ MacroObjectDescriptorMine objectMine = MacroManager.getInstance() >+ .getObjectMine(); >+ MacroObjectDescriptor activeObject = objectMine.getActiveObject(); >+ >+ if (useObjectMine() && getMacroObjectIdentifier() != null) { >+ String contextId = (getMacroObjectIdentifier() >+ .getContextIdentifier() == null) ? null >+ : getMacroObjectIdentifier().getContextIdentifier() >+ .toString(); >+ super >+ .setCorrespondingMacroObjectDescriptor(activeObject == null ? null >+ : objectMine.lookupMacroObjectDescriptor( >+ activeObject, contextId, >+ getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getWidgetId(), >+ getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getObjectId())); >+ } >+ >+ return super.getCorrespondingMacroObjectDescriptor(); > } >- >+ > /** >- * Returns the tree item index in the form of N1|N2|N2|...|Nn where >- * Ni corresponds to the item index in the tree. >+ * Returns the tree item index in the form of N1|N2|N2|...|Nn where Ni >+ * corresponds to the item index in the tree. > * >- * @param treeItem The tree item >- * @param currentInx The current index >+ * @param treeItem >+ * The tree item >+ * @param currentInx >+ * The current index > * @return A string representation of the index. > */ >- private String findTreeItemInx(TreeItem treeItem, String currentInx) >- { >+ private static String findTreeItemInx(TreeItem treeItem, String currentInx) { > if (currentInx != null && currentInx.length() > 0) >- currentInx = "|" + currentInx; >- >+ currentInx = "|" + currentInx; >+ > /* We're not the root */ >- if (treeItem.getParentItem() != null) >- { >+ if (treeItem.getParentItem() != null) { > TreeItem parentItem = treeItem.getParentItem(); > currentInx = parentItem.indexOf(treeItem) + "|" + currentInx; > return findTreeItemInx(parentItem, currentInx); > } > /* Otherwise we are the root */ > int index = treeItem.getParent().indexOf(treeItem); >- return index + currentInx; >+ return index + currentInx; >+ } >+ >+ private static Item findItem(Item[] children, IUIObjectIdentifier widgetId) { >+ for (int i = 0; i < children.length; i++) { >+ IUIObjectIdentifier defaultAttributes = getDefaultItemAttributes(children[i]); >+ if (UIObjectDeprecatedDeresolvingSupport.foundWidget(children[i], >+ widgetId) >+ || defaultAttributes.getWidgetId().equals( >+ widgetId.getWidgetId())) >+ return children[i]; >+ >+ /* We need to do a recursive search in the case of a tree */ >+ if (children instanceof TreeItem[]) { >+ TreeItem treeItem = (TreeItem) children[i]; >+ int ccount = treeItem.getItemCount(); >+ if (ccount > 0) { >+ /* Test the item's children */ >+ Item citem = findItem(treeItem.getItems(), widgetId); >+ if (citem != null) >+ return citem; >+ } >+ } >+ } >+ return null; >+ } >+ >+ private static IUIObjectIdentifier getDefaultItemAttributes(Widget item) { >+ Object data = item.getData(); >+ >+ String idStr = MacroConstants.EMPTY_STRING; >+ if (data != null) >+ idStr = data.getClass().getName(); >+ >+ /* Append index to id if it's a table or a tree item */ >+ if (item instanceof TreeItem) { >+ TreeItem treeItem = (TreeItem) item; >+ idStr = idStr >+ + findTreeItemInx(treeItem, MacroConstants.EMPTY_STRING); >+ } else if (item instanceof TableItem) { >+ TableItem tableItem = (TableItem) item; >+ idStr = idStr + tableItem.getParent().indexOf(tableItem); >+ } >+ if (idStr.length() > 0) >+ return new PrimitiveUIObjectIdentifier(idStr); >+ >+ return null; > } > >- > /** >- * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#load(org.w3c.dom.Node, java.util.Hashtable) >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#load(org.w3c.dom.Node, >+ * java.util.Hashtable) > */ >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); > NodeList children = node.getChildNodes(); >- for (int i = 0; i < children.getLength(); i++) >- { >+ for (int i = 0; i < children.getLength(); i++) { > Node child = children.item(i); >- if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(MacroConstants.ITEM_ELEMENT)) >- { >+ if (child.getNodeType() == Node.ELEMENT_NODE >+ && child.getNodeName().equals(MacroConstants.ITEM_ELEMENT)) { > /* First check to see if a reference id is available */ > String attribute = MacroConstants.REFERENCE_ID_ATTRIBUTE; >- String attributeValue = MacroUtil.getAttribute(child, attribute); >- >- /* If a reference id is not available, then check the path attribute */ >- if (attributeValue == null) >- { >- attribute = MacroConstants.PATH_ATTRIBUTE; >+ String attributeValue = MacroUtil >+ .getAttribute(child, attribute); >+ >+ /* >+ * If a reference id is not available, then check the path >+ * attribute >+ */ >+ if (attributeValue == null) { >+ attribute = MacroConstants.WIDGET_ID_ATTRIBUTE; > attributeValue = MacroUtil.getAttribute(child, attribute); > } >- >- if (attributeValue != null) >- { >+ >+ if (attributeValue != null) { > Hashtable itemData = new Hashtable(); > itemData.put(attribute, attributeValue); >- String resolverId = MacroUtil.getAttribute(child, MacroConstants.RESOLVER_ATTRIBUTE); >+ String resolverId = MacroUtil.getAttribute(child, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE); > if (resolverId != null) >- itemData.put(MacroConstants.RESOLVER_ATTRIBUTE, resolverId); >+ itemData.put(MacroConstants.RESOLVER_ID_ATTRIBUTE, >+ resolverId); > items.add(itemData); > } > } >@@ -350,277 +402,243 @@ > /** > * Sub-classes can optionally overwrite this method to write additional > * attributes to command. >- * >- * @param sb The string buffer that the attributes should be written to. >+ * >+ * @param sb >+ * The string buffer that the attributes should be written to. > */ >- protected void writeAdditionalAttributes(StringBuffer sb) >- { >+ protected void writeAdditionalAttributes(StringBuffer sb) { > } > >- > /** >- * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#write(int, java.lang.StringBuffer) >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#write(int, >+ * java.lang.StringBuffer) > */ >- public void write(int indent, StringBuffer sb) >- { >+ public void write(int indent, StringBuffer sb) { > super.write(indent, sb); > writeAdditionalAttributes(sb); > sb.append(MacroConstants.CLOSE_ANGLE_BRACKET); > sb.append(GlobalConstants.LINE_SEPARATOR); >- >+ > int cindent = indent + 1; > boolean isObjectMineOn = MacroManager.getInstance().isObjectMineOn(); >- for (int i = 0; i < items.size(); i++) >- { >- Map itemData = (Map)items.get(i); >- if (itemData != null) >- { >- String referenceId = (String)itemData.get(MacroConstants.REFERENCE_ID_ATTRIBUTE); >- String itemId = itemData.get(MacroConstants.PATH_ATTRIBUTE).toString(); >+ for (int i = 0; i < items.size(); i++) { >+ Map itemData = (Map) items.get(i); >+ if (itemData != null) { >+ String referenceId = (String) itemData >+ .get(MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ String itemId = itemData >+ .get(MacroConstants.WIDGET_ID_ATTRIBUTE).toString(); > boolean useReferenceId = isObjectMineOn && referenceId != null; >- MacroUtil.addElement(sb, cindent, MacroConstants.ITEM_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, >- new String[]{ >- useReferenceId ? MacroConstants.REFERENCE_ID_ATTRIBUTE : MacroConstants.PATH_ATTRIBUTE, >- MacroConstants.RESOLVER_ATTRIBUTE >- }, >- new String[]{ >- useReferenceId ? referenceId : itemId, >- useReferenceId ? null : (String)itemData.get(MacroConstants.RESOLVER_ATTRIBUTE) >- }, true, true); >- } >- } >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true); >+ MacroUtil.addElement(sb, cindent, MacroConstants.ITEM_ELEMENT, >+ false, false); >+ MacroUtil.addAttribute(sb, new String[] { >+ useReferenceId ? MacroConstants.REFERENCE_ID_ATTRIBUTE >+ : MacroConstants.WIDGET_ID_ATTRIBUTE, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE }, new String[] { >+ useReferenceId ? referenceId : itemId, >+ useReferenceId ? null : (String) itemData >+ .get(MacroConstants.RESOLVER_ID_ATTRIBUTE) }, >+ true, true); >+ } >+ } >+ MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, >+ true); > } > > /** >- * Used to play the structured command collectively for all the discovered matches. >- * >- * @param widget The widget >- * @param matches The matches discovered >- */ >- protected abstract void playStructuredCommand(Widget widget, Object[] matches); >- >- >- /** >- * Some events require to be played as matches are discovered. (e.g. an expansion command >- * requires to be played for each discovered item in order for successive children to be found) >- * It's recommended that either playStructuredCommandForFoundMatch or playStructuredCommand be implemented >- * by clients, eventhough both methods will be invoked. >- * >- * @param widget The widget >- * @param matches The match discovered >- */ >- protected abstract void playStructuredCommandForFoundMatch(Widget widget, Object match); >- >- >- public final boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine()); >+ * Used to play the structured command collectively for all the discovered >+ * matches. >+ * >+ * @param widget >+ * The widget >+ * @param matches >+ * The matches discovered >+ */ >+ protected abstract void playStructuredCommand(Widget widget, >+ Object[] matches); > >- if (targets == null) >+ /** >+ * Some events require to be played as matches are discovered. (e.g. an >+ * expansion command requires to be played for each discovered item in order >+ * for successive children to be found) It's recommended that either >+ * playStructuredCommandForFoundMatch or playStructuredCommand be >+ * implemented by clients, eventhough both methods will be invoked. >+ * >+ * @param widget >+ * The widget >+ * @param matches >+ * The match discovered >+ */ >+ protected abstract void playStructuredCommandForFoundMatch(Widget widget, >+ Object match); >+ >+ public final boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ if (macroObject == null) > return false; >- >- for (int i = 0; i < targets.length; i++) >- { >- targets[i].setFocus(); >- >- /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: A process display event causes the target widget to sometimes >- * be disposed. >- * MacroUtil.processDisplayEvents(display); */ >- Widget widget = targets[i].getWidget(); >- >- if (widget == null || widget.isDisposed()) >- continue; >- >- Object[] matches = findMatches(widget); >- >- /* If we failed to locate the item, then continue */ >- if (matches != null && items.size() != matches.length) >- continue; >- >- playStructuredCommand(widget, matches); >- return true; >- } >- >- return false; >+ >+ // for (int i = 0; i < targets.length; i++) { >+ setFocus(macroObject); >+ >+ /* >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: A process >+ * display event causes the target widget to sometimes be disposed. >+ * MacroUtil.processDisplayEvents(display); >+ */ >+ Widget widget = macroObject.getUIObject().getWidget(); >+ >+ if (widget == null || widget.isDisposed()) >+ return false;// continue; >+ >+ Object[] matches = findMatches(widget); >+ >+ /* If we failed to locate the item, then continue */ >+ if (matches != null && items.size() != matches.length) >+ return false;// continue; >+ >+ playStructuredCommand(widget, matches); >+ return true; >+ // } >+ >+ // return false; > } > >- protected Object[] findMatches(Widget widget) throws CoreException >- { >+ protected Object[] findMatches(Widget widget) throws CoreException { > if (widget instanceof Tree) >- return findMatches((Tree)widget); >+ return findMatches((Tree) widget); > else if (widget instanceof Table) >- return findMatches((Table)widget); >+ return findMatches((Table) widget); > else if (widget instanceof List) >- return findMatches ((List) widget); >- >+ return findMatches((List) widget); >+ > return null; > } > >- private String[] findMatches(List list) throws CoreException >- { >+ private String[] findMatches(List list) throws CoreException { > String[] children = list.getItems(); > ArrayList matches = new ArrayList(); >- for (int i = 0; i < items.size(); i++) >- { >+ for (int i = 0; i < items.size(); i++) { > String itemId = findObjectId(i).toString(); > int itemInx = list.indexOf(itemId); >- if (itemInx >= 0 && itemInx < children.length) >- { >- playStructuredCommandForFoundMatch (list, children[itemInx]); >+ if (itemInx >= 0 && itemInx < children.length) { >+ playStructuredCommandForFoundMatch(list, children[itemInx]); > matches.add(children[itemInx]); > } > } > return (String[]) matches.toArray(new String[matches.size()]); > } >- > >- private TreeItem[] findMatches(Tree tree) throws CoreException >- { >+ private TreeItem[] findMatches(Tree tree) throws CoreException { > TreeItem[] children = tree.getItems(); > ArrayList matches = new ArrayList(); >- for (int i = 0; i < items.size(); i++) >- { >- IWidgetId currentWidgetId = findObjectId(i); >- String itemId = currentWidgetId.toString(); >- Item item = findItem(children, currentWidgetId.getResolverId(), itemId); >- if (item != null) >- { >- playStructuredCommandForFoundMatch (tree, item); >+ for (int i = 0; i < items.size(); i++) { >+ IUIObjectIdentifier currentWidgetId = findObjectId(i); >+ Item item = findItem(children, currentWidgetId); >+ if (item != null) { >+ playStructuredCommandForFoundMatch(tree, item); > matches.add(item); > } > } > return (TreeItem[]) matches.toArray(new TreeItem[matches.size()]); > } > >- private TableItem[] findMatches(Table table) throws CoreException >- { >+ private TableItem[] findMatches(Table table) throws CoreException { > TableItem[] elements = table.getItems(); > ArrayList matches = new ArrayList(); > >- for (int i = 0; i < items.size(); i++) >- { >- IWidgetId currentWidgetId = findObjectId(i); >- String itemId = currentWidgetId.toString(); >- Item item = findItem(elements, currentWidgetId.getResolverId(), itemId); >- if (item != null) >- { >- playStructuredCommandForFoundMatch (table, item); >+ for (int i = 0; i < items.size(); i++) { >+ IUIObjectIdentifier currentWidgetId = findObjectId(i); >+ Item item = findItem(elements, currentWidgetId); >+ if (item != null) { >+ playStructuredCommandForFoundMatch(table, item); > matches.add(item); > } > } > return (TableItem[]) matches.toArray(new TableItem[matches.size()]); > } > >- > /** >- * Returns the object id of the inx-th item associated with this >- * structured command. >+ * Returns the object id of the inx-th item associated with this structured >+ * command. > * >- * @param inx The index of the item >+ * @param inx >+ * The index of the item > * @return The object id > * >- * @throws CoreException If an error occurrs while attempting to find the object >+ * @throws CoreException >+ * If an error occurrs while attempting to find the object > */ >- protected IWidgetId findObjectId(int inx) throws CoreException >- { >+ protected IUIObjectIdentifier findObjectId(int inx) throws CoreException { > Hashtable itemData = null; >- if (inx < 0 || inx >= items.size() || (itemData = (Hashtable)items.get(inx)) == null) >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_ITEM, getStartLine()); >- >+ if (inx < 0 || inx >= items.size() >+ || (itemData = (Hashtable) items.get(inx)) == null) >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_ITEM, getStartLine()); >+ > Object itemObjectId = null; >- PrimitiveWidgetId widgetId = null; >- if ((itemObjectId = itemData.get(MacroConstants.PATH_ATTRIBUTE)) != null) >- { >- widgetId = new PrimitiveWidgetId(itemObjectId.toString()); >- widgetId.setResolverId((String)itemData.get(MacroConstants.RESOLVER_ATTRIBUTE)); >+ PrimitiveUIObjectIdentifier widgetId = null; >+ if ((itemObjectId = itemData.get(MacroConstants.WIDGET_ID_ATTRIBUTE)) != null) { >+ widgetId = new PrimitiveUIObjectIdentifier(itemObjectId.toString(), >+ (String) itemData.get(MacroConstants.RESOLVER_ID_ATTRIBUTE)); > return widgetId; > } >- >- String referenceId = (String)itemData.get(MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ >+ String referenceId = (String) itemData >+ .get(MacroConstants.REFERENCE_ID_ATTRIBUTE); > if (referenceId == null) >- return new PrimitiveWidgetId(MacroConstants.EMPTY_STRING); >- >- IObjectMine objectMine = MacroManager.getInstance().getObjectMine(); >+ return new PrimitiveUIObjectIdentifier(MacroConstants.EMPTY_STRING); >+ >+ MacroObjectDescriptorMine objectMine = MacroManager.getInstance() >+ .getObjectMine(); > if (objectMine == null) >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_T, getStartLine()); >- >- IUIObject parentObject = getCorrespondingObject(); >- IUIObject itemObject = null; >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_T, >+ getStartLine()); >+ >+ MacroObjectDescriptor parentObject = getCorrespondingMacroObjectDescriptor(); >+ MacroObjectDescriptor itemObject = null; > if (parentObject != null) >- itemObject = MacroManager.getInstance().getObjectMine().lookupUIObject(parentObject, referenceId); >- >- >- if (itemObject == null || (itemObjectId = itemObject.getObjectId()) == null) >- return new PrimitiveWidgetId(MacroConstants.EMPTY_STRING); >- >- itemData.put(MacroConstants.PATH_ATTRIBUTE, itemObjectId); >- widgetId = new PrimitiveWidgetId(itemObjectId.toString()); >- widgetId.setResolverId(itemObject.getResolverId()); >- return widgetId; >- } >- >- >- private Item findItem(Item[] children, String resolverId, String itemId) >- { >- for (int i = 0; i < children.length; i++) >- { >- if (MacroObjectLocator.foundWidget(children[i], resolverId, itemId) || getDefaultItemAttributes(children[i]).equals(itemId)) >- return children[i]; >+ itemObject = MacroManager.getInstance().getObjectMine() >+ .lookupMacroObjectDescriptor(parentObject, referenceId); > >- /* We need to do a recursive search in the case of a tree */ >- if (children instanceof TreeItem[]) >- { >- TreeItem treeItem = (TreeItem)children[i]; >- int ccount = treeItem.getItemCount(); >- if (ccount > 0) >- { >- /* Test the item's children */ >- Item citem = findItem(treeItem.getItems(), resolverId, itemId); >- if (citem != null) >- return citem; >- } >- } >- } >- return null; >+ if (itemObject == null >+ || (itemObjectId = itemObject.getWidgetId()) == null) >+ return new PrimitiveUIObjectIdentifier(MacroConstants.EMPTY_STRING); >+ >+ itemData.put(MacroConstants.WIDGET_ID_ATTRIBUTE, itemObjectId); >+ widgetId = new PrimitiveUIObjectIdentifier(itemObjectId.toString(), >+ itemObject.getResolverId()); >+ return widgetId; > } > >- > /** > * Returns the items that this command must match > * > * @return Matched items > */ >- protected ArrayList getItems() >- { >+ protected ArrayList getItems() { > return items; > } >- >- >- public boolean equals (Object obj) >- { >+ >+ public boolean equals(Object obj) { > boolean equalState = super.equals(obj); > if (!equalState) > return false; >- >- AbstractStructuredCommand compareWithObj = (AbstractStructuredCommand)obj; >+ >+ AbstractStructuredCommand compareWithObj = (AbstractStructuredCommand) obj; > if (compareWithObj.getItems().size() != items.size()) > return false; >- >+ > /* For each item */ >- for (int i = 0, objectCount = items.size(); i < objectCount; i++) >- { >- try >- { >+ for (int i = 0, objectCount = items.size(); i < objectCount; i++) { >+ try { > if (!compareWithObj.findObjectId(i).equals(findObjectId(i))) > return false; >- } catch (CoreException e) >- { >+ } catch (CoreException e) { > return false; > } > } >- >+ > return true; > } > >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/WindowCommandTarget.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/WindowCommandTarget.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/WindowCommandTarget.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/WindowCommandTarget.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,36 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import org.eclipse.jface.window.Window; >-import org.eclipse.swt.widgets.Widget; >- >-public class WindowCommandTarget extends CommandTarget { >- /** >- * @param widget >- * @param context >- */ >- public WindowCommandTarget(Widget widget, Window window) { >- super(widget, window); >- } >- >- Window getWindow() { >- return (Window)getContext(); >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.ui.macro.CommandTarget#ensureVisible() >- */ >- public void ensureVisible() { >- Window window = getWindow(); >- window.getShell().setActive(); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/CloseWorkbenchPartCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/CloseWorkbenchPartCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 CloseWorkbenchPartCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/CloseWorkbenchPartCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/CloseWorkbenchPartCommand.java 26 Jul 2008 19:22:00 -0000 >@@ -14,12 +14,17 @@ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.Path; >-import org.eclipse.swt.widgets.Composite; >+import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; > import org.eclipse.ui.IEditorPart; > import org.eclipse.ui.IEditorReference; > import org.eclipse.ui.IViewPart; >@@ -32,75 +37,84 @@ > * > * @author Ali Mehregani > */ >-public class CloseWorkbenchPartCommand extends AbstractMacroCommand >-{ >- public static final String TYPE = "close-workbenchpart"; >- >- public CloseWorkbenchPartCommand(MacroCommandShell parent, WidgetIdentifier widgetId) >- { >- super(parent, widgetId); >+public class CloseWorkbenchPartCommand extends ObjectBasedCommand { >+ >+ public static final String TYPE = IMacroCommand.CLOSE_WORKBENCHPART; >+ >+ public CloseWorkbenchPartCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public String getType() { > return TYPE; > } >+ >+ protected final void preProcessEvent(Event event) throws CoreException { >+ IMacroObjectIdentifier macroObjectIdentifier = MacroUtil.getCustomEventIdentifier(event); >+ if(macroObjectIdentifier == null){ >+ IWorkbenchPart part = (IWorkbenchPart) event.data; >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE, part)); >+ } >+ setMacroObjectIdentifier(macroObjectIdentifier); >+ } > >- public void processEvent(Event e) >- { >- setDescriptiveField(((IWorkbenchPart)e.data).getTitle()); >+ public void doProcessEvent(Event e) { >+ setDescriptiveField(((IWorkbenchPart) e.data).getTitle()); > } > >- public void write(int indent, StringBuffer sb) >- { >- super.write(indent, sb, true, true); >+ public void write(int indent, StringBuffer sb) { >+ super.write(indent, >+ sb, >+ true, >+ true); > } >+ >+ public boolean playback(Display display, Shell parent, IProgressMonitor monitor) throws CoreException { >+ String partType = getMacroObjectIdentifier().getContextIdentifier().toString(); >+ String partId = getMacroObjectIdentifier().getObjectIdentifier().getWidgetId(); > >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- String partType = getWidgetId().getContextId().toString(); >- String partId = getWidgetId().getObjectId().toString(); >- > boolean isView = partType.equals(MacroConstants.VIEW_VALUE); > IEditorReference[] editorReferences = null; > IViewReference[] viewReferences = null; >- >+ > IWorkbenchPage activePage = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); > String editorPartId = null; > String editorInputName = null; >- >+ > /* Try to locate the part */ >- if (isView) >- { >+ if (isView) { > viewReferences = activePage.getViewReferences(); > } >- else >- { >+ else { > editorReferences = activePage.getEditorReferences(); > Path partIdPath = new Path(partId); > editorPartId = partIdPath.segment(0); > editorInputName = partIdPath.segment(1); > } >- >+ > IWorkbenchPart desiredPart = null; >- for (int i = 0; i < (isView ? viewReferences.length : editorReferences.length); i++) >- { >- if (isView ? viewReferences[i].getId().equals(partId) : (editorReferences[i].getId().equals(editorPartId) && editorReferences[i].getEditorInput().getName().equals(editorInputName))) >- { >- desiredPart = (isView ? (IWorkbenchPart)viewReferences[i].getView(false) : (IWorkbenchPart)editorReferences[i].getEditor(false)); >+ for (int i = 0; i < (isView >+ ? viewReferences.length >+ : editorReferences.length); i++) { >+ if (isView >+ ? viewReferences[i].getId().equals(partId) >+ : (editorReferences[i].getId().equals(editorPartId) && editorReferences[i].getEditorInput().getName().equals(editorInputName))) { >+ desiredPart = (isView >+ ? (IWorkbenchPart) viewReferences[i].getView(false) >+ : (IWorkbenchPart) editorReferences[i].getEditor(false)); > break; > } > } >- >+ > /* Close the part if we found it */ >- if (desiredPart != null) >- { >+ if (desiredPart != null) { > if (isView) >- activePage.hideView((IViewPart)desiredPart); >+ activePage.hideView((IViewPart) desiredPart); > else >- activePage.closeEditor((IEditorPart)desiredPart, true); >+ activePage.closeEditor((IEditorPart) desiredPart, >+ true); > } >- >+ > return true; > } > >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/WaitCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/WaitCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 WaitCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/WaitCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/WaitCommand.java 26 Jul 2008 19:22:05 -0000 >@@ -20,11 +20,11 @@ > import org.eclipse.core.runtime.jobs.IJobManager; > import org.eclipse.core.runtime.jobs.Job; > import org.eclipse.core.runtime.jobs.JobChangeAdapter; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > import org.w3c.dom.Node; >@@ -32,96 +32,87 @@ > /** > * <p> > * The purpose of this command is to provide a waiting mechanism so as to avoid >- * racing conditions that may cause a test case to fail when the underlying functionality >- * works as expected. >+ * racing conditions that may cause a test case to fail when the underlying >+ * functionality works as expected. > * </p> > * > * <p> >- * The command has a dual behaviour depending on whether the waitTime field is set or not. If >- * this field is set, then this command will cause the caller thread to wait 'waitTime' milliseconds. >- * If the field is not set, then the command will cause the caller thread to wait until all >- * non-system Eclipse jobs are completed. >- * </p> >+ * The command has a dual behaviour depending on whether the waitTime field is >+ * set or not. If this field is set, then this command will cause the caller >+ * thread to wait 'waitTime' milliseconds. If the field is not set, then the >+ * command will cause the caller thread to wait until all non-system Eclipse >+ * jobs are completed. >+ * </p> > */ >-public class WaitCommand extends AbstractMacroCommand >-{ >- public static final String TYPE = "wait"; >+public class WaitCommand extends AbstractMacroCommand { >+ >+ public static final String TYPE = IMacroCommand.WAIT; > >- /* The amount of waiting time. If this field is set, then this command behaves differently */ >+ /* >+ * The amount of waiting time. If this field is set, then this command >+ * behaves differently >+ */ > private long waitTime; >- >- private static class JobListener extends JobChangeAdapter >- { >+ >+ private static class JobListener extends JobChangeAdapter { >+ > private int counter = 0; > > private IProgressMonitor monitor; > > private Thread t; > >- public JobListener(IProgressMonitor monitor, Thread t, int number) >- { >+ public JobListener(IProgressMonitor monitor, Thread t, int number) { > this.counter = number; > this.monitor = monitor; > this.t = t; > } > >- private synchronized void change(int increment) >- { >+ private synchronized void change(int increment) { > this.counter += increment; >- if (counter == 0) >- { >+ if (counter == 0) { > monitor.subTask(""); >- synchronized (t) >- { >+ synchronized (t) { > t.interrupt(); > } > } > } > >- public void running(IJobChangeEvent event) >- { >+ public void running(IJobChangeEvent event) { > Job job = event.getJob(); > if (!job.isSystem()) > change(1); > } > >- public void done(IJobChangeEvent event) >- { >+ public void done(IJobChangeEvent event) { > Job job = event.getJob(); > if (!job.isSystem()) > change(-1); > } > } > >- > /** > * A chance to build the meta-data of this verification command > */ >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); >- >- String waitTime = MacroUtil.getAttribute(node, MacroConstants.TIME_TO_WAIT_ATTRIBUTE); >- >- if (waitTime != null && waitTime.length() > 0) >- { >- try >- { >+ >+ String waitTime = MacroUtil.getAttribute(node, >+ MacroConstants.TIME_TO_WAIT_ATTRIBUTE); >+ >+ if (waitTime != null && waitTime.length() > 0) { >+ try { > long timeToWait = Long.parseLong(waitTime); > if (timeToWait > 0) > this.waitTime = timeToWait; >- } >- catch (NumberFormatException nfe) >- { >+ } catch (NumberFormatException nfe) { > nfe.printStackTrace(); > } > } > } >- > >- public WaitCommand(MacroCommandShell parent) >- { >- super(parent, WidgetIdentifier.NULL_IDENTIFIER); >+ public WaitCommand(MacroCommandShell parent) { >+ super(parent); > } > > /* >@@ -129,8 +120,7 @@ > * > * @see org.eclipse.ui.macro.MacroCommand#getType() > */ >- public String getType() >- { >+ public String getType() { > return TYPE; > } > >@@ -139,8 +129,7 @@ > * > * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event) > */ >- public void processEvent(Event e) >- { >+ public void processEvent(Event e) { > } > > /* >@@ -149,130 +138,121 @@ > * @see org.eclipse.ui.macro.IWritable#write(java.lang.String, > * java.io.PrintWriter) > */ >- public void write(int indent, StringBuffer sb) >- { >- /* Don't print out this wait command if it happens to be the last command in the macro shell OR >- * the next command following it is a macro command shell */ >+ public void write(int indent, StringBuffer sb) { >+ /* >+ * Don't print out this wait command if it happens to be the last >+ * command in the macro shell OR the next command following it is a >+ * macro command shell >+ */ > ArrayList commands = getParent().getCommands(); > int commandSize = commands.size(); >- if ((commandSize > 0 && this == commands.get(commandSize - 1)) || isNextCommandShell(commands)) >+ if ((commandSize > 0 && this == commands.get(commandSize - 1)) >+ || isNextCommandShell(commands)) > return; >- >- >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, >- new String[] {MacroConstants.DESCRIPTIVE_ATTRIBUTE, >- MacroConstants.TYPE_ATTRIBUTE, >- MacroConstants.TIME_TO_WAIT_ATTRIBUTE}, >- new String[] {MacroUtil.boundSize(getDescriptiveField(), AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND), >- getType(), >- waitTime > 0 ? String.valueOf(waitTime) : null}, true, true); >+ >+ MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, >+ false); >+ MacroUtil.addAttribute(sb, new String[] { >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE, >+ MacroConstants.TYPE_ATTRIBUTE, >+ MacroConstants.TIME_TO_WAIT_ATTRIBUTE }, new String[] { >+ MacroUtil.boundSize(getDescriptiveField(), >+ AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND), >+ getType(), waitTime > 0 ? String.valueOf(waitTime) : null }, >+ true, true); > } > >- private boolean isNextCommandShell(ArrayList commands) >- { >+ private boolean isNextCommandShell(ArrayList commands) { > int index = -1; >- >+ > int commandCount = commands.size(); >- for (int i = 0; i < commandCount; i++) >- { >- if (this == commands.get(i)) >- { >+ for (int i = 0; i < commandCount; i++) { >+ if (this == commands.get(i)) { > index = i; > break; >- } >+ } > } >- >+ > if (index + 1 < commandCount) > return commands.get(index + 1) instanceof MacroCommandShell; > return false; > } > >- > /* > * (non-Javadoc) > * > * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite) > */ >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- >- if (waitTime > 0) >- { >- try >- { >+ public boolean playback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ >+ if (waitTime > 0) { >+ try { > Thread.sleep(waitTime); >- } >- catch (InterruptedException e) >- { >+ } catch (InterruptedException e) { > /* Doesn't need to be handled */ > } > return true; > } >- >- >+ > IJobManager jobManager = Platform.getJobManager(); > int nrunning = getNumberOfRunningJobs(jobManager); >- if (nrunning == 0) >- { >+ if (nrunning == 0) { > return true; > } > String message = AutoGUIMessages.AUTO_GUI_MACRO_WAITING; >- JobListener listener = new JobListener(monitor, Thread.currentThread(), nrunning); >+ JobListener listener = new JobListener(monitor, Thread.currentThread(), >+ nrunning); > jobManager.addJobChangeListener(listener); > monitor.subTask(message); >- >+ > final long INCREMENT_WAIT = 2000; > final int MAX_INCREMENT_NUM = 5; >- try >- { >+ try { > int counter = 0; >- >- /* Let's wait in increments of INCREMENT_WAIT milliseconds for a maximum of INCREMENT_WAIT * MAX_INCREMENT_NUM milliseconds*/ >- while (counter < MAX_INCREMENT_NUM) >- { >- Thread.sleep(INCREMENT_WAIT); >+ >+ /* >+ * Let's wait in increments of INCREMENT_WAIT milliseconds for a >+ * maximum of INCREMENT_WAIT * MAX_INCREMENT_NUM milliseconds >+ */ >+ while (counter < MAX_INCREMENT_NUM) { >+ Thread.sleep(INCREMENT_WAIT); > if (getNumberOfRunningJobs(jobManager) == 0) >- break; >+ break; > counter++; > } >- >- } >- catch (InterruptedException e) >- { >+ >+ } catch (InterruptedException e) { > } > jobManager.removeJobChangeListener(listener); > return true; > } > >- private int getNumberOfRunningJobs(IJobManager manager) >- { >+ private int getNumberOfRunningJobs(IJobManager manager) { > int count = 0; > Job[] jobs = manager.find(null); >- for (int i = 0; i < jobs.length; i++) >- { >+ for (int i = 0; i < jobs.length; i++) { > if (!jobs[i].isSystem() && jobs[i].getState() == Job.RUNNING) > count++; > } > return count; > } > >- public void setWaitTime(long difference) >- { >+ public void setWaitTime(long difference) { > this.waitTime = difference; > } >- >+ > /** >- * Overwrite this method so that a custom descriptive field can be specified. >- * The format of the descriptive field is "<WAIT_TIME> seconds" >+ * Overwrite this method so that a custom descriptive field can be >+ * specified. The format of the descriptive field is "<WAIT_TIME> seconds" > * > * @return The descriptive field. > */ >- public String getDescriptiveField() >- { >+ public String getDescriptiveField() { > if (waitTime > 0) >- return (((double)waitTime) / 1000.0) + " " + AutoGUIMessages.TST_SUITE_AUTO_MACRO_SECONDS; >- >+ return (((double) waitTime) / 1000.0) + " " >+ + AutoGUIMessages.TST_SUITE_AUTO_MACRO_SECONDS; >+ > return null; > } > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/EditorCommandTarget.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/EditorCommandTarget.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/EditorCommandTarget.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/EditorCommandTarget.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,38 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.ui.IEditorPart; >-import org.eclipse.ui.IWorkbenchPage; >- >-public class EditorCommandTarget extends CommandTarget { >- /** >- * @param widget >- * @param context >- */ >- public EditorCommandTarget(Widget widget, IEditorPart editor) { >- super(widget, editor); >- } >- >- public IEditorPart getEditor() { >- return (IEditorPart)getContext(); >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.ui.macro.CommandTarget#ensureVisible() >- */ >- public void ensureVisible() { >- IEditorPart editor = getEditor(); >- IWorkbenchPage page = editor.getEditorSite().getPage(); >- page.activate(editor); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/CheckCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/CheckCommand.java,v >retrieving revision 1.2 >diff -u -r1.2 CheckCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/CheckCommand.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/CheckCommand.java 26 Jul 2008 19:21:59 -0000 >@@ -17,90 +17,87 @@ > import org.eclipse.swt.widgets.Tree; > import org.eclipse.swt.widgets.TreeItem; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > >-public class CheckCommand extends ToggleStructuredCommand >-{ >- public static final String TYPE = "item-check"; >+public class CheckCommand extends ToggleStructuredCommand { >+ >+ public static final String TYPE = IMacroCommand.ITEM_CHECK; >+ > /** > * @param wid > */ >- public CheckCommand(MacroCommandShell parent, WidgetIdentifier wid) { >- super(parent, wid); >+ public CheckCommand(MacroCommandShell parent) { >+ super(parent); > } >- >+ > public String getType() { > return TYPE; > } >- >- public void processEvent(Event event) >- { >- super.processEvent(event); >+ >+ public void doProcessEvent(Event event) { >+ super.doProcessEvent(event); >+ > Widget item = event.item; >- itemState = getItemState (item); >+ itemState = getItemState(item); > } >- >- public boolean getItemState(Widget item) >- { >+ >+ public boolean getItemState(Widget item) { > if (item instanceof TreeItem) >- return ((TreeItem)item).getChecked(); >+ return ((TreeItem) item).getChecked(); > else if (item instanceof TableItem) >- return ((TableItem)item).getChecked(); >- >+ return ((TableItem) item).getChecked(); >+ > return false; > } >- >- protected void playStructuredCommand(Widget widget, Object[] matches) >- { >+ >+ protected void playStructuredCommand(Widget widget, Object[] matches) { > boolean isTree = widget instanceof Tree; > boolean isTable = false; > if (!isTree) > isTable = widget instanceof Table; >- >+ > if (!isTree && !isTable) > return; >- >+ > Event selectionEvent = null; >- >- for (int i=0; i<matches.length; i++) >- { >+ >+ for (int i = 0; i < matches.length; i++) { > selectionEvent = constructSelectionEvent(widget); >- >+ > if ((widget.getStyle() & SWT.CHECK) != 0) > selectionEvent.detail = SWT.CHECK; >- selectionEvent.item = (Widget)matches[i]; >- >+ selectionEvent.item = (Widget) matches[i]; >+ > if (isTree) >- ((TreeItem)matches[i]).setChecked(getValue()); >+ ((TreeItem) matches[i]).setChecked(getValue()); > else >- ((TableItem)matches[i]).setChecked(getValue()); >- >+ ((TableItem) matches[i]).setChecked(getValue()); >+ > /* Send the selection event */ >- widget.notifyListeners(SWT.Selection, selectionEvent); >+ widget.notifyListeners(SWT.Selection, >+ selectionEvent); > MacroUtil.processDisplayEvents(widget.getDisplay()); > } >- >+ > } >- >+ > /** >- * Clients will often expect a selection event to be sent. >- * This helper method is used to construct a selection event. >+ * Clients will often expect a selection event to be sent. This helper method is used to construct a selection event. > * >- * @param widget The widget that will be used to send out the event. >- * @return The event. >+ * @param widget >+ * The widget that will be used to send out the event. >+ * @return The event. > */ >- private Event constructSelectionEvent(Widget widget) >- { >+ private Event constructSelectionEvent(Widget widget) { > Event event = new Event(); > event.display = widget.getDisplay(); > event.widget = widget; >- event.type = SWT.Selection; >+ event.type = SWT.Selection; > return event; > } > >- protected void playStructuredCommandForFoundMatch(Widget widget, Object match) >- { >+ protected void playStructuredCommandForFoundMatch(Widget widget, Object match) { > /* Deosn't need to be implemented */ > } > >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ViewCommandTarget.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/ViewCommandTarget.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/ViewCommandTarget.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/ViewCommandTarget.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,34 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.ui.IViewPart; >-import org.eclipse.ui.IWorkbenchPage; >- >-public class ViewCommandTarget extends CommandTarget { >- public ViewCommandTarget(Widget widget, IViewPart view) { >- super(widget, view); >- } >- >- public IViewPart getView() { >- return (IViewPart)getContext(); >- } >- >- /* (non-Javadoc) >- * @see org.eclipse.ui.macro.CommandTarget#ensureVisible() >- */ >- public void ensureVisible() { >- IViewPart view = getView(); >- IWorkbenchPage page = view.getViewSite().getPage(); >- page.activate(view); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/CommandTarget.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/CommandTarget.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/CommandTarget.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/CommandTarget.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,43 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import org.eclipse.swt.widgets.*; >-import org.eclipse.swt.widgets.Widget; >- >-public class CommandTarget { >- private Widget widget; >- private Object context; >- >- public CommandTarget(Widget widget, Object context) { >- this.widget = widget; >- this.context = context; >- } >- >- public void ensureVisible() { >- } >- >- public Widget getWidget() { >- return widget; >- } >- public Object getContext() { >- return context; >- } >- public void setFocus() { >- ensureVisible(); >- Display display = widget.getDisplay(); >- if (widget instanceof Control) { >- Control c = (Control)widget; >- if (!c.equals(display.getFocusControl())) >- c.setFocus(); >- } >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ExpansionCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/ExpansionCommand.java,v >retrieving revision 1.2 >diff -u -r1.2 ExpansionCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/ExpansionCommand.java 7 Dec 2006 22:10:28 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/ExpansionCommand.java 26 Jul 2008 19:22:00 -0000 >@@ -15,65 +15,76 @@ > import org.eclipse.swt.widgets.Tree; > import org.eclipse.swt.widgets.TreeItem; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; > > public class ExpansionCommand extends ToggleStructuredCommand { >- public static final String TYPE = "item-expand"; >+ >+ public static final String TYPE = IMacroCommand.ITEM_EXPAND; >+ > /** > * @param wid > */ >- public ExpansionCommand(MacroCommandShell parent, WidgetIdentifier wid) { >- super(parent, wid); >+ public ExpansionCommand(MacroCommandShell parent) { >+ super(parent); >+ } >+ >+ public ExpansionCommand(MacroCommandShell parent, >+ IMacroObjectIdentifier identifier) { >+ super(parent); >+ setMacroObjectIdentifier(identifier); > } >- >- public void processEvent(Event event) { >- super.processEvent(event); >+ >+ public void doProcessEvent(Event event) { >+ super.doProcessEvent(event); > Widget item = event.item; >- itemState = getItemState (item); >+ itemState = getItemState(item); > } >- >- /* Added for defect 164197*/ >- >- public void processEvent(Event event, boolean preferredState) >- { >- super.processEvent(event); >+ >+ /* Added for defect 164197 */ >+ >+ public void doProcessEvent(Event event, boolean preferredState) { >+ super.doProcessEvent(event); >+ > itemState = preferredState; > } >- public boolean getItemState(Widget item) >- { >+ >+ public void setItemState(boolean state) { >+ this.itemState = state; >+ } >+ >+ public boolean getItemState(Widget item) { > if (item instanceof TreeItem) >- return !((TreeItem)item).getExpanded(); >- >+ return !((TreeItem) item).getExpanded(); >+ > return false; > } > >- protected void playStructuredCommand(Widget widget, Object[] matches) >- { >+ protected void playStructuredCommand(Widget widget, Object[] matches) { > /* Doesn't need to be implemented */ > } >- >- protected void playStructuredCommandForFoundMatch(Widget widget, Object match) >- { >+ >+ protected void playStructuredCommandForFoundMatch(Widget widget, >+ Object match) { > if (!(widget instanceof Tree)) > return; >- >- TreeItem treeItem = (TreeItem)match; >+ >+ TreeItem treeItem = (TreeItem) match; > treeItem.setExpanded(getValue()); >- fireEvent(widget, treeItem); >+ fireEvent(widget, treeItem); > } >- >- >- private void fireEvent(Widget widget, Widget item) >- { >+ >+ private void fireEvent(Widget widget, Widget item) { > Event event = new Event(); >- event.type = getValue()?SWT.Expand:SWT.Collapse; >+ event.type = getValue() ? SWT.Expand : SWT.Collapse; > event.widget = widget; >- event.item= item; >+ event.item = item; > widget.notifyListeners(event.type, event); > } > >- >- /* (non-Javadoc) >+ /* >+ * (non-Javadoc) >+ * > * @see org.eclipse.ui.macro.SelectionCommand#getKind() > */ > public String getType() { >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/WizardCommandTarget.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/WizardCommandTarget.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/WizardCommandTarget.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/WizardCommandTarget.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,29 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.commands; >- >-import org.eclipse.jface.window.Window; >-import org.eclipse.jface.wizard.WizardDialog; >-import org.eclipse.swt.widgets.Widget; >- >-public class WizardCommandTarget extends WindowCommandTarget { >- /** >- * @param widget >- * @param window >- */ >- public WizardCommandTarget(Widget widget, Window window) { >- super(widget, window); >- } >- >- public WizardDialog getWizardDialog() { >- return (WizardDialog)getWindow(); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/VerificationCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/VerificationCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 VerificationCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/VerificationCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/VerificationCommand.java 26 Jul 2008 19:22:03 -0000 >@@ -13,6 +13,7 @@ > > import java.io.File; > import java.lang.reflect.Constructor; >+import java.net.MalformedURLException; > import java.net.URL; > import java.util.Hashtable; > import java.util.StringTokenizer; >@@ -25,374 +26,549 @@ > import org.eclipse.jdt.core.IJavaProject; > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.core.VerifHookClassLoader; >-import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; > import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIVerificationHook; >+import org.eclipse.tptp.test.auto.gui.internal.util.VerificationHookClassLoader; > import org.eclipse.ui.IEditorPart; > import org.eclipse.ui.IViewPart; > import org.w3c.dom.Node; > >- > /** >- * The following command is inserted for every verification hook that the >- * user inserts for a particular test case. An instance of this class can >- * only be created through constructInstance(Event). <br/> >- * In order for clients to be able to write or playback this command they must >- * meet the following pre-conditions. >+ * The following command is inserted for every verification hook that the user >+ * inserts for a particular test case. An instance of this class can only be >+ * created through constructInstance(Event). <br/> In order for clients to be >+ * able to write or playback this command they must meet the following >+ * pre-conditions. > * > * <ul> >- * <li> test suite must be set using setTestSuite </li> >- * <li> verification hook must be set using setVerificationHook </li> >+ * <li> test suite must be set using setTestSuite </li> >+ * <li> verification hook must be set using setVerificationHook </li> > * </ul> > * > * @author Ali Mehregani >+ * @author Alexander Nyssen (refactored to be a normal object based command and >+ * use the new resolving mechanism) > */ >-public class VerificationCommand extends AbstractMacroCommand >-{ >+public class VerificationCommand extends ObjectBasedCommand { >+ > /* The type of this command */ >- public static final String TYPE = "verification"; >+ public static final String TYPE = IMacroCommand.VERIFICATION; >+ >+ /* The possible types */ >+ public static final byte EDITOR = 0x01; >+ public static final byte VIEW = 0x02; >+ public static final byte SHELL = 0x03; >+ >+ /* The location is the plugin that contains the hook source code */ >+ private String location; >+ >+ /* The resource is the class name containing the hook */ >+ private String resource; >+ >+ /* The hook is the method name representing the verification point */ >+ private String hook; >+ >+ /* The focus type indicates whether the type of context being retrieved */ >+ private byte focusType; >+ >+ private Class contextClass; >+ >+ private Class widgetClass; >+ >+ private Class objectClass; >+ >+ /* >+ * flag to indicate if additionally to the context id, an object id should >+ * be used as verification hook target >+ */ >+ private boolean extendedScope = false; > >- /* This instance variable is updated if at any point there is an error >- * creating an instance of this class through constructInstance. This can >- * be null if no errors are to be reported */ >- private static String error; >- >- /* The meta data required by this verification command */ >- private VerificationMetaData metaData; >- >- /* To be acknowledged events */ >- private static WidgetIdentifier toBeAck; >- > /** >- * The constructor >+ * The constructor > * >- * @param metaData The meta data that this verification command uses to write >- * or play back itself. >+ * @param metaData >+ * The meta data that this verification command uses to write or >+ * play back itself. > */ >- public VerificationCommand (MacroCommandShell parent, VerificationMetaData metaData) >- { >- super(parent, WidgetIdentifier.NULL_IDENTIFIER); /* The widget id is irrelevant in the verification command. This is just a dummy command */ >- this.metaData = metaData; >+ public VerificationCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public String getType() { > return TYPE; > } > >- public void processEvent(Event e) >- { >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand#processEvent(org.eclipse.swt.widgets.Event) >+ */ >+ public void doProcessEvent(Event event) { >+ focusType = findFocusType(getMacroObjectIdentifier() >+ .getContextIdentifier()); >+ contextClass = findContextClass(getMacroObjectIdentifier() >+ .getContextIdentifier()); >+ widgetClass = macroObject.getUIObject().getWidget().getClass(); >+ if (macroObject.getUIObject().getObject() != null) { >+ objectClass = macroObject.getUIObject().getObject().getClass(); >+ } > } > > /** > * A chance to build the meta-data of this verification command > */ >- public void load(Node node, Hashtable lineTable) >- { >- /* Bind the source location */ >- super.bindSourceLocation(node, lineTable); >- >- /* Construct the meta data here */ >- VerificationMetaData metaData = getMetaData(); >- >- String contextId = MacroUtil.getAttribute(node, "contextId"); >- metaData.setContextId(contextId); >- metaData.setFocusType(MacroUtil.findFocusType(contextId)); >- metaData.setLocation(MacroUtil.getAttribute(node, "location")); >- metaData.setResource(MacroUtil.getAttribute(node, "resource")); >- metaData.setHook(MacroUtil.getAttribute(node, "hook")); >- } >- >- >- /** >- * Invoked when this writable object is ready to be written to >- * a print writer. >- */ >- public void write(int indent, StringBuffer sb) >- { >- if (!metaData.isComplete()) >- return; >- >- /* If the default package is selected for a verification hook class, >- * it is often prefixed with a '.' This needs to be taken out before >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, lineTable); >+ >+ // String contextId = MacroUtil.getAttribute(node, >+ // "contextId"); >+ focusType = findFocusType(getMacroObjectIdentifier() >+ .getContextIdentifier()); >+ contextClass = findContextClass(getMacroObjectIdentifier() >+ .getContextIdentifier()); >+ location = MacroUtil.getAttribute(node, "location"); >+ resource = MacroUtil.getAttribute(node, "resource"); >+ hook = MacroUtil.getAttribute(node, "hook"); >+ // if the hook has more than one parameter, we are in extended scope >+ // mode >+ setExtendedScope(hook.indexOf(';') != hook.lastIndexOf(";")); >+ // if we are in extended mode, we have to load the object class. >+ if (isExtendedScope()) { >+ widgetClass = findWidgetClass(hook); >+ objectClass = findObjectClass(hook); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#loadMacroObjectIdentifier(org.w3c.dom.Node, >+ * java.util.Hashtable) >+ */ >+ protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable) >+ throws CoreException { >+ // let the super implementation try (in case we are in extended mode, >+ // this should build a valid descriptor) >+ super.loadMacroObjectIdentifier(node, lineTable); >+ >+ // if we are not in extended mode, just set the context id >+ if (getMacroObjectIdentifier() == null) { >+ String cid = MacroUtil.getAttribute(node, >+ MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ setMacroObjectIdentifier(new MacroObjectIdentifier(cid, null)); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#writeMacroObjectIdentifier(int, >+ * java.lang.StringBuffer, boolean, boolean) >+ */ >+ protected void writeMacroObjectIdentifier(int indent, StringBuffer sb, >+ boolean close, boolean end) { >+ if (isExtendedScope()) { >+ // write the normal triple (contextID, objectID, resolverID) >+ super.writeMacroObjectIdentifier(indent, sb, close, end); >+ } else { >+ // only write the context id >+ MacroUtil.addAttribute(sb, >+ new String[] { MacroConstants.CONTEXT_ID_ATTRIBUTE }, >+ new String[] { getMacroObjectIdentifier() >+ .getContextIdentifier() }, close, end); >+ } >+ } >+ >+ /** >+ * Invoked when this writable object is ready to be written to a print >+ * writer. >+ */ >+ public void write(int indent, StringBuffer sb) { >+ // let the super implementation write the element, we will just add our >+ // attributes >+ super.write(indent, sb); >+ /* >+ * If the default package is selected for a verification hook class, it >+ * is often prefixed with a '.' This needs to be taken out before > * written as part of the macro > */ >- String resource = metaData.getResource(); >- if (resource != null && resource.length() > 0 && resource.charAt(0) == '.') >+ if (resource != null && resource.length() > 0 >+ && resource.charAt(0) == '.') > resource = resource.substring(1); >- >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, >- new String[] {MacroConstants.TYPE_ATTRIBUTE, >- MacroConstants.CONTEXT_ID_ATTRIBUTE, >- MacroConstants.LOCATION_ATTRIBUTE, >- MacroConstants.RESOURCE_ATTRIBUTE, >- MacroConstants.HOOK_ATTRIBUTE}, >- new String[] {getType(), >- metaData.getContextId(), >- metaData.getLocation(), >- resource, >- metaData.getHook()}, true, true); >- } >- >- >- /** >- * This doesn't involve any UI actions. Playing back the verification command will >- * simply run the verification hook. >- * @throws CoreException >- */ >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- /* Phases: >- * 1. Load the necessary class >- * 2. Do the method look up on the hook entry >- * 3. If valid: >- * 4. Load its context (i.e. View/Editor/etc...) >- * 5. Invoke the hook with the context >+ >+ MacroUtil.addAttribute(sb, new String[] { >+ /* >+ * MacroConstants.TYPE_ATTRIBUTE, MacroConstants.CONTEXT_ID_ATTRIBUTE, > */ >- >+ MacroConstants.LOCATION_ATTRIBUTE, MacroConstants.RESOURCE_ATTRIBUTE, >+ MacroConstants.HOOK_ATTRIBUTE }, new String[] {/* >+ * getType(), >+ * metaData.getContextId(), >+ */ >+ location, resource, hook }, true, true); >+ >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#useObjectMine() >+ */ >+ protected boolean useObjectMine() { >+ // verification commands do never use the object mine (why?) >+ return false; >+ } >+ >+ private Class findWidgetClass(String hook) { >+ // parse the hook signature to retrieve the class name of the widget >+ // class >+ String className = hook.substring(hook.indexOf(";Q") + 2, hook.indexOf( >+ ";", hook.indexOf(";Q") + 2)); >+ try { >+ return loadClass(className); >+ } catch (Exception e) { >+ return null; >+ } >+ } >+ >+ private Class findObjectClass(String hook) { >+ // see if we have also an object parameter >+ String className = hook.substring(hook.indexOf(";Q", >+ hook.indexOf(";Q") + 2) + 2, hook.lastIndexOf(";")); >+ try { >+ return loadClass(className); >+ } catch (Exception e) { >+ return null; >+ } >+ } >+ >+ private Class loadClass(String className) throws MalformedURLException, >+ CoreException, ClassNotFoundException { > String classPath = System.getProperty("java.class.path"); >- try >- { >- Vector reqPlugins = null; >- >- >- /* If we happen to run in the quick run mode, then we need to explicitly modify the >- * class path ourself. */ >- if (MacroManager.getInstance().getGlobalState() == MacroManager.QUICK_RUN_MODE) >- { >- /* The project is expected to be a java project */ >- IJavaProject javaProject = AutoGUIUtil.findJavaProject(metaData.getLocation()); >- >- /* We need to add the output folder of all the java projects in our workspace to the classpath */ >- classPath += AutoGUIUtil.appendWSProjOutputFolder(classPath); >- >- if (javaProject != null && javaProject.exists()) >- { >- /* Add the classpath entries of the project */ >- reqPlugins = new Vector(5); >- classPath += AutoGUIUtil.findDependencies (javaProject, reqPlugins, true); >- } >- } >- >- /* Otherwise we're running in execution mode. We'll still need to resolve the dependencies of the plugin >- * containing the test suite. If any exists, then it would have been registerd with the MacroManager. */ >- else >- { >- reqPlugins = MacroManager.getInstance().getDependecies(); >- } >- >- StringTokenizer st = new StringTokenizer (classPath, File.pathSeparator); >- Vector urlsVec = new Vector(10); >- >- /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=136157 */ >- final String PREFIX = "file:"; >- >- while (st.hasMoreTokens()) >- { >- String curURL = st.nextToken(); >- >- /* The URL class loader will require all directories to end with a forward slash */ >- if (!curURL.endsWith(".jar") && !curURL.endsWith("/")) >- curURL += "/"; >- >- urlsVec.add(new URL(PREFIX + curURL)); >+ Vector reqPlugins = null; >+ >+ /* >+ * If we happen to run in the quick run mode, then we need to explicitly >+ * modify the class path ourself. >+ */ >+ if (MacroManager.getInstance().getGlobalState() == ModeConstants.QUICK_RUN_MODE) { >+ /* The project is expected to be a java project */ >+ IJavaProject javaProject = AutoGUIUtil.findJavaProject(location); >+ >+ /* >+ * We need to add the output folder of all the java projects in our >+ * workspace to the classpath >+ */ >+ classPath += AutoGUIUtil.appendWSProjOutputFolder(classPath); >+ >+ if (javaProject != null && javaProject.exists()) { >+ /* Add the classpath entries of the project */ >+ reqPlugins = new Vector(5); >+ classPath += AutoGUIUtil.findDependencies(javaProject, >+ reqPlugins, true); > } >- >- /* Construct the urls */ >- URL[] urls = new URL[urlsVec.size()]; >- for (int i = 0; i < urls.length; i++) >- { >- urls[i] = (URL) urlsVec.get(i); >+ } >+ >+ /* >+ * Otherwise we're running in execution mode. We'll still need to >+ * resolve the dependencies of the plugin containing the test suite. If >+ * any exists, then it would have been registerd with the MacroManager. >+ */ >+ else { >+ reqPlugins = MacroManager.getInstance().getDependecies(); >+ } >+ >+ StringTokenizer st = new StringTokenizer(classPath, File.pathSeparator); >+ Vector urlsVec = new Vector(10); >+ >+ /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=136157 */ >+ final String PREFIX = "file:"; >+ >+ while (st.hasMoreTokens()) { >+ String curURL = st.nextToken(); >+ >+ /* >+ * The URL class loader will require all directories to end with a >+ * forward slash >+ */ >+ if (!curURL.endsWith(".jar") && !curURL.endsWith("/")) >+ curURL += "/"; >+ >+ urlsVec.add(new URL(PREFIX + curURL)); >+ } >+ >+ /* Construct the urls */ >+ URL[] urls = new URL[urlsVec.size()]; >+ for (int i = 0; i < urls.length; i++) { >+ urls[i] = (URL) urlsVec.get(i); >+ } >+ >+ ClassLoader customClassLoader = new VerificationHookClassLoader(urls, >+ this.getClass().getClassLoader(), reqPlugins); >+ return Class.forName(className, true, customClassLoader); >+ } >+ >+ /** >+ * This doesn't involve any UI actions. Playing back the verification >+ * command will simply run the verification hook. >+ * >+ * @throws CoreException >+ */ >+ public boolean playback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ /* >+ * Phases: 1. Load the necessary class 2. Do the method look up on the >+ * hook entry 3. If valid: 4. Load its context (i.e. View/Editor/etc...) >+ * 5. Invoke the hook with the context >+ */ >+ try { >+ Class verifyHookClass = loadClass(resource); >+ >+ if (isExtendedScope()) { >+ macroObject = MacroObjectResolver.deresolve(getParent() >+ .getShell(), getMacroObjectIdentifier()); > } >- >- >- ClassLoader customClassLoader = new VerifHookClassLoader (urls, this.getClass().getClassLoader(), reqPlugins); >- Class verifyHookClass = Class.forName(metaData.getResource(), true, customClassLoader); >- >- Object[] args = new Object[1]; >- String contextId = new Path(metaData.getContextId()).segment(1); >- >- if (metaData.getFocusType() == VerificationMetaData.VIEW) >- { >- IViewPart view = MacroObjectLocator.locateView(display.getActiveShell(), contextId, getStartLine()); >+ >+ Object[] args = isExtendedScope() ? (macroObject.getUIObject() >+ .getObject() != null ? new Object[3] : new Object[2]) >+ : new Object[1]; >+ String contextId = new Path(getMacroObjectIdentifier() >+ .getContextIdentifier()).segment(1); >+ >+ if (focusType == VIEW) { >+ IViewPart view = MacroUtil.locateView(display.getActiveShell(), >+ contextId); > args[0] = view; >- } >- else if (metaData.getFocusType() == VerificationMetaData.EDITOR) >- { >- IEditorPart editor = MacroObjectLocator.locateEditor(display.getActiveShell(), contextId, getStartLine(), null); >+ } else if (focusType == EDITOR) { >+ IEditorPart editor = MacroUtil.locateEditor(display >+ .getActiveShell(), contextId, null); > args[0] = editor; >- } >- else if (metaData.getFocusType() == VerificationMetaData.SHELL) >- { >+ } else if (focusType == SHELL) { > Shell shell = getParent().getShell(); > args[0] = shell; > } >- >+ >+ if (isExtendedScope()) { >+ args[1] = macroObject.getUIObject().getWidget(); >+ if (macroObject.getUIObject().getObject() != null) { >+ args[2] = macroObject.getUIObject().getObject(); >+ } >+ } >+ > /* Construct the test case */ > HyadesTestSuite testSuite = new HyadesTestSuite(); >- Constructor constructor = verifyHookClass.getConstructor(new Class[] {String.class, Class[].class, Object[].class}); >- >- String testMethodName = MacroUtil.findMethodName(metaData); >- Class[] testMethodParams = MacroUtil.findParameterType(metaData); >- AutoGUIVerificationHook verificationHook = (AutoGUIVerificationHook) constructor.newInstance(new Object[] {testMethodName,testMethodParams , args}); >- verificationHook.setTestInvocationId("invocation-id-" + System.currentTimeMillis()); >+ Constructor constructor = verifyHookClass >+ .getConstructor(new Class[] { String.class, Class[].class, >+ Object[].class }); >+ >+ String testMethodName = findMethodName(hook); >+ >+ Class[] testMethodParams = isExtendedScope() ? (macroObject >+ .getUIObject().getObject() != null ? new Class[] { >+ getContextClass(), getWidgetClass(), getObjectClass() } >+ : new Class[] { getContextClass(), getWidgetClass() }) >+ : new Class[] { getContextClass() }; >+ AutoGUIVerificationHook verificationHook = (AutoGUIVerificationHook) constructor >+ .newInstance(new Object[] { testMethodName, >+ testMethodParams, args }); >+ verificationHook.setTestInvocationId("invocation-id-" >+ + System.currentTimeMillis()); > testSuite.addTest(verificationHook); >- >- /* If we are running in quick mode, then report verification test methods that are missing */ >- if (MacroManager.getInstance().getGlobalState() == MacroManager.QUICK_RUN_MODE) >- { >- try >- { >- verificationHook.getClass().getMethod(testMethodName, testMethodParams); >- } >- catch (NoSuchMethodException e) >- { >- AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF_T, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF, new String[] {testMethodName, String.valueOf(getStartLine())}), >- MessageDialog.WARNING); >+ >+ /* >+ * If we are running in quick mode, then report verification test >+ * methods that are missing >+ */ >+ if (MacroManager.getInstance().getGlobalState() == ModeConstants.QUICK_RUN_MODE) { >+ try { >+ verificationHook.getClass().getMethod(testMethodName, >+ testMethodParams); >+ } catch (NoSuchMethodException e) { >+ AutoGUIUtil >+ .showMessage( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF_T, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF, >+ new String[] { >+ testMethodName, >+ String >+ .valueOf(getStartLine()) }), >+ MessageDialog.WARNING); > } > } >- MacroManager.getInstance().getRunner().runVerificaitonHook(testSuite); >- >+ MacroManager.getInstance().getRunner().runVerificationHook( >+ testSuite); >+ > return true; >- >- } >- catch (ClassNotFoundException e) >- { >- /* The class was not found. The classpath should have been set by the deployment adapter >- * (JavaExecutionDeploymentAdapter) and the file should have been transferred to the >- * system's temporary directory. This is an internal error */ >- String[] args = {metaData.getResource(), metaData.getHook(), classPath}; >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_F, args), super.getStartLine(), e); >- } >- catch (InstantiationException e) >- { >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_INSTANTIATE, metaData.getResource()), super.getStartLine(), e); >- } >- catch (CoreException e) >- { >- String[] args = {metaData.getContextId(), metaData.getHook()}; >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CONTEXT, args), super.getStartLine()); >- } >- catch (IllegalArgumentException e) >- { >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_VER_ARG_EXCEPT, super.getStartLine()); >- } >- catch (Exception e) >- { >- AutoGUIUtil.throwCoreException(AutoGUIUtil.getOriginOfException(e), super.getStartLine(), e); >+ >+ } catch (ClassNotFoundException e) { >+ e.printStackTrace(); >+ /* >+ * The class was not found. The classpath should have been set by >+ * the deployment adapter (JavaExecutionDeploymentAdapter) and the >+ * file should have been transferred to the system's temporary >+ * directory. This is an internal error >+ */ >+ String[] args = { resource, hook }; >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_F, args), >+ super.getStartLine(), e); >+ } catch (CoreException e) { >+ e.printStackTrace(); >+ String[] args = { >+ getMacroObjectIdentifier().getContextIdentifier(), hook }; >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_CONTEXT, args), super >+ .getStartLine()); >+ } catch (InstantiationException e) { >+ e.printStackTrace(); >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_INSTANTIATE, resource), >+ super.getStartLine(), e); >+ } catch (IllegalArgumentException e) { >+ e.printStackTrace(); >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_ARG_EXCEPT, super >+ .getStartLine()); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ AutoGUIUtil.throwCoreException(AutoGUIUtil.getOriginOfException(e), >+ super.getStartLine(), e); > } >- >+ > return false; > } > >+ /** >+ * Given a context id, return the focus type. >+ * >+ * @param contextId >+ * The id of the context >+ * @return The type of the context (i.e. focus type). -1 is returned if the >+ * focus type is not recognized. >+ */ >+ public static byte findFocusType(String contextId) { >+ if (contextId.startsWith(MacroConstants.VIEW_VALUE + "/")) >+ return VIEW; >+ else if (contextId.startsWith(MacroConstants.EDITOR_VALUE + "/")) >+ return EDITOR; >+ else if (contextId.startsWith(MacroConstants.SHELL_VALUE + "/")) >+ return SHELL; > >- >+ return -1; >+ } > > /** >- * Returns an instance of this class based an event. The returned value is null >- * if an error occurs while constructing the instance. Check the value returned >- * by getError to determine the error that has occurred. >+ * Find the method name corresponding the verification hook > * >- * @param event The event >- * @return An instance of this class >+ * @param metaData >+ * @return > */ >- public synchronized static VerificationCommand constructInstance (MacroCommandShell parent, Event event) >- { >- VerificationCommand instance = null; >- >- error = ""; >- if (MacroUtil.isIgnorableEvent(event)) >- { >- error = ""; /* We don't want to report anything */ >+ public static String findMethodName(String hook) { >+ String methodName = hook; >+ >+ if (methodName == null || methodName.length() <= 0) > return null; >- } >- >- try >- { >- /* Ignore all command except for a focus in command */ >- switch (event.type) >- { >- case SWT.Activate: >- case SWT.Selection: >- case SWT.FocusIn: >- >- WidgetIdentifier widgetID = MacroUtil.getVerificationContextIdentifier(event); >- String path = (widgetID == null ? "" : widgetID.getFullyQualifiedPath().toString()); >- >- if (MacroUtil.findFocusType(path) == -1) >- { >- error = AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON; >- break; >- } >- >- /* We only acknowledge after there is a mouse up event */ >- toBeAck = widgetID; >- break; >- >- case SWT.MouseUp: >- >- if (toBeAck == null) >- break; >- >- /* Build the verification meta data -- we only know the context id and the focus type at this point */ >- VerificationMetaData metaData = new VerificationMetaData(); >- String contextId = toBeAck.getContextId().toString(); >- metaData.setContextId(contextId); >- metaData.setFocusType(MacroUtil.findFocusType(contextId)); >- >- /* Create the verification command instance */ >- instance = new VerificationCommand (parent, metaData); >- break; >- >- default: >- toBeAck = null; >- error = AutoGUIMessages.AUTO_GUI_ERROR_VER_WRONG_EVENT; >- } >- >- return instance; >- } >- catch (Exception e) >- { >- error = e.getMessage(); >- e.printStackTrace(); >+ >+ int index = methodName.indexOf(':'); >+ if (index != -1) >+ return methodName.substring(0, index); >+ >+ return methodName; >+ } >+ >+ /** >+ * Find the parameter types of the verificaiton hook >+ * >+ * @param metaData >+ * @return >+ */ >+ private Class findContextClass(String contextId) { >+ Class param = null; >+ byte focusType = findFocusType(contextId); >+ if (focusType == EDITOR) >+ param = IEditorPart.class; >+ else if (focusType == VIEW) >+ param = IViewPart.class; >+ else if (focusType == SHELL) >+ param = Shell.class; >+ >+ return param; >+ } >+ >+ /** >+ * Return the class name containing the verification point that this meta >+ * data points to. >+ * >+ * @param metaData >+ * The verification point's meta data >+ * @return The class name. null is returned if it can't be determined >+ */ >+ public static String getClassName(String resource) { >+ String className = resource; >+ >+ if (className == null || className.length() <= 0) > return null; >- } >+ >+ int index = className.lastIndexOf('.'); >+ if (index != -1) >+ return className.substring(index + 1, className.length()); >+ return className; > } > >- >- public static String getError() >- { >- return error; >+ public void setLocation(String location) { >+ this.location = location; > } > >- public static void setError(String error) >- { >- VerificationCommand.error = error; >+ public void setResource(String resource) { >+ this.resource = resource; > } > >- public VerificationMetaData getMetaData() >- { >- return metaData; >+ public void setHook(String hook) { >+ this.hook = hook; > } > >- public void setMetaData(VerificationMetaData metaData) >- { >- this.metaData = metaData; >+ public Class getObjectClass() { >+ return objectClass; >+ } >+ >+ public Class getWidgetClass() { >+ return widgetClass; >+ } >+ >+ public Class getContextClass() { >+ return contextClass; >+ } >+ >+ public String getLocation() { >+ return location; > } >- >-} > >+ public String getResource() { >+ return resource; >+ } >+ >+ public String getHook() { >+ return hook; >+ } >+ >+ public boolean isExtendedScope() { >+ return extendedScope; >+ } >+ >+ public void setExtendedScope(boolean extendedScope) { >+ this.extendedScope = extendedScope; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/KeyEventCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/KeyEventCommand.java,v >retrieving revision 1.2 >diff -u -r1.2 KeyEventCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/KeyEventCommand.java 27 Oct 2006 14:39:12 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/KeyEventCommand.java 26 Jul 2008 19:22:01 -0000 >@@ -11,162 +11,140 @@ > *******************************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.commands; > >-import java.util.ArrayList; > import java.util.Hashtable; > > import org.eclipse.core.runtime.CoreException; > import org.eclipse.swt.SWT; > import org.eclipse.swt.widgets.Event; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > import org.w3c.dom.Node; > > /** >- * A concrete extension of PositionBasedCommand that is used to represent SWT.KeyUp >- * and SWT.KeyDown events. >+ * A concrete extension of PositionBasedCommand that is used to represent >+ * SWT.KeyUp and SWT.KeyDown events. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen (refactoring) > */ >-public class KeyEventCommand extends PositionBasedCommand >-{ >- public static String TYPE0 = "key-up"; >- public static String TYPE1 = "key-down"; >- public static String TYPE2 = "key-press"; >- >- private String type; /* The type of the event (either TYPE0 or TYPE1) */ >- private int button; /* The key pressed or released */ >- private boolean isCharSet; /* Set when the character field of event is used as opposed to >- the keyCode */ >- public KeyEventCommand(MacroCommandShell parent) >- { >- super(parent, null); >+public class KeyEventCommand extends PositionBasedCommand { >+ >+ private boolean isCharSet; /* >+ * Set when the character field of event is used >+ * as opposed to the keyCode >+ */ >+ >+ public KeyEventCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public String getType() { > return type; > } > >- public void processEvent(Event e) >- { >- if (e.character > 0) >- { >- button = e.character; >- isCharSet = true; >+ public boolean mergeEvent(Event e) throws Exception { >+ /* >+ * Defect #: 110726 -- Make the key events consistent with the mouse >+ * event and introduce a notion of key-press >+ */ >+ if (e.type == SWT.KeyUp && type != null && type.equals(KEY_DOWN) >+ && isCharSet(e) ? isCharSet && detail.intValue() == e.character >+ : !isCharSet && detail.intValue() == e.keyCode) { >+ >+ type = KEY_PRESS; >+ return true; > } >- else if (e.keyCode > 0) >- button = e.keyCode; >- >- if (e.type == SWT.KeyUp) >- { >- /* Defect #: 110726 -- Make the key events consistent with the mouse event and >- * introduce a notion of key-press */ >- ArrayList commands = getParent().getCommands(); >- int commandSize; >- if (commands != null && (commandSize = commands.size()) > 0) >- { >- Object lastCommand = commands.get(commandSize - 1); >- if (lastCommand instanceof KeyEventCommand) >- { >- int lastButton = ((KeyEventCommand)lastCommand).getButton(); >- boolean lastIsCharSet = ((KeyEventCommand)lastCommand).isCharSet(); >- if (button == lastButton && isCharSet == lastIsCharSet) >- { >- type = TYPE2; >- commands.remove(commandSize - 1); >- return; >- } >- } >- } >- >- type = TYPE0; >- type = TYPE0; >+ return false; >+ } >+ >+ private boolean isCharSet(Event e) { >+ return e.character > 0; >+ } >+ >+ protected Integer determineDetail(Event e) { >+ Integer detail = null; >+ if (e.character > 0) { >+ detail = new Integer(e.character); >+ >+ } else if (e.keyCode > 0) { >+ detail = new Integer(e.keyCode); >+ } >+ return detail; >+ } >+ >+ protected String determineType(Event e) { >+ String type = null; >+ if (e.type == SWT.KeyUp) { >+ type = KEY_UP; >+ } else if (e.type == SWT.KeyDown) { >+ type = KEY_DOWN; > } >- else if (e.type == SWT.KeyDown) >- type = TYPE1; >+ return type; > } >- >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ >+ public void processEvent(Event e) throws Exception { >+ super.processEvent(e); >+ >+ isCharSet = e.character > 0; >+ } >+ >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); >- >- type = MacroUtil.getAttribute(node, "type"); >- button = Integer.parseInt(MacroUtil.getAttribute(node, "detail")); >- if (MacroConstants.TRUE_VALUE.equals(MacroUtil.getAttribute(node, "ischarset"))) >+ >+ if (MacroConstants.TRUE_VALUE.equals(MacroUtil.getAttribute(node, >+ "ischarset"))) > isCharSet = true; > } >- >- public void write(int indent, StringBuffer sb, boolean close, boolean end) >- { >- super.write(indent, sb, close, end); >- MacroUtil.addAttribute(sb, >- new String[] {MacroConstants.IS_CHAR_SET_ATTRIBUTE}, >- new String[] {String.valueOf(isCharSet)}, true, true); >- } >- >- >- public int getDetail() >- { >- return button; >+ >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ super.write(indent, sb, false, false); >+ MacroUtil.addAttribute(sb, >+ new String[] { MacroConstants.IS_CHAR_SET_ATTRIBUTE }, >+ new String[] { String.valueOf(isCharSet) }, true, true); > } > >- public Event[] constructSWTEvents() >- { >+ public Event[] constructSWTEvents() { > Event[] events; >- >- if (type.equals(TYPE2)) >+ >+ if (type.equals(KEY_PRESS)) > events = new Event[2]; > else > events = new Event[1]; >- >+ > Event keyUpEvent = new Event(), keyDownEvent = new Event(); > keyUpEvent.type = SWT.KeyUp; > keyDownEvent.type = SWT.KeyDown; >- >- if (isCharSet) >- { >- keyUpEvent.character = (char) button; >- keyDownEvent.character = (char) button; >- } >- else >- { >- keyUpEvent.keyCode = button; >- keyDownEvent.keyCode = button; >+ >+ if (isCharSet) { >+ keyUpEvent.character = (char) detail.intValue(); >+ keyDownEvent.character = (char) detail.intValue(); >+ } else { >+ keyUpEvent.keyCode = detail.intValue(); >+ keyDownEvent.keyCode = detail.intValue(); > } >- >- >- if (type.equals(TYPE0)) >+ >+ if (type.equals(KEY_UP)) > events[0] = keyUpEvent; >- else if (type.equals(TYPE1)) >- events[0] = keyDownEvent; >- else if (type.equals(TYPE2)) >- { >+ else if (type.equals(KEY_DOWN)) >+ events[0] = keyDownEvent; >+ else if (type.equals(KEY_PRESS)) { > events[0] = keyDownEvent; > events[1] = keyUpEvent; > } >- >- return events; >+ >+ return events; > } >- >- public boolean equals (Object obj) >- { >+ >+ public boolean equals(Object obj) { > if (!(obj instanceof KeyEventCommand)) > return false; >- >- KeyEventCommand keyEvent = (KeyEventCommand)obj; >- if (this.type.equals(keyEvent.getType()) && this.button == keyEvent.getButton()) >+ >+ KeyEventCommand keyEvent = (KeyEventCommand) obj; >+ if (this.type.equals(keyEvent.getType()) >+ && this.detail == keyEvent.getDetail()) > return true; > return false; > } > >- private int getButton() >- { >- return button; >- } >- >- private boolean isCharSet() >- { >- return isCharSet; >- } >- > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ChoiceSelectionCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/ChoiceSelectionCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 ChoiceSelectionCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/ChoiceSelectionCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/ChoiceSelectionCommand.java 26 Jul 2008 19:22:00 -0000 >@@ -14,246 +14,323 @@ > > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.Path; > import org.eclipse.swt.SWT; > import org.eclipse.swt.custom.CCombo; > import org.eclipse.swt.custom.CTabFolder; > import org.eclipse.swt.custom.CTabItem; > 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.Item; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.swt.widgets.TabFolder; > import org.eclipse.swt.widgets.TabItem; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; > import org.w3c.dom.Node; > >- > /** >- * A choice selection command represents a user selection of an item from >- * a set of items present. For example, selecting a specific tab from a tab >- * group or an item from a combo box. >+ * A choice selection command represents a user selection of an item from a set >+ * of items present. For example, selecting a specific tab from a tab group or >+ * an item from a combo box. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen (complete refactoring to use new widget resolving >+ * mechanism) > */ >-public class ChoiceSelectionCommand extends AbstractMacroCommand >-{ >- public static final String TYPE = "choice-select"; >- >- /** Widget types */ >- private static final byte WIDGET_TYPE_TAB_FOLDER = 0x00; >- private static final byte WIDGET_TYPE_CTAB_FOLDER = 0x01; >- private static final byte WIDGET_TYPE_COMBO = 0x02; >- private static final byte WIDGET_TYPE_CCOMBO = 0x03; >- >- private Object choiceId; >- >- public ChoiceSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid) >- { >- super(parent, wid); >+public class ChoiceSelectionCommand extends SingleSelectionCommand { >+ >+ public static final String TYPE = IMacroCommand.CHOICE_SELECT; >+ >+ // ANy: this field is only needed for backwards compatibility issues >+ private String choiceId = null; >+ >+ // /** Widget types */ >+ // private static final byte WIDGET_TYPE_TAB_FOLDER = 0x00; >+ // private static final byte WIDGET_TYPE_CTAB_FOLDER = 0x01; >+ // private static final byte WIDGET_TYPE_COMBO = 0x02; >+ // private static final byte WIDGET_TYPE_CCOMBO = 0x03; >+ >+ public ChoiceSelectionCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public String getType() { > return TYPE; > } > >- public void processEvent(Event e) >- { >- choiceId = resolveChoiceId(e.widget, e.item, MacroUtil.newCounter()); >- >- boolean isCombo = e.widget instanceof Combo; >- boolean isCCombo = e.widget instanceof CCombo; >- >- Combo combo = isCombo ? (Combo)e.widget : null; >- CCombo ccombo = isCCombo ? (CCombo)e.widget : null; >- Object item = isCombo ? combo.getItem(combo.getSelectionIndex()) : (isCCombo ? (Object)ccombo.getItem(ccombo.getSelectionIndex()) : e.item); >- >- choiceId = choiceId == null ? computeDefaultChoiceId(e.widget, item) : choiceId; >- >- if (isCombo || isCCombo) >- { >- setDescriptiveField(isCombo ? combo.getItem(combo.getSelectionIndex()) : ccombo.getItem(ccombo.getSelectionIndex())); >+ protected IMacroObject locateMacroObject(Event event) { >+ // find the selected item >+ boolean isCombo = event.widget instanceof Combo; >+ boolean isCCombo = event.widget instanceof CCombo; >+ >+ Combo combo = isCombo ? (Combo) event.widget : null; >+ CCombo ccombo = isCCombo ? (CCombo) event.widget : null; >+ Object item = isCombo ? combo.getItem(combo.getSelectionIndex()) >+ : (isCCombo ? (Object) ccombo.getItem(ccombo >+ .getSelectionIndex()) : event.item); >+ >+ // if the item is itself a widget it can be resolved without its parent >+ // widget, e.g. in case of a TabItem or CTabItem >+ if (item != null && item instanceof Widget) { >+ return new MacroObject(new UIObject((Widget) item)); >+ } else { >+ return new MacroObject(new UIObject(event.widget, item)); > } >- else >- { >+ } >+ >+ // @Override >+ // protected void writeMacroObject(int indent, StringBuffer sb, boolean >+ // close, >+ // boolean end) { >+ // >+ // // remove the trailing path fragment and store it separately (for >+ // // backwards compatibility) >+ // MacroObjectIdentifier identifier = (MacroObjectIdentifier) >+ // getMacroObjectIdentifier(); >+ // String originalContextId = identifier.getContextIdentifier(); >+ // String originalObjectId = identifier.getObjectIdentifier() >+ // .getObjectId(); >+ // String resolverId = identifier.getObjectIdentifier().getResolverId(); >+ // String choiceId = new Path(originalObjectId).removeFirstSegments(1) >+ // .toString(); >+ // >+ // setMacroObjectIdentifier(new MacroObjectIdentifier(originalContextId, >+ // new PrimitiveUIObjectIdentifier(new Path(originalObjectId).segment(0) >+ // .toString(), resolverId))); >+ // >+ // super.writeMacroObject(indent, sb, false, false); >+ // >+ // setMacroObjectIdentifier(identifier); >+ // >+ // MacroUtil.addAttribute(sb, >+ // new String[] { MacroConstants.CHOICE_ID_ATTRIBUTE }, >+ // new String[] { choiceId == null || choiceId.equals("") ? null >+ // : choiceId.toString() }, close, end); >+ // } >+ >+ protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable) >+ throws CoreException { >+ super.loadMacroObjectIdentifier(node, lineTable); >+ >+ // for backwards compatibility, the choice id is read (if present) and >+ // appended to the macro object identifier >+ MacroObjectIdentifier identifier = (MacroObjectIdentifier) getMacroObjectIdentifier(); >+ >+ // ANy: added for backwards compatibility, in case we have a macro that >+ // still has the choice id attribute stored >+ choiceId = MacroUtil.getAttribute(node, >+ MacroConstants.CHOICE_ID_ATTRIBUTE); >+ } >+ >+ public void doProcessEvent(Event e) { >+ if (e.widget instanceof Combo || e.widget instanceof CCombo) { >+ setDescriptiveField(e.widget instanceof Combo ? ((Combo) e.widget) >+ .getItem(((Combo) e.widget).getSelectionIndex()) >+ : ((CCombo) e.widget).getItem(((CCombo) e.widget) >+ .getSelectionIndex())); >+ } else { > findDescriptiveField(e.item); > } > } > >- private Object resolveChoiceId (Widget widget, Object item, int[] resolverIndex) >- { >- return MacroManager.getInstance().resolveWidget(widget, item, getWidgetId().getResolverId(), resolverIndex); >- } >- >- >- private Object computeDefaultChoiceId(Widget widget, Object item) >- { >- int index = -1; >- boolean isCombo = widget instanceof Combo; >- boolean isCCombo = isCombo ? false : widget instanceof CCombo; >- if (isCombo || isCCombo) >- { >- Combo combo = isCombo ? ((Combo)widget) : null; >- CCombo ccombo = isCCombo ? ((CCombo)widget) : null; >- >- index = isCombo ? combo.indexOf((String)item) : ccombo.indexOf((String)item); >- } >- else >- { >- boolean isTabFolder = widget instanceof TabFolder; >- boolean isCTabFolder = isTabFolder ? false : widget instanceof CTabFolder; >- if (isTabFolder || isCTabFolder) >- { >- index = isTabFolder ? ((TabFolder)widget).indexOf((TabItem)item) : ((CTabFolder)widget).indexOf((CTabItem)item); >+ // public void load(Node node, Hashtable lineTable) throws CoreException { >+ // super.load(node, lineTable); >+ // String choiceId = MacroUtil.getAttribute(node, >+ // MacroConstants.CHOICE_ID_ATTRIBUTE); >+ // } >+ // >+ >+ // public void write(int indent, StringBuffer sb) { >+ // super.write(indent, sb); >+ // MacroUtil.addAttribute(sb, >+ // new String[] { MacroConstants.CHOICE_ID_ATTRIBUTE }, >+ // new String[] { choiceId == null ? null : choiceId.toString() }, >+ // true, true); >+ // } >+ >+ public boolean playback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ IMacroObjectIdentifier identifier = getMacroObjectIdentifier(); >+ // backwards compatibility issues >+ if (choiceId != null && !choiceId.equals("")) { >+ // we need to deresolve here to decide wether we have an identifier >+ // for a Combo (CCombo) or a TabFolder (CTabFolder) >+ IMacroObject macroObject = MacroObjectResolver.deresolve( >+ getParent().getShell(), identifier); >+ if (macroObject.getUIObject().getWidget() instanceof Combo >+ || macroObject.getUIObject().getWidget() instanceof CCombo) { >+ // set the enhanced identifier that used the object id to denote >+ // the String item on the Combo or CCombo >+ setMacroObjectIdentifier(new MacroObjectIdentifier(identifier >+ .getContextIdentifier(), >+ new PrimitiveUIObjectIdentifier(identifier >+ .getObjectIdentifier().getWidgetId(), choiceId, >+ identifier.getObjectIdentifier() >+ .getResolverId()))); >+ } else if (macroObject.getUIObject().getWidget() instanceof TabFolder >+ || macroObject.getUIObject().getWidget() instanceof CTabFolder) { >+ // compute a new macro object identifier, the old one points to >+ // the tabFolder >+ String contextId = new Path(MacroConstants.TAB_VALUE).append( >+ MacroObjectIdentifier >+ .serializeMacroObjectIdentifier(identifier)) >+ .toString(); >+ String widgetId = choiceId; >+ setMacroObjectIdentifier(new MacroObjectIdentifier(contextId, >+ new PrimitiveUIObjectIdentifier(widgetId, identifier >+ .getObjectIdentifier().getResolverId()))); > } > } >- >- if (index != -1) >- return "item#" + index; >- return null; >- } >- >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >- super.load(node, lineTable); >- choiceId = MacroUtil.getAttribute(node, MacroConstants.CHOICE_ID_ATTRIBUTE); >- } >- >- public void write(int indent, StringBuffer sb) >- { >- super.write(indent, sb); >- MacroUtil.addAttribute(sb, >- new String[] {MacroConstants.CHOICE_ID_ATTRIBUTE}, >- new String[] {choiceId == null ? null : choiceId.toString()}, >- true, true); >- } >- >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine()); >- if (targets == null) >+ return super.playback(display, parent, monitor); >+ } >+ >+ public boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ >+ // deresolve the macro object (using the old path format (the choice id >+ // was kept separately before) -> locating a child with the given item >+ // suffix does not work yet) >+ // Path path = new Path(getMacroObjectIdentifier().getObjectIdentifier() >+ // .getObjectId()); >+ // String oldObjectId = path.segmentCount() > 1 ? >+ // path.removeLastSegments( >+ // 1).toString() : path.toString(); >+ >+ // IMacroObject target = MacroObjectResolver.deresolve(parent, >+ // getMacroObjectIdentifier()); >+ // // new MacroObjectIdentifier(getMacroObjectIdentifier() >+ // .getContextIdentifier(), >+ // new PrimitiveUIObjectIdentifier(oldObjectId, >+ // getMacroObjectIdentifier() >+ // .getObjectIdentifier() >+ // .getResolverId()))); >+ >+ if (macroObject == null) { > return false; >- >- CommandTarget target = targets[0]; >- target.setFocus(); >- Widget widget = target.getWidget(); >- if (widget instanceof TabFolder) >- { >- doSelect(WIDGET_TYPE_TAB_FOLDER, widget); >- } >- else if (widget instanceof CTabFolder) >- { >- doSelect(WIDGET_TYPE_CTAB_FOLDER, widget); >- } >- else if (widget instanceof Combo) >- { >- doSelect(WIDGET_TYPE_COMBO, widget); >- } >- else if (widget instanceof CCombo) >- { >- doSelect(WIDGET_TYPE_CCOMBO, (CCombo) widget); > } >- >+ >+ setFocus(macroObject); >+ doSelect(macroObject); >+ > return true; > } >- >- >- private void doSelect(byte widgetType, Widget widget) >- { >- Object[] items = null; >- switch (widgetType) >- { >- case WIDGET_TYPE_TAB_FOLDER: >- items = ((TabFolder)widget).getItems(); >- break; >- case WIDGET_TYPE_CTAB_FOLDER: >- items = ((CTabFolder)widget).getItems(); >- break; >- case WIDGET_TYPE_COMBO: >- items = ((Combo)widget).getItems(); >- break; >- case WIDGET_TYPE_CCOMBO: >- items = ((CCombo)widget).getItems(); >- break; >- } >- >- Object widgetId = null; >- int[] resolverIndex = MacroUtil.newCounter(); >- boolean foundItem = false; >- for (int i = 0; !foundItem && i < items.length; i++) >- { >- while (!foundItem && (widgetId = resolveChoiceId(widget, items[i], resolverIndex)) != null) >- { >- foundItem = foundItem (widgetType, widget, items[i], widgetId, i); >- } >- >- if (foundItem) >- break; >- resolverIndex[0] = 0; >- foundItem = foundItem (widgetType, widget, items[i], computeDefaultChoiceId(widget, items[i]), i); >+ >+ protected void doSelect(IMacroObject target) { >+ Widget widget = target.getUIObject().getWidget(); >+ Object object = target.getUIObject().getObject(); >+ >+ Widget parent = null; >+ Item item = null; >+ >+ if (widget instanceof Combo) { >+ Combo combo = (Combo) widget; >+ combo.select(combo.indexOf((String) object)); >+ parent = combo; >+ } else if (widget instanceof CCombo) { >+ CCombo combo = (CCombo) widget; >+ combo.select(combo.indexOf((String) object)); >+ parent = combo; >+ } >+ // TabItems and CTabItems are widgets themselves, so when selecting, >+ // they have to be passed into the event as item >+ else if (widget instanceof TabItem) { >+ TabItem tabItem = (TabItem) widget; >+ TabFolder tabFolder = tabItem.getParent(); >+ tabFolder.setSelection(tabItem); >+ parent = tabFolder; >+ item = tabItem; >+ } else if (widget instanceof CTabItem) { >+ CTabItem tabItem = (CTabItem) widget; >+ CTabFolder tabFolder = tabItem.getParent(); >+ tabFolder.setSelection(tabItem); >+ parent = tabFolder; >+ item = tabItem; > } >- } > >- private boolean foundItem(byte widgetType, Widget widget, Object item, Object itemId, int index) >- { >- if (itemId != null && itemId.equals(choiceId)) >- { >- switch(widgetType) >- { >- case WIDGET_TYPE_TAB_FOLDER: >- ((TabFolder)widget).setSelection(index); >- break; >- case WIDGET_TYPE_CTAB_FOLDER: >- ((CTabFolder)widget).setSelection(index); >- break; >- case WIDGET_TYPE_COMBO: >- ((Combo)widget).select(index); >- break; >- case WIDGET_TYPE_CCOMBO: >- ((CCombo)widget).select(index); >- break; >- } >- >- /* Ali M.: A set selection is not enough for Eclipse forms. We have to send out a selection event */ >- Event selectionEvent = new Event(); >- selectionEvent.type = SWT.Selection; >- selectionEvent.widget = widget; >- selectionEvent.display = widget.getDisplay(); >- selectionEvent.item = item instanceof Item ? (Item)item : null; >- widget.notifyListeners(SWT.Selection, selectionEvent); >- MacroUtil.processDisplayEvents(selectionEvent.display); >- >- return true; >- } >- >+ /* >+ * Ali M.: A set selection is not enough for Eclipse forms. We have to >+ * send out a selection event >+ */ >+ Event selectionEvent = new Event(); >+ selectionEvent.type = SWT.Selection; >+ selectionEvent.widget = parent; >+ selectionEvent.display = parent.getDisplay(); >+ selectionEvent.item = item; >+ widget.notifyListeners(SWT.Selection, selectionEvent); >+ MacroUtil.processDisplayEvents(selectionEvent.display); >+ } >+ >+ // private void doSelect(byte widgetType, Widget widget) { >+ // Object[] items = null; >+ // switch (widgetType) { >+ // case WIDGET_TYPE_TAB_FOLDER: >+ // items = ((TabFolder) widget).getItems(); >+ // break; >+ // case WIDGET_TYPE_CTAB_FOLDER: >+ // items = ((CTabFolder) widget).getItems(); >+ // break; >+ // case WIDGET_TYPE_COMBO: >+ // items = ((Combo) widget).getItems(); >+ // break; >+ // case WIDGET_TYPE_CCOMBO: >+ // items = ((CCombo) widget).getItems(); >+ // break; >+ // } >+ // >+ // // tries to determine the item by querying all resolves >+ // IUIObjectIdentifier widgetId = null; >+ // boolean foundItem = false; >+ // for (int i = 0; !foundItem && i < items.length; i++) { >+ // while (!foundItem >+ // && ((widgetId = MacroObjectResolver.resolve(new MacroObject(new >+ // UIObject(widget, items[i]))).getObjectIdentifier()) != null)) { >+ // foundItem = itemId != null >+ // && itemId.equals(getMacroObjectIdentifier() >+ // .getObjectIdentifier()) >+ // >+ // } >+ // >+ // if (foundItem) >+ // break; >+ // // foundItem = foundItem(widgetType, widget, items[i], >+ // // computeDefaultChoiceId(widget, items[i]), i); >+ // } >+ // } >+ >+ public boolean mergeEvent(Event e) throws Exception { > return false; > } >- >- >- public boolean mergeEvent(Event e) >- { >- return false; >+ >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ super.write(indent, sb, true, true); > } >- >+ > /** >- * Overwrite this method in order to indicate that two choice commands that have >- * different choice ids are not the same >+ * Overwrite this method in order to indicate that two choice commands that >+ * have different choice ids are not the same > */ >- public boolean equals (Object obj) >- { >+ public boolean equals(Object obj) { > if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj)) > return false; >- >- ChoiceSelectionCommand compareWithObj = (ChoiceSelectionCommand)obj; >- if ((this.choiceId != null && this.choiceId.equals(compareWithObj.choiceId)) || (this.choiceId == null && compareWithObj.choiceId == null)) >- return true; >- >- return false; >+ >+ return true; >+ // ChoiceSelectionCommand compareWithObj = (ChoiceSelectionCommand) obj; >+ // if ((this.choiceId != null && this.choiceId >+ // .equals(compareWithObj.choiceId)) >+ // || (this.choiceId == null && compareWithObj.choiceId == null)) >+ // return true; >+ // >+ // return false; > } > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/IMacroCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/IMacroCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 IMacroCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/IMacroCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/IMacroCommand.java 26 Jul 2008 19:22:00 -0000 >@@ -11,91 +11,111 @@ > package org.eclipse.tptp.test.auto.gui.internal.commands; > > import org.eclipse.swt.widgets.Event; >-import org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction; >- >+import org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > > /** >- * Represents a macro command that can be included as part of the >- * macro script or played back to perform a UI interaction. >+ * Represents a macro command that can be included as part of the macro script >+ * or played back to perform a UI interaction. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ >-public interface IMacroCommand extends IMacroInstruction >-{ >+public interface IMacroCommand extends IMacroInstruction { >+ /* command type constants */ >+ public static final String VERIFICATION = "verification"; >+ public static final String WAIT = "wait"; >+ public static final String MODIFY = "modify"; >+ public static final String SELECT = "select"; >+ public static final String ITEM_CHECK = "item-check"; >+ public static final String CHOICE_SELECT = "choice-select"; >+ public static final String CLOSE_WORKBENCHPART = "close-workbenchpart"; >+ public static final String ITEM_EXPAND = "item-expand"; >+ public static final String FOCUS = "focus"; >+ public static final String KEY_UP = "key-up"; >+ public static final String KEY_DOWN = "key-down"; >+ public static final String KEY_PRESS = "key-press"; >+ public static final String MOUSE_UP = "mouse-up"; >+ public static final String MOUSE_DOWN = "mouse-down"; >+ public static final String MOUSE_MOVE = "mouse-move"; >+ public static final String MOUSE_CLICK = "mouse-click"; >+ public static final String DEFAULT_SELECT = "default-select"; >+ public static final String ITEM_SELECT = "item-select"; >+ >+ /** The bound for the value of descriptive fields */ >+ public static final int DESCRIPTIVE_FIELD_BOUND = 50; >+ > /** > * Returns the type of this command >- * >+ * > * @return The type > */ > public String getType(); >- >- >+ > /** >- * Allows this command to process the corresponding event. >+ * Allows this command to process the corresponding event. > * >- * @param event The event that awaits processing >+ * @param event >+ * The event that awaits processing > */ >- public void processEvent(Event event); >- >- >+ public void processEvent(Event event) throws Exception; >+ > /** >- * If this command occurs consecutively, then this method >- * gives this command a chance to merge mutliple commands >- * together to reduce the overhead. >+ * If this command occurs consecutively, then this method gives this command >+ * a chance to merge mutliple commands together to reduce the overhead. > * >- * @param event The event that caused the creation of a consecutive >- * command of this type. >+ * @param event >+ * The event that caused the creation of a consecutive command of >+ * this type. > * > * @return true if the command is merged; false otherwise. >+ * @throws Exception >+ * TODO > */ >- public boolean mergeEvent(Event e); >- >- >- /** >- * Returns the descriptive field of this command. The descriptive field >- * is a human readable label that allows users to easily identify the >- * purpose of this command. >+ public boolean mergeEvent(Event e) throws Exception; >+ >+ /** >+ * Returns the descriptive field of this command. The descriptive field is a >+ * human readable label that allows users to easily identify the purpose of >+ * this command. > * > * @return The descriptive field > */ > public String getDescriptiveField(); >- >- >+ > /** >- * Sets the descriptive field of this command. The descriptive field >- * is a human readable label that allows users to easily identify the >- * purpose of this command. >+ * Sets the descriptive field of this command. The descriptive field is a >+ * human readable label that allows users to easily identify the purpose of >+ * this command. > * >- * @param descriptiveField The descriptive field >+ * @param descriptiveField >+ * The descriptive field > */ > public void setDescriptiveField(String descriptiveField); >- >- >+ > /** > * Returns the parent of this command. > * > * @return The parent > */ > public MacroCommandShell getParent(); >- >- >+ > /** > * Sets the parent of this command. > * >- * @param parent The parent >+ * @param parent >+ * The parent > */ > public void setParent(MacroCommandShell parent); >- >- >+ > /** >- * Returns false if executing this command just after it has already been executed >- * will have a different output. (e.g. Two focus commands that are identical are >- * redundant but two button selections are not); otherwise true should be returned. >+ * Returns false if executing this command just after it has already been >+ * executed will have a different output. (e.g. Two focus commands that are >+ * identical are redundant but two button selections are not); otherwise >+ * true should be returned. > * > * @return A flag indicating if repeats of this command are redundant. >- */ >+ */ > public boolean isRepeatRedundant(); > > } >- >- >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ModifyCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/ModifyCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 ModifyCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/ModifyCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/ModifyCommand.java 26 Jul 2008 19:22:01 -0000 >@@ -18,56 +18,55 @@ > import org.eclipse.swt.custom.CCombo; > import org.eclipse.swt.custom.StyledText; > 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.Shell; > import org.eclipse.swt.widgets.Text; > import org.eclipse.swt.widgets.Widget; > import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; > import org.w3c.dom.Node; > import org.w3c.dom.NodeList; > >-public class ModifyCommand extends AbstractMacroCommand { >- >- public static final String TYPE = "modify"; >+public class ModifyCommand extends ObjectBasedCommand { >+ >+ public static final String TYPE = IMacroCommand.MODIFY; > public static final String CDATA_OPEN = "<![CDATA["; > public static final String CDATA_CLOSE = "]]>"; > > private String text; >- >- public ModifyCommand(MacroCommandShell parent, WidgetIdentifier wid) { >- super(parent, wid); >+ >+ public ModifyCommand(MacroCommandShell parent) { >+ super(parent); > } > > public String getType() { > return TYPE; > } > >- public boolean mergeEvent(Event e) { >- return doProcessEvent(e); >- } >- >- public void processEvent(Event e) { >- doProcessEvent(e); >+ public boolean mergeEvent(Event e) throws Exception { >+ try { >+ doProcessEvent(e); >+ return true; >+ } catch (Exception exception) { >+ return false; >+ } > } > >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); > > NodeList children = node.getChildNodes(); >- for (int i=0; i<children.getLength(); i++) { >+ for (int i = 0; i < children.getLength(); i++) { > Node child = children.item(i); >- if (child.getNodeType()==Node.TEXT_NODE) { >+ if (child.getNodeType() == Node.TEXT_NODE) { > text = child.getNodeValue().trim(); > break; > } > } >- >+ > /* If in case the text is null, then set it to an empty string */ > if (text == null) > text = ""; >@@ -75,114 +74,105 @@ > text = convertHTMLCodeToChar(text); > } > >- private boolean doProcessEvent(Event e) { >+ protected void doProcessEvent(Event e) throws CoreException { >+ findDescriptiveField(e.widget); > String text = extractText(e.widget); > if (text != null) { > this.text = text; >- return true; > } >- return false; > } > >- private String extractText(Widget widget) >- { >+ private String extractText(Widget widget) { > String widgetText = null; >- if (widget instanceof Text) >+ if (widget instanceof Text) > widgetText = ((Text) widget).getText(); >- >+ > else if (widget instanceof Combo) > widgetText = ((Combo) widget).getText(); >- >+ > else if (widget instanceof CCombo) > widgetText = ((CCombo) widget).getText(); >- >+ > else if (widget instanceof StyledText) > widgetText = ((StyledText) widget).getText(); >- >+ > if (widgetText != null) > return convertSpaces(widgetText); >- >+ > return null; > } > > /** >- * Convert leading and trailing spaces to their respective HTML code. This is so >- * that the user inserted spaces are not lost after a trim operation. >+ * Convert leading and trailing spaces to their respective HTML code. This >+ * is so that the user inserted spaces are not lost after a trim operation. > */ >- public String convertSpaces (String input) >- { >+ public String convertSpaces(String input) { > String convertedString = ""; > char[] inputCharacters = input.toCharArray(); >- >+ > /* Convert leading spaces */ > boolean validCharacterReached = false; > String htmlCode; > int i = 0; >- for (; i < inputCharacters.length && !validCharacterReached; i++) >- { >- htmlCode = convertCharacter (inputCharacters[i]); >+ for (; i < inputCharacters.length && !validCharacterReached; i++) { >+ htmlCode = convertCharacter(inputCharacters[i]); > if (htmlCode == null) > break; > convertedString += htmlCode; > } > convertedString += input.substring(i).trim(); >- >+ > /* Convert trailing spaces */ > String trailingSpaces = ""; >- for (i = inputCharacters.length - 1; i >= 0; i--) >- { >- htmlCode = convertCharacter (inputCharacters[i]); >+ for (i = inputCharacters.length - 1; i >= 0; i--) { >+ htmlCode = convertCharacter(inputCharacters[i]); > if (htmlCode == null) > break; > trailingSpaces = htmlCode + trailingSpaces; > } >- convertedString += trailingSpaces; >+ convertedString += trailingSpaces; > return convertedString; > } >- >- >- public String convertCharacter (char character) >- { >- switch (character) >- { >- case '\t': >- return "	"; >- case '\n': >- return " "; >- case '\r': >- return " "; >- case ' ': >- return " "; >- default: >- return null; >- } >- } >- >- private String convertHTMLCodeToChar(String input) >- { >+ >+ public String convertCharacter(char character) { >+ switch (character) { >+ case '\t': >+ return "	"; >+ case '\n': >+ return " "; >+ case '\r': >+ return " "; >+ case ' ': >+ return " "; >+ default: >+ return null; >+ } >+ } >+ >+ private String convertHTMLCodeToChar(String input) { > String normalizedString = ""; > String inputCloned = input; > int currentHTMLCodeInx; > final int HTML_LENGTH_CODE = 5; >- >- while ((currentHTMLCodeInx = inputCloned.indexOf("&#"))!= -1) >- { >+ >+ while ((currentHTMLCodeInx = inputCloned.indexOf("&#")) != -1) { > int totalHTMLCodeLen = currentHTMLCodeInx + HTML_LENGTH_CODE; > if (totalHTMLCodeLen > inputCloned.length()) > break; >- >- String htmlCode = inputCloned.substring(currentHTMLCodeInx, totalHTMLCodeLen); >+ >+ String htmlCode = inputCloned.substring(currentHTMLCodeInx, >+ totalHTMLCodeLen); > String htmlChar = convertCodeToChar(htmlCode); >- normalizedString += inputCloned.substring(0, currentHTMLCodeInx) + htmlChar; >+ normalizedString += inputCloned.substring(0, currentHTMLCodeInx) >+ + htmlChar; > inputCloned = inputCloned.substring(totalHTMLCodeLen); > } > normalizedString += inputCloned; >- >+ > return normalizedString; > } >- >- private String convertCodeToChar(String htmlCode) >- { >+ >+ private String convertCodeToChar(String htmlCode) { > if (htmlCode.equals("	")) > return "\t"; > else if (htmlCode.equals(" ")) >@@ -195,38 +185,34 @@ > return htmlCode; > } > >- public void write(int indent, StringBuffer sb) >- { >+ public void write(int indent, StringBuffer sb) { > /* Ignore this command if it's corrupted */ >- if (getWidgetId() == null || text == null || text.length() <= 0) >+ if (getMacroObjectIdentifier() == null || text == null >+ || text.length() <= 0) > return; > > super.write(indent, sb, false, true); >- if (text != null) >- { >+ if (text != null) { > MacroUtil.addIndent(sb, indent); > sb.append(CDATA_OPEN); > sb.append(text); > sb.append(CDATA_CLOSE); > sb.append(GlobalConstants.LINE_SEPARATOR); > } >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true); >+ MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, >+ true); > } > >- public boolean playback(Display display, Composite parent, >- IProgressMonitor monitor) throws CoreException >- { >- >- if (parent.isDisposed()) >+ public boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ >+ if (parent.isDisposed()) > return false; >- >- CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine()); >- CommandTarget target = targets[0]; >- if (target != null) >- { >- target.setFocus(); >- Widget widget = target.getWidget(); >- >+ >+ if (macroObject != null) { >+ setFocus(macroObject); >+ Widget widget = macroObject.getUIObject().getWidget(); >+ > if (widget instanceof Text) > ((Text) widget).setText(text); > else if (widget instanceof Combo) >@@ -234,23 +220,26 @@ > else if (widget instanceof CCombo) > ((CCombo) widget).setText(text); > else if (widget instanceof StyledText) >- ((StyledText)widget).setText(text); >- >- /* Ali M.: Some classes explicitly listen for a selection before a modification is made */ >+ ((StyledText) widget).setText(text); >+ >+ /* >+ * Ali M.: Some classes explicitly listen for a selection before a >+ * modification is made >+ */ > Event event = new Event(); > event.display = display; > event.widget = widget; > event.type = SWT.Selection; > widget.notifyListeners(SWT.Selection, event); >- MacroUtil.processDisplayEvents(display); >- >+ MacroUtil.processDisplayEvents(display); >+ > /* Send out a modify command to notify modify listeners */ >- event.type = SWT.Modify; >+ event.type = SWT.Modify; > widget.notifyListeners(SWT.Modify, event); > MacroUtil.processDisplayEvents(display); >- >- } >- >+ >+ } >+ > return true; > } > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/PositionBasedCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/PositionBasedCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 PositionBasedCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/PositionBasedCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/PositionBasedCommand.java 26 Jul 2008 19:22:03 -0000 >@@ -11,46 +11,49 @@ > *******************************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.commands; > >+import java.util.Hashtable; >+ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.w3c.dom.Node; > > /** > * An abstract representation of position-based commands > * > * @author Ali Mehregani >+ * @author Alexander Nyssen (refactoring) > */ >-public abstract class PositionBasedCommand extends AbstractMacroCommand >-{ >+public abstract class PositionBasedCommand extends AbstractMacroCommand { > >- public PositionBasedCommand(MacroCommandShell parent, WidgetIdentifier wi) >- { >- super(parent, wi); >+ protected String type = null; >+ protected Integer detail = null; >+ >+ public PositionBasedCommand(MacroCommandShell parent) { >+ super(parent); > } >+ >+ protected abstract String determineType(Event e); >+ >+ protected abstract Integer determineDetail(Event e); > >- /** >- * The type of the event >- */ >- public abstract String getType(); >+ public void processEvent(Event event) throws Exception { >+ this.type = determineType(event); >+ this.detail = determineDetail(event); >+ } > >- /** >- * A chance for the command to process the original SWT event >- */ >- public abstract void processEvent(Event e); >+ public String getType() { >+ return type; >+ } > >- /** >- * Returns a field that is required to complete the string serialization of the >- * command. >- * >- * @return A detail field (for mouse events it corresponds to the button pressed/released and >- * for key events it corresponds to the key pressed/released >- */ >- public abstract int getDetail(); >+ public Integer getDetail() { >+ return detail; >+ } > > /** > * Constructs the SWT event that will be played back >@@ -58,39 +61,43 @@ > * @return The SWT event > */ > public abstract Event[] constructSWTEvents(); >- >- >+ > /** > * String serialize this event > */ >- public void write(int indent, StringBuffer sb, boolean close, boolean end) >- { >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, >- new String[] { >- MacroConstants.TYPE_ATTRIBUTE, >- MacroConstants.DETAIL_ATTRIBUTE, >- }, >- new String[] { >- getType(), >- String.valueOf(getDetail()), >- } >- , false, false); >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ MacroUtil.addElement(sb, >+ indent, >+ MacroConstants.COMMAND_ELEMENT, >+ false, >+ false); >+ MacroUtil.addAttribute(sb, >+ new String[] {MacroConstants.TYPE_ATTRIBUTE, MacroConstants.DETAIL_ATTRIBUTE}, >+ new String[] {getType(), detail != null ? String.valueOf(detail) : null}, >+ false, >+ false); >+ } >+ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, lineTable); >+ >+ type = MacroUtil.getAttribute(node, "type"); >+ if(MacroUtil.getAttribute(node, "detail") != null){ >+ detail = new Integer(MacroUtil.getAttribute(node, "detail")); >+ } > } > > /** > * Plays back this command > */ >- public boolean playback(final Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- Event[] events = constructSWTEvents (); >+ public boolean playback(final Display display, final Shell parent, IProgressMonitor monitor) throws CoreException { >+ Event[] events = constructSWTEvents(); > boolean success = true; >- >- for (int i = 0; i < events.length; i++) >- { >+ >+ for (int i = 0; i < events.length; i++) { > success = success && display.post(events[i]); > } >- >+ > MacroUtil.processDisplayEvents(display); > return success; > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/FocusCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/FocusCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 FocusCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/FocusCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/FocusCommand.java 26 Jul 2008 19:22:00 -0000 >@@ -12,72 +12,63 @@ > > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > >-public class FocusCommand extends AbstractMacroCommand >-{ >- public static final String TYPE = "focus"; >- >- public FocusCommand(MacroCommandShell parent, WidgetIdentifier wid) >- { >- super(parent, wid); >+public class FocusCommand extends ObjectBasedCommand { >+ >+ public static final String TYPE = IMacroCommand.FOCUS; >+ >+ public FocusCommand(MacroCommandShell parent) { >+ super(parent); > } > > /** > * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event) > */ >- public boolean mergeEvent(Event e) >- { >+ public boolean mergeEvent(Event e) throws Exception { > /* we can directly merge repeated focus requests on the same widget */ > return true; > } > >- >- /** >+ /** > * @see org.eclipse.ui.macro.MacroCommand#getType() > */ >- public String getType() >- { >+ public String getType() { > return TYPE; > } > >- >- /** >+ /** > * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event) > */ >- public void processEvent(Event e) >- { >+ public void doProcessEvent(Event e) { > findDescriptiveField(e.widget); > } > >- >- /** >- * @see org.eclipse.ui.macro.IWritable#write(java.lang.String, java.io.PrintWriter) >+ /** >+ * @see org.eclipse.ui.macro.IPersistable#write(java.lang.String, >+ * java.io.PrintWriter) > */ >- public void write(int indent, StringBuffer sb) >- { >+ public void write(int indent, StringBuffer sb) { > /* Don't bother with the focus command if the id is invalid */ >- if (getWidgetId() == null) >+ if (getMacroObjectIdentifier() == null) > return; > > super.write(indent, sb, true, true); > } > >- > /** > * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite) > */ >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >+ public boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { > if (parent.isDisposed()) > return false; >- CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent,getWidgetId(), getStartLine()); >- if (targets !=null && targets.length > 0) >- targets[0].setFocus(); >+ if (macroObject != null) >+ setFocus(macroObject); > return true; > } >+ > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/BooleanSelectionCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/BooleanSelectionCommand.java,v >retrieving revision 1.2 >diff -u -r1.2 BooleanSelectionCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/BooleanSelectionCommand.java 14 Jul 2006 23:17:02 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/BooleanSelectionCommand.java 26 Jul 2008 19:21:59 -0000 >@@ -23,105 +23,97 @@ > import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.Point; > import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Listener; > import org.eclipse.swt.widgets.Menu; > import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.swt.widgets.ToolItem; > import org.eclipse.swt.widgets.Widget; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject; >-import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport; > import org.w3c.dom.Node; > import org.w3c.dom.NodeList; > >- > /** >- * Represents the select command (e.g. button, check box, radio button, and >+ * Represents the select command (e.g. button, check box, radio button, and > * etc... selections) > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ >-public class BooleanSelectionCommand extends AbstractMacroCommand >-{ >- public static final String TYPE = "select"; >+public class BooleanSelectionCommand extends SingleSelectionCommand { > >- private Boolean selection; >+ public static final String TYPE = IMacroCommand.SELECT; > >- private ArrayList path; >+ private Boolean selection; > >- /* Indicates the cursor location relative to the tool bar item (the value is non-zero >- * if the toolbar item is dropped down */ >+ /* >+ * Indicates the cursor location relative to the tool bar item (the value is >+ * non-zero if the toolbar item is dropped down >+ */ > private Point toolBarLocation; > > /* The detail of the event as described in the SWT class */ > private int detail; >- >- /* If an item is selected from a drop down menu, then this points to the id of the item */ >- private IWidgetId itemSelectedId; > >- /* The refrence id of the selected item that points to an object in an object mine */ >+ /* >+ * If an item is selected from a drop down menu, then this points to the id >+ * of the item >+ */ >+ private IUIObjectIdentifier itemSelectedIdentifier; >+ >+ /* >+ * The refrence id of the selected item that points to an object in an >+ * object mine >+ */ > private String itemSelectedRefId; >- >+ > /* This listener is used to get a reference to a drop-down menu */ > private DropDownMenuListener dropDownMenuListener; >- >+ > /* Reference to a drop-down menu */ > private Menu dropDownMenu; > > /* Indicates whether we're waiting for a drop down menu item */ > private boolean menuIsNeeded; >- >- /** >- * The toolBarLocation argument is needed when the toolbar item is a drop down. >- * >- * @param wid The widget identifier. >- * @param toolBarLocation The cursor location >- * @param detail The detail of the event as described by the SWT class >- */ >- public BooleanSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid, Point toolBarLocation, int detail) >- { >- super(parent, wid); >- this.toolBarLocation = toolBarLocation; >- this.detail = detail; >- } > >- public BooleanSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid) >- { >- super(parent, wid); >- this.detail = -10; >+ public BooleanSelectionCommand(MacroCommandShell parent) { >+ super(parent); > } > >- public String getType() >- { >+ public String getType() { > return TYPE; > } > >- public void processEvent(Event e) >- { >- selection = getSelection(e.widget); >- if (e.widget instanceof MenuItem) >- { >- path = getPath((MenuItem) e.widget); >+ public void doProcessEvent(Event event) { >+ if (event.x != 0 || event.y != 0 || event.detail != 0) { >+ this.toolBarLocation = new Point(event.x, event.y); >+ this.detail = event.detail; >+ } else { >+ this.detail = -10; > } >- >- findDescriptiveField(e.widget); >+ >+ selection = getSelection(event.widget); >+ >+ findDescriptiveField(event.widget); > } > >- private Boolean getSelection(Widget widget) >- { >+ private Boolean getSelection(Widget widget) { > if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0) > return null; > if (widget instanceof Button) >@@ -133,468 +125,473 @@ > return null; > } > >- private ArrayList getPath(MenuItem item) >- { >- ArrayList segments = new ArrayList(); >- Object data = item.getData(); >- >- if (data instanceof ContributionItem) >- { >- ContributionItem aitem = (ContributionItem) data; >- MenuManager manager = (MenuManager) aitem.getParent(); >- while (manager != null) >- { >- String id = manager.getId(); >- if (id == null) >- break; >- segments.add(0, id); >- manager = (MenuManager) manager.getParent(); >- } >- } >- return segments.size() > 0 ? segments : null; >- } >- >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >+ public void load(Node node, Hashtable lineTable) throws CoreException { > super.load(node, lineTable); >- String sel = MacroUtil.getAttribute(node, MacroConstants.SELECTION_ATTRIBUTE); >- String xCoordStr = MacroUtil.getAttribute(node, MacroConstants.X_COORD_ATTRIBUTE); >- String yCoordStr = MacroUtil.getAttribute(node, MacroConstants.Y_COORD_ATTRIBUTE); >- String detailStr = MacroUtil.getAttribute(node, MacroConstants.DETAIL_ATTRIBUTE); >+ String sel = MacroUtil.getAttribute(node, >+ MacroConstants.SELECTION_ATTRIBUTE); >+ String xCoordStr = MacroUtil.getAttribute(node, >+ MacroConstants.X_COORD_ATTRIBUTE); >+ String yCoordStr = MacroUtil.getAttribute(node, >+ MacroConstants.Y_COORD_ATTRIBUTE); >+ String detailStr = MacroUtil.getAttribute(node, >+ MacroConstants.DETAIL_ATTRIBUTE); > > if (xCoordStr != null && yCoordStr != null) >- toolBarLocation = new Point(Integer.parseInt(xCoordStr), Integer.parseInt(yCoordStr)); >+ toolBarLocation = new Point(Integer.parseInt(xCoordStr), Integer >+ .parseInt(yCoordStr)); > if (detailStr != null) >- detail = Integer.parseInt(detailStr); >- >+ detail = Integer.parseInt(detailStr); > >- if (sel != null) >- { >- selection = sel.equals(MacroConstants.TRUE_VALUE) ? Boolean.TRUE : Boolean.FALSE; >+ if (sel != null) { >+ selection = sel.equals(MacroConstants.TRUE_VALUE) ? Boolean.TRUE >+ : Boolean.FALSE; > } > NodeList children = node.getChildNodes(); >- for (int i = 0; i < children.getLength(); i++) >- { >+ for (int i = 0; i < children.getLength(); i++) { > Node child = children.item(i); > if (!(child.getNodeType() == Node.ELEMENT_NODE)) > continue; >- >- if (child.getNodeName().equals(MacroConstants.PARENT_ELEMENT)) >- { >- if (path == null) >- path = new ArrayList(); >- path.add(MacroUtil.getAttribute(child, MacroConstants.WIDGET_ID_ATTRIBUTE)); >- } >- else if (child.getNodeName().equals(MacroConstants.SELECT_ITEM_ELEMENT)) >- { >- String pathOfItem = MacroUtil.getAttribute(child, MacroConstants.PATH_ATTRIBUTE); >- if (pathOfItem == null) >- { >- String refId = MacroUtil.getAttribute(child, MacroConstants.REFERENCE_ID_ATTRIBUTE); >- if (refId == null) >- { >- itemSelectedId = null; >- } >- else >- { >- IUIObject uiObject = MacroManager.getInstance().getObjectMine().lookupUIObject(getCorrespondingObject(), refId); >- if (uiObject != null) >- { >- itemSelectedId = new PrimitiveWidgetId(uiObject.getObjectId().toString()); >- itemSelectedId.setResolverId(uiObject.getResolverId()); >+ >+ if (child.getNodeName().equals(MacroConstants.SELECT_ITEM_ELEMENT)) { >+ String pathOfItem = MacroUtil.getAttribute(child, >+ MacroConstants.WIDGET_ID_ATTRIBUTE); >+ if (pathOfItem == null) { >+ String refId = MacroUtil.getAttribute(child, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ if (refId == null) { >+ itemSelectedIdentifier = null; >+ } else { >+ MacroObjectDescriptor uiObject = MacroManager >+ .getInstance() >+ .getObjectMine() >+ .lookupMacroObjectDescriptor( >+ getCorrespondingMacroObjectDescriptor(), >+ refId); >+ if (uiObject != null) { >+ itemSelectedIdentifier = new PrimitiveUIObjectIdentifier( >+ uiObject.getWidgetId(), uiObject >+ .getResolverId()); > } > } >- >- } >- else >- { >- itemSelectedId = new PrimitiveWidgetId(pathOfItem); >+ >+ } else { >+ itemSelectedIdentifier = new PrimitiveUIObjectIdentifier( >+ pathOfItem); > } >- >+ > dropDownMenuListener = new DropDownMenuListener(); > } > } > } > >- public void write(int indent, StringBuffer sb) >- { >+ public void write(int indent, StringBuffer sb) { > super.write(indent, sb); >- boolean childElementPresent = itemSelectedId != null; >- MacroUtil.addAttribute(sb, >- new String[]{MacroConstants.X_COORD_ATTRIBUTE, >- MacroConstants.Y_COORD_ATTRIBUTE, >- MacroConstants.DETAIL_ATTRIBUTE, >- MacroConstants.SELECTION_ATTRIBUTE >- }, >- >- new String[]{toolBarLocation == null ? null : String.valueOf(toolBarLocation.x), >- toolBarLocation == null ? null : String.valueOf(toolBarLocation.y), >- detail == -10 ? null : String.valueOf(detail), >- selection == null ? null : selection.equals(Boolean.TRUE) ? MacroConstants.TRUE_VALUE : MacroConstants.FALSE_VALUE >- }, >- !childElementPresent, true); >- >- >+ boolean childElementPresent = itemSelectedIdentifier != null; >+ MacroUtil >+ .addAttribute( >+ sb, >+ new String[] { MacroConstants.X_COORD_ATTRIBUTE, >+ MacroConstants.Y_COORD_ATTRIBUTE, >+ MacroConstants.DETAIL_ATTRIBUTE, >+ MacroConstants.SELECTION_ATTRIBUTE }, >+ >+ new String[] { >+ toolBarLocation == null ? null : String >+ .valueOf(toolBarLocation.x), >+ toolBarLocation == null ? null : String >+ .valueOf(toolBarLocation.y), >+ detail == -10 ? null : String.valueOf(detail), >+ selection == null ? null >+ : selection.equals(Boolean.TRUE) ? MacroConstants.TRUE_VALUE >+ : MacroConstants.FALSE_VALUE }, >+ !childElementPresent, true); >+ > int pindent = childElementPresent ? indent + 1 : 0; >- >- if (itemSelectedId != null) >- { >- boolean useObjectMine = MacroManager.getInstance().isObjectMineOn() && itemSelectedRefId != null; >- MacroUtil.addElement(sb, pindent, MacroConstants.SELECT_ITEM_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, new String[] >- { >- useObjectMine ? MacroConstants.REFERENCE_ID_ATTRIBUTE : MacroConstants.PATH_ATTRIBUTE >- }, >- new String[] >- { >- useObjectMine ? itemSelectedRefId : itemSelectedId.toString() >- }, true, true); >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true); >+ >+ if (itemSelectedIdentifier != null) { >+ boolean useObjectMine = useObjectMine() >+ && itemSelectedRefId != null; >+ MacroUtil.addElement(sb, pindent, >+ MacroConstants.SELECT_ITEM_ELEMENT, false, false); >+ MacroUtil >+ .addAttribute( >+ sb, >+ new String[] { useObjectMine ? MacroConstants.REFERENCE_ID_ATTRIBUTE >+ : MacroConstants.WIDGET_ID_ATTRIBUTE }, >+ new String[] { useObjectMine ? itemSelectedRefId >+ : itemSelectedIdentifier.getWidgetId() }, >+ true, true); >+ MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, >+ true, true); > } > } > >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >- CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), path, getStartLine()); >- if (targets == null) >+ public boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ >+ if (macroObject == null) > return false; >- >- boolean executeForFirstMatch = false; >- for (int i = 0; i < targets.length && !executeForFirstMatch; i++) >- { >- targets[i].setFocus(); >- Widget widget = targets[i].getWidget(); >- >- executeForFirstMatch = widget instanceof Button; >- Display currentDisplay = GuiPlugin.getDefault().getWorkbench().getDisplay(); >- ActionContributionItem contributionItem = null; >- if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0) >+ >+ // boolean executeForFirstMatch = false; >+ // for (int i = 0; i < targets.length && !executeForFirstMatch; i++) { >+ setFocus(macroObject); >+ Widget widget = macroObject.getUIObject().getWidget(); >+ >+ // executeForFirstMatch = widget instanceof Button; >+ Display currentDisplay = GuiPlugin.getDefault().getWorkbench() >+ .getDisplay(); >+ ActionContributionItem contributionItem = null; >+ if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0) { >+ /* >+ * If in case we're dealing with a toolbar item that is a drop-down, >+ * then register appropriate listeners that will be used for getting >+ * a reference to the menu. We only need to do this if a menu >+ * creator is not provided >+ */ >+ if (widget instanceof ToolItem && /* Are we a tool item? */ >+ (widget.getStyle() & SWT.DROP_DOWN) != 0 && /* Are we a drop down? */ >+ itemSelectedIdentifier != null && /* >+ * Do we have a selected item >+ * from our menu (i.e. is the >+ * menu even needed)? >+ */ >+ widget.getData() instanceof ActionContributionItem)/* >+ * Are we >+ * dealing with >+ * a >+ * contribution >+ * item? >+ */ > { >- /* If in case we're dealing with a toolbar item that is a drop-down, then register >- * appropriate listeners that will be used for getting a reference to the menu. We only need >- * to do this if a menu creator is not provided */ >- if ( widget instanceof ToolItem && /* Are we a tool item? */ >- (widget.getStyle() & SWT.DROP_DOWN) != 0 && /* Are we a drop down? */ >- itemSelectedId != null && /* Do we have a selected item from our menu (i.e. is the menu even needed)? */ >- widget.getData() instanceof ActionContributionItem)/* Are we dealing with a contribution item? */ >- { >- >- contributionItem = (ActionContributionItem)widget.getData(); >- >- /* We don't have a menu creator. Register the listeners */ >- if (contributionItem.getAction().getMenuCreator() == null) >- { >- currentDisplay.addFilter(SWT.Show, dropDownMenuListener); >- >- } >+ >+ contributionItem = (ActionContributionItem) widget.getData(); >+ >+ /* We don't have a menu creator. Register the listeners */ >+ if (contributionItem.getAction().getMenuCreator() == null) { >+ currentDisplay.addFilter(SWT.Show, dropDownMenuListener); >+ > } >- >- if (itemSelectedId == null || >- (itemSelectedId != null && contributionItem != null && contributionItem.getAction().getMenuCreator() == null)) >- doClick(display, widget, false); > } >- > >- else if (selection != null) >- { >- doSelect(display, widget); >+ if (itemSelectedIdentifier == null >+ || (itemSelectedIdentifier != null >+ && contributionItem != null && contributionItem >+ .getAction().getMenuCreator() == null)) >+ doClick(display, widget, false); >+ } >+ >+ else if (selection != null) { >+ doSelect(display, widget); >+ } >+ >+ /* Select the item from the drop-down menu, if there is one set */ >+ if (itemSelectedIdentifier != null) { >+ if (contributionItem == null) { >+ currentDisplay.removeFilter(SWT.Show, dropDownMenuListener); >+ return false; // continue; /* we weren't able to select the >+ // item */ > } >- >- /* Select the item from the drop-down menu, if there is one set */ >- if (itemSelectedId != null) >- { >- if (contributionItem == null) >- { >- currentDisplay.removeFilter(SWT.Show, dropDownMenuListener); >- continue; /* we weren't able to select the item */ >- } >- >- Menu menu = null; >- IMenuCreator menuCreator = contributionItem.getAction().getMenuCreator(); >- >- /* Attempt to create the menu */ >- if (menuCreator != null) >- menu = menuCreator.getMenu(parent); >- /* Otherwise we wait until the menu is handed out to us */ >- else >- { >- try >- { >- menuIsNeeded = true; >- /* Wait a maximum of INCREMENTS * COUNT in increments of INCREMENT */ >- final int INCREMENT = 200; >- final int COUNT = 15; >- synchronized (this) >- { >- int count = 0; >- while (dropDownMenu == null && count < COUNT) >- { >- wait (INCREMENT); >- count++; >- } >+ >+ Menu menu = null; >+ IMenuCreator menuCreator = contributionItem.getAction() >+ .getMenuCreator(); >+ >+ /* Attempt to create the menu */ >+ if (menuCreator != null) >+ menu = menuCreator.getMenu(parent); >+ /* Otherwise we wait until the menu is handed out to us */ >+ else { >+ try { >+ menuIsNeeded = true; >+ /* >+ * Wait a maximum of INCREMENTS * COUNT in increments of >+ * INCREMENT >+ */ >+ final int INCREMENT = 200; >+ final int COUNT = 15; >+ synchronized (this) { >+ int count = 0; >+ while (dropDownMenu == null && count < COUNT) { >+ wait(INCREMENT); >+ count++; > } >- } >- catch (InterruptedException e) >- { >- /* doesn't need to be handled */ > } >- if (dropDownMenu != null) >- menu = dropDownMenu; >+ } catch (InterruptedException e) { >+ /* doesn't need to be handled */ > } >- /* Bail out if we couldn't get the menu */ >- if (menu == null) >- { >- currentDisplay.removeFilter(SWT.Show, dropDownMenuListener); >- continue; /* we weren't able to select the item */ >- } >- >- /* Unregister the listener */ >+ if (dropDownMenu != null) >+ menu = dropDownMenu; >+ } >+ /* Bail out if we couldn't get the menu */ >+ if (menu == null) { > currentDisplay.removeFilter(SWT.Show, dropDownMenuListener); >- >- /* Find the menu item corresponding to the drop down menu */ >- MenuItem[] menuItems = menu.getItems(); >- MenuItem foundItem = null; >- for (int j = 0; j < menuItems.length; j++) >- { >- if (foundMenuItem(menuItems[j])) >- { >- foundItem = menuItems[j]; >- break; >- } >+ return false; // continue; /* we weren't able to select the >+ // item */ >+ } >+ >+ /* Unregister the listener */ >+ currentDisplay.removeFilter(SWT.Show, dropDownMenuListener); >+ >+ /* Find the menu item corresponding to the drop down menu */ >+ MenuItem[] menuItems = menu.getItems(); >+ MenuItem foundItem = null; >+ for (int j = 0; j < menuItems.length; j++) { >+ if (foundMenuItem(menuItems[j])) { >+ foundItem = menuItems[j]; >+ break; > } >- >- if (foundItem == null) >- continue; >- >- doClick(display, foundItem, true); >- >- } >+ } >+ >+ if (foundItem == null) >+ return false;// /continue; >+ >+ doClick(display, foundItem, true); >+ > } >- >+ >+ // } >+ > return true; > } >- >- private boolean foundMenuItem (MenuItem menuItem) >- { >+ >+ private boolean foundMenuItem(MenuItem menuItem) { > /* Try the widget resolvers first */ >- if (MacroObjectLocator.foundItem(menuItem, itemSelectedId.getResolverId(), itemSelectedId.toString())) >+ if (UIObjectDeprecatedDeresolvingSupport.foundItem(menuItem, >+ itemSelectedIdentifier)) > return true; >- >+ > /* Give the old policy a try */ > Object menuItemIdObj = getDropDownItemTraditionalId(menuItem); >- if (menuItemIdObj.equals(itemSelectedId.toString())) >+ if (menuItemIdObj.equals(itemSelectedIdentifier.getWidgetId())) > return true; >- >+ > return false; > } > >- >- private Object getDropDownItemTraditionalId (MenuItem menuItem) >- { >+ private Object getDropDownItemTraditionalId(MenuItem menuItem) { > Object data = menuItem.getData(); >- if (data instanceof ActionContributionItem) >- { >- return ((ActionContributionItem)data).getAction().getClass().getName(); >- } >- else if (data!=null) >+ if (data instanceof ActionContributionItem) { >+ return ((ActionContributionItem) data).getAction().getClass() >+ .getName(); >+ } else if (data != null) > return data.getClass().getName(); >- >- /* As a last resort, index the menu item */ >- return findMenuItemInx (menuItem, ""); >- } >- >- private String findMenuItemInx(MenuItem menuItem, String index) >- { >+ >+ /* As a last resort, index the menu item */ >+ return findMenuItemInx(menuItem, ""); >+ } >+ >+ private String findMenuItemInx(MenuItem menuItem, String index) { > if (index != null && index.length() > 0) > index = index + "|"; >- >+ > Menu parentMenu = menuItem.getMenu(); >- >+ > if (parentMenu == null) > parentMenu = menuItem.getParent(); >- >- if (parentMenu != null) >- { >+ >+ if (parentMenu != null) { > int currentInx = parentMenu.indexOf(menuItem); > MenuItem parentItem = parentMenu.getParentItem(); >- >+ > index = index + currentInx; > if (parentItem != null) > return index + findMenuItemInx(parentItem, index); > } >- >+ > return index; > } >- >- private void doClick(Display display, Widget widget, boolean isItemSelected) throws CoreException >- { >+ >+ private void doClick(Display display, Widget widget, boolean isItemSelected) >+ throws CoreException { >+ > checkEnableStatus(widget); > Event e = new Event(); > e.type = SWT.Selection; > e.widget = widget; > e.display = display; >- >+ > boolean positionSet = false; >- boolean detailSet = false; >- if (!isItemSelected) >- { >- if (toolBarLocation != null) >- { >+ boolean detailSet = false; >+ if (!isItemSelected) { >+ if (toolBarLocation != null) { > e.x = toolBarLocation.x; > e.y = toolBarLocation.y; > positionSet = true; > } >- >- if (detail != -10) >- { >+ >+ if (detail != -10) { > e.detail = detail; > detailSet = true; >- } >+ } > } >- >+ > boolean isWidgetNotified = false; >- >+ > /* We need to do an immediate notify if we're a drop down menu */ >- if ((positionSet && detailSet) || menuIsNeeded) >- { >+ if ((positionSet && detailSet) || menuIsNeeded) { > isWidgetNotified = true; > widget.notifyListeners(e.type, e); > } >- > >- /* If we're dealing with a drop down menu, then we have to send out this >- * mouse down event. Otherwise the readAndDispatch will wait indefinitely. >- * This is safe because we're only sending a mouse down event without a successive >- * mouse up event. */ >- if (positionSet && detailSet) >- { >+ /* >+ * If we're dealing with a drop down menu, then we have to send out this >+ * mouse down event. Otherwise the readAndDispatch will wait >+ * indefinitely. This is safe because we're only sending a mouse down >+ * event without a successive mouse up event. >+ */ >+ if (positionSet && detailSet) { > /* Move the cursor to a safe position */ > Event mouseMoveEvent = new Event(); > mouseMoveEvent.type = SWT.MouseMove; > mouseMoveEvent.x = 10; > mouseMoveEvent.y = widget.getDisplay().getClientArea().height / 2; > widget.getDisplay().post(mouseMoveEvent); >- >+ > Event mouseDownEvent = new Event(); > mouseDownEvent.type = SWT.MouseDown; > mouseDownEvent.button = 1; >- widget.getDisplay().post(mouseDownEvent); >+ widget.getDisplay().post(mouseDownEvent); > } > >- > /* Run the events */ > MacroUtil.processDisplayEvents(display); >- >- /* Now notify the listeners of the widget if they haven't already been notified */ >- if (!isWidgetNotified) >+ >+ /* >+ * Now notify the listeners of the widget if they haven't already been >+ * notified >+ */ >+ if (!isWidgetNotified) { > widget.notifyListeners(e.type, e); >- >+ } > } > >- private void doSelect(Display display, Widget widget) throws CoreException >- { >+ private void doSelect(Display display, Widget widget) throws CoreException { > checkEnableStatus(widget); > boolean shouldClick = false; >- if (widget instanceof Button) >- { >+ if (widget instanceof Button) { > ((Button) widget).setSelection(selection.booleanValue()); > shouldClick = true; >- } >- else if (widget instanceof ToolItem) >- { >+ } else if (widget instanceof ToolItem) { > ((ToolItem) widget).setSelection(selection.booleanValue()); >- shouldClick = true; >- } >- else if (widget instanceof MenuItem) >- { >+ shouldClick = true; >+ } else if (widget instanceof MenuItem) { > ((MenuItem) widget).setSelection(selection.booleanValue()); > shouldClick = true; > } >- >+ > /* Ali M.: We need to also send out a selection event */ > if (shouldClick) >- doClick(display, widget, selection.booleanValue()); >+ doClick(display, widget, selection.booleanValue()); > } > >- > /** >- * Checks the enable status of the widget. If in case the widget happens to be >- * disabled, then throw a core exception. >+ * Checks the enable status of the widget. If in case the widget happens to >+ * be disabled, then throw a core exception. > * >- * @param widget The widget whose status is being checked. >- * @throws CoreException If widget is disabled >+ * @param widget >+ * The widget whose status is being checked. >+ * @throws CoreException >+ * If widget is disabled > */ >- public void checkEnableStatus(Widget widget) throws CoreException >- { >+ public void checkEnableStatus(Widget widget) throws CoreException { > Button button = null; >- if (widget instanceof Button && !(button = ((Button)widget)).isEnabled()) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_DISABLE, button.getText()), getStartLine()); >+ if (widget instanceof Button >+ && !(button = ((Button) widget)).isEnabled()) >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_DISABLE, button >+ .getText()), getStartLine()); > } >- >- >- public int getDetail() >- { >+ >+ public int getDetail() { > return detail; > } > >- public void setItemSelected(Event event) >- { >+ public void setItemSelected(Event event) { > if (!(event.widget instanceof MenuItem)) > return; >- >- itemSelectedId = MacroUtil.determineItemId((MenuItem)event.widget); >- >+ >+ // ANy: The formerly called determineItemId has moved into the >+ // NonTrivialUIObjectResolverDelegate, which is the only contributor to >+ // resolve/deresolve items, >+ // so defect# 112668 is still handled properly here >+ try { >+ itemSelectedIdentifier = UIObjectResolver.resolve(new MacroObject( >+ new UIObject(event.widget)).getContext(), new UIObject( >+ (MenuItem) event.widget)); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ } >+ > /* Register the selected item with the object mine */ > MacroManager macroManager = MacroManager.getInstance(); >- if (macroManager.isObjectMineOn()) >- { >- IObjectMine objectMine = macroManager.getObjectMine(); >- IUIObject parent = objectMine.lookupUIObject(objectMine.getActiveObject(), getWidgetId().getReferenceId()); >- IUIObject uiObject = objectMine.lookupUIObject(parent, null, itemSelectedId.toString()); >- if (uiObject == null) >- { >- uiObject = new UIObject(parent); >- uiObject.setObjectId(itemSelectedId.toString()); >- uiObject.setReferenceId(objectMine.getUniqueReferenceId()); >- uiObject.setResolver(itemSelectedId.getResolverId()); >- uiObject.setDescriptive(getObjectClassName (event.widget)); >- try >- { >- uiObject = objectMine.registerObject(uiObject); >- } >- catch (Exception e) >- { >+ if (macroManager.isObjectMineOn()) { >+ MacroObjectDescriptorMine objectMine = macroManager.getObjectMine(); >+ >+ MacroObjectDescriptor parent = objectMine >+ .lookupMacroObjectDescriptor(objectMine.getActiveObject(), >+ getCorrespondingMacroObjectDescriptor() >+ .getReferenceId()); >+ MacroObjectDescriptor macroObjectDescriptor = objectMine >+ .lookupMacroObjectDescriptor(parent, null, >+ itemSelectedIdentifier.getWidgetId(), itemSelectedIdentifier.getObjectId()); >+ >+ if (macroObjectDescriptor == null) { >+ macroObjectDescriptor = new MacroObjectDescriptor(parent); >+ ((MacroObjectDescriptor) macroObjectDescriptor) >+ .setWidgetId(itemSelectedIdentifier.getWidgetId()); >+ ((MacroObjectDescriptor) macroObjectDescriptor) >+ .setObjectId(itemSelectedIdentifier.getObjectId()); >+ ((MacroObjectDescriptor) macroObjectDescriptor) >+ .setResolver(itemSelectedIdentifier.getResolverId()); >+ ((MacroObjectDescriptor) macroObjectDescriptor) >+ .setDescriptive(getObjectClassName(event.widget)); >+ try { >+ macroObjectDescriptor = objectMine >+ .registerObject((MacroObjectDescriptor) macroObjectDescriptor); >+ } catch (Exception e) { > itemSelectedRefId = null; >- } >+ } > } >- >- if (uiObject != null) >- { >- itemSelectedRefId = uiObject.getReferenceId(); >+ >+ if (macroObjectDescriptor != null) { >+ itemSelectedRefId = macroObjectDescriptor.getReferenceId(); > } > } > } > >- public boolean isRepeatRedundant() >- { >+ public boolean isRepeatRedundant() { > return false; > } >- >- >- public class DropDownMenuListener implements Listener >- { >- >- public void handleEvent(Event event) >- { >- if (event.widget instanceof Menu) >- { >- dropDownMenu = (Menu)event.widget; >- synchronized (BooleanSelectionCommand.this) >- { >- BooleanSelectionCommand.this.notify(); >- } >+ >+ public class DropDownMenuListener implements Listener { >+ >+ public void handleEvent(Event event) { >+ if (event.widget instanceof Menu) { >+ dropDownMenu = (Menu) event.widget; >+ synchronized (BooleanSelectionCommand.this) { >+ BooleanSelectionCommand.this.notify(); >+ } > } > } >- >+ > } >+ >+ private static ArrayList getPath(MenuItem item) { >+ ArrayList segments = new ArrayList(); >+ Object data = item.getData(); >+ >+ if (data instanceof ContributionItem) { >+ ContributionItem aitem = (ContributionItem) data; >+ MenuManager manager = (MenuManager) aitem.getParent(); >+ while (manager != null) { >+ String id = manager.getId(); >+ if (id == null) >+ break; >+ segments.add(0, id); >+ manager = (MenuManager) manager.getParent(); >+ } >+ } >+ return segments.size() > 0 ? segments : null; >+ } >+ > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/StructuredSelectionCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/StructuredSelectionCommand.java,v >retrieving revision 1.3 >diff -u -r1.3 StructuredSelectionCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/StructuredSelectionCommand.java 18 Apr 2008 14:25:04 -0000 1.3 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/StructuredSelectionCommand.java 26 Jul 2008 19:22:03 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2008 IBM Corporation and others. >+ * Copyright (c) 2000, 2006 IBM Corporation and others. > * 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 >@@ -10,7 +10,6 @@ > *******************************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.commands; > >- > import java.util.ArrayList; > import java.util.Iterator; > import java.util.Map; >@@ -23,141 +22,108 @@ > import org.eclipse.swt.widgets.Tree; > import org.eclipse.swt.widgets.TreeItem; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+ >+public class StructuredSelectionCommand extends AbstractStructuredCommand { > >-public class StructuredSelectionCommand extends AbstractStructuredCommand >-{ > private String type; >- public static final String DEFAULT_SELECT="default-select"; >- public static final String ITEM_SELECT="item-select"; > >- public StructuredSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid, String type) { >- super(parent, wid); >+ public StructuredSelectionCommand(MacroCommandShell parent, String type) { >+ super(parent); > items = new ArrayList(); > this.type = type; > } > >- public boolean mergeEvent(Event e) >- { >+ public boolean mergeEvent(Event e) throws Exception { > if (e.detail == SWT.CHECK) > return false; >- >- if (e.type==SWT.DefaultSelection) >- { >+ >+ if (e.type == SWT.DefaultSelection) { > this.type = DEFAULT_SELECT; > } >- >- // If the selected item number is 1, and the old and new item are the same, then merge. >- // Otherwise, do not merge, so that different command of selecting different items >- // can be generated. >- Object[] eventItems = getItemsForEvent(e); >- if (eventItems.length == 1) >- { >- ArrayList newItems = new ArrayList(); >- Map attributeValuePairs = null; >- >- if (eventItems[0] instanceof Widget) >- attributeValuePairs = getItemAttributes((Widget)eventItems[0]); >- else >- attributeValuePairs = getItemAttributes(null, new PrimitiveWidgetId((String)eventItems[0])); >- >- if (attributeValuePairs != null) >- newItems.add(attributeValuePairs); >- >- if (!isSameList(items, newItems)) >- return false; >- } >- > return super.mergeEvent(e); > } >- >+ > public String getType() { > return type; > } > >- protected Object[] getItemsForEvent(Event event) >- { >- if (event.widget instanceof Tree) >- { >- return ((Tree)event.widget).getSelection(); >+ public Object[] getItemsForEvent(Event event) { >+ if (event.widget instanceof Tree) { >+ return ((Tree) event.widget).getSelection(); > } >- else if (event.widget instanceof Table) >- { >- return ((Table)event.widget).getSelection(); >+ else if (event.widget instanceof Table) { >+ return ((Table) event.widget).getSelection(); > } >- else if (event.widget instanceof List) >- { >- return ((List)event.widget).getSelection(); >+ else if (event.widget instanceof List) { >+ return ((List) event.widget).getSelection(); > } > return super.getItemsForEvent(event); > } > >- protected void playStructuredCommand(Widget widget, Object[] matches) >- { >- >+ protected void playStructuredCommand(Widget widget, Object[] matches) { >+ > if (widget instanceof Tree) >- ((Tree)widget).setSelection((TreeItem[])matches); >+ ((Tree) widget).setSelection((TreeItem[]) matches); > else if (widget instanceof Table) >- ((Table)widget).setSelection((TableItem[])matches); >+ ((Table) widget).setSelection((TableItem[]) matches); > else if (widget instanceof List) >- ((List)widget).setSelection((String[])matches); >- >- fireEvent(widget, matches); >+ ((List) widget).setSelection((String[]) matches); >+ >+ fireEvent(widget, >+ matches); > } >- >- private void fireEvent(Widget widget, Object[] items) >- { >+ >+ private void fireEvent(Widget widget, Object[] items) { > Event e = new Event(); > e.widget = widget; >- e.type = type.equals(ITEM_SELECT)?SWT.Selection:SWT.DefaultSelection; >- e.item = (items.length>0 && items instanceof Widget[] ? (Widget)items[0] : null); >- widget.notifyListeners(e.type, e); >+ e.type = type.equals(ITEM_SELECT) >+ ? SWT.Selection >+ : SWT.DefaultSelection; >+ e.item = (items.length > 0 && items instanceof Widget[] >+ ? (Widget) items[0] >+ : null); >+ widget.notifyListeners(e.type, >+ e); > } >- >+ > /** >- * Overwrite this method in order to indicate that two item selection commands that have >- * different items are not the same >+ * Overwrite this method in order to indicate that two item selection commands that have different items are not the same > */ >- public boolean equals (Object obj) >- { >+ public boolean equals(Object obj) { > if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj)) > return false; >- >- StructuredSelectionCommand compareWithObj = (StructuredSelectionCommand)obj; >- if (compareWithObj.items.size() == this.items.size() && isSameList(compareWithObj.items, this.items)) >+ >+ StructuredSelectionCommand compareWithObj = (StructuredSelectionCommand) obj; >+ if (compareWithObj.items.size() == this.items.size() && isSameList(compareWithObj.items, >+ this.items)) > return true; >- >+ > return false; > } > >- private boolean isSameList(ArrayList listA, ArrayList listB) >- { >+ private boolean isSameList(ArrayList listA, ArrayList listB) { > if (listA.size() != listB.size()) > return false; >- >- for (int i = 0, listSize = listA.size(); i < listSize; i++) >- { >- Map itemDataA = (Map)listA.get(i); >- Map itemDataB = (Map)listB.get(i); >- >- >+ >+ for (int i = 0, listSize = listA.size(); i < listSize; i++) { >+ Map itemDataA = (Map) listA.get(i); >+ Map itemDataB = (Map) listB.get(i); >+ > if (itemDataA.size() != itemDataB.size()) > return false; >- >- for(Iterator keys = itemDataA.keySet().iterator(); keys.hasNext();) >- { >+ >+ for (Iterator keys = itemDataA.keySet().iterator(); keys.hasNext();) { > Object currentKey = keys.next(); > if (!itemDataA.get(currentKey).equals(itemDataB.get(currentKey))) > return false; > } > } >- >+ > return true; > } > >- protected void playStructuredCommandForFoundMatch(Widget widget, Object match) >- { >+ protected void playStructuredCommandForFoundMatch(Widget widget, Object match) { > /* Doesn't need to be implemented */ > } > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractMacroCommand.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractMacroCommand.java,v >retrieving revision 1.1 >diff -u -r1.1 AbstractMacroCommand.java >--- src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractMacroCommand.java 10 Jul 2006 14:49:05 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractMacroCommand.java 26 Jul 2008 19:21:56 -0000 >@@ -14,169 +14,140 @@ > import java.util.Hashtable; > > import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.Path; > import org.eclipse.hyades.test.common.util.XMLUtil; >+import org.eclipse.jface.window.Window; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; > import org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IViewPart; >+import org.eclipse.ui.IWorkbenchPage; > import org.w3c.dom.Node; > > /** >- * An abstract implementation of {@link IMacroCommand}. Contributors can subclass this >- * class or provide a direct implementation of {@link IMacroCommand}. >+ * An abstract implementation of {@link IMacroCommand}. Contributors can subclass this class or provide a direct implementation of >+ * {@link IMacroCommand}. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ >-public abstract class AbstractMacroCommand extends AbstractMacroInstruction implements IMacroCommand >-{ >- /** The bound for the value of descriptive fields */ >- protected static final int DESCRIPTIVE_FIELD_BOUND = 50; >- >+public abstract class AbstractMacroCommand extends AbstractMacroInstruction implements IMacroCommand { >+ > /** The parent command shell */ > private MacroCommandShell parent; >- >+ > /** The descriptive field of this command */ >- private String descriptiveField; >+ private String descriptiveField; > > /** Time difference between this command and the previous command (applicable when artificial wait time is enabled) */ >- private long timeDifference; >- >- >+ private long timeDifference; >+ > /** > * Constructor > * >- * @param parent The parent command shell >- * @param widgetId The associated widget id >+ * @param parent >+ * The parent command shell >+ * @param widgetId >+ * The associated widget id > */ >- public AbstractMacroCommand(MacroCommandShell parent, WidgetIdentifier widgetId) >- { >- setWidgetId(widgetId); >+ public AbstractMacroCommand(MacroCommandShell parent) { > this.parent = parent; > } >- >- >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >- super.load(node, lineTable); >- String cid = MacroUtil.getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE); >- String wid = MacroUtil.getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE); >- String rid = MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE); >- >- if (cid != null && wid != null) >- { >- setWidgetId(new WidgetIdentifier( >- cid == null ? new Path(MacroConstants.EMPTY_STRING) : new Path(cid), >- wid == null ? new Path(MacroConstants.EMPTY_STRING) : new Path(wid), >- rid)); >- } >- } >- >- >- public boolean mergeEvent(Event e) >- { >+ >+ public boolean mergeEvent(Event e) throws Exception { > return false; > } >+ > >- >+ > /** > * Returns the descriptive field of this command. > * > * @return The descriptive field of this command. > */ >- public String getDescriptiveField() >- { >+ public String getDescriptiveField() { > return descriptiveField; > } >- >- >+ > /** >- * Set the descriptive field of this command. The descriptive field is used >- * to more easily identify the semantics of a command. >- * >- * @param descriptiveField The descriptive field (can be a button's text, a tree >- * item label, or etc...) >- */ >- public void setDescriptiveField(String descriptiveField) >- { >- this.descriptiveField = XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField, DESCRIPTIVE_FIELD_BOUND))); >+ * Set the descriptive field of this command. The descriptive field is used to more easily identify the semantics of a command. >+ * >+ * @param descriptiveField >+ * The descriptive field (can be a button's text, a tree item label, or etc...) >+ */ >+ public void setDescriptiveField(String descriptiveField) { >+ this.descriptiveField = XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField, >+ DESCRIPTIVE_FIELD_BOUND))); > } > >- > /** >- * Initializes the descriptive field of this command based on the >- * value returned by the getText() method of the widget (if it has one) >+ * Initializes the descriptive field of this command based on the value returned by the getText() method of the widget (if it has one) > * >- * @param widget The widget >+ * @param widget >+ * The widget > */ >- protected void findDescriptiveField(Widget widget) >- { >- setDescriptiveField(getText(widget)); >+ protected void findDescriptiveField(Widget widget) { >+ setDescriptiveField(getText(widget)); > } >- >- >+ > /** >- * Similar to initializeDescriptiveField(Widget), but the descriptive field >- * is a comma-separated string of all the descriptive fields that corresponds >- * to the objects passed in. >+ * Similar to initializeDescriptiveField(Widget), but the descriptive field is a comma-separated string of all the descriptive fields that >+ * corresponds to the objects passed in. > * >- * @param objects The objects >+ * @param objects >+ * The objects > */ >- protected void findDescriptiveField(Object[] objects) >- { >+ protected void findDescriptiveField(Object[] objects) { > String descriptive = ""; >- for (int i = 0; i < objects.length; i++) >- { >+ for (int i = 0; i < objects.length; i++) { > if (descriptive.length() > 0) > descriptive += ", "; > String textValue = getText(objects[i]); > if (textValue != null && textValue.length() > 0) >- descriptive += textValue; >+ descriptive += textValue; > } >- >+ > if (descriptive.length() > 0) > setDescriptiveField(descriptive); > } >- >- >- protected String getText(Object obj) >- { >+ >+ protected String getText(Object obj) { > if (obj == null) > return null; >- >- try >- { >- Method getText = obj.getClass().getMethod("getText", null); >- String textValue = (String)getText.invoke(obj, null); >+ >+ try { >+ Method getText = obj.getClass().getMethod("getText", >+ null); >+ String textValue = (String) getText.invoke(obj, >+ null); > if (textValue != null && textValue.length() > 0) >- return textValue; >- } >- catch (Exception e) >- { >+ return textValue; >+ } >+ catch (Exception e) { > /* Doesn't need to be handled */ > } >- >+ > return null; > } > >- >- public String toString() >- { >+ public String toString() { > return "MacroCommand [" + getType() + ", line " + getStartLine() + "]"; > } >- >- public boolean equals (Object obj) >- { >+ >+ public boolean equals(Object obj) { > if (!(obj instanceof IMacroCommand)) > return false; >- >- IMacroCommand compareWithObj = (IMacroCommand)obj; >- if (compareWithObj.getType() == this.getType() && compareWithObj.getWidgetId() != null && compareWithObj.getWidgetId().equals(getWidgetId())) >+ >+ IMacroCommand compareWithObj = (IMacroCommand) obj; >+ if (compareWithObj.getType() == this.getType()) > return true; >- >+ > return false; > } > >@@ -187,105 +158,141 @@ > public void setParent(MacroCommandShell parent) { > this.parent = parent; > } >- >+ > /** >- * Should return false if executing this command just after it >- * has already been executed will have a different output. >- * (e.g. If two focus commands that are identical are redundant but >- * two button selections are not) >- */ >- public boolean isRepeatRedundant() >- { >+ * Should return false if executing this command just after it has already been executed will have a different output. (e.g. If two focus commands >+ * that are identical are redundant but two button selections are not) >+ */ >+ public boolean isRepeatRedundant() { > return true; > } >- >+ > /** >- * This is our chance to write any artificial wait commands if the >- * option is enabled. >+ * This is our chance to write any artificial wait commands if the option is enabled. > * >- * @param indent The current indent that the command should be at >- * @param writer The writer used to write the macro >+ * @param indent >+ * The current indent that the command should be at >+ * @param writer >+ * The writer used to write the macro > */ >- public void writeStart(int indent, StringBuffer writer) >- { >+ public void writeStart(int indent, StringBuffer writer) { > if (timeDifference <= 0) > return; >- >+ > WaitCommand waitCommand = new WaitCommand(parent); >- waitCommand.setWaitTime(timeDifference); >- waitCommand.write(indent, writer); >+ waitCommand.setWaitTime(timeDifference); >+ waitCommand.write(indent, >+ writer); > } >- > > /** >+ * {@inheritDoc} >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable) >+ */ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, >+ lineTable); >+ // load the descriptive field >+ descriptiveField = MacroUtil.getAttribute(node, MacroConstants.DESCRIPTIVE_ATTRIBUTE); >+ >+ } >+ >+ /** > * Equivalent to write(indent, writer, false, false) > */ >- public void write(int indent, StringBuffer sb) >- { >- write(indent, sb, false, false); >+ public void write(int indent, StringBuffer sb) { >+ write(indent, >+ sb, >+ false, >+ false); > } >- >- >+ > /** > * Writes the common fiels of this command > * >- * @param indent The current indent that the command should be at >- * @param writer The writer used to write the macro >- * @param close A flag that indicates whether the command fragment should be closed (i.e.adding "/" to the end). >- * @param end A flag that indicates whether the command fragment should end (i.e.adding "/" to the end). >- */ >- public void write(int indent, StringBuffer sb, boolean close, boolean end) >- { >- MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false); >- boolean noWidgetId = getWidgetId() == null; >- boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn() && getWidgetId().getReferenceId() != null; >- MacroUtil.addAttribute(sb, >- new String[] { >- MacroConstants.DESCRIPTIVE_ATTRIBUTE, >- MacroConstants.TYPE_ATTRIBUTE, >- MacroConstants.RESOLVER_ATTRIBUTE, >- MacroConstants.CONTEXT_ID_ATTRIBUTE, >- MacroConstants.WIDGET_ID_ATTRIBUTE, >- MacroConstants.REFERENCE_ID_ATTRIBUTE}, >+ * @param indent >+ * The current indent that the command should be at >+ * @param writer >+ * The writer used to write the macro >+ * @param close >+ * A flag that indicates whether the command fragment should be closed (i.e.adding "/" to the end). >+ * @param end >+ * A flag that indicates whether the command fragment should end (i.e.adding "/" to the end). >+ */ >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ MacroUtil.addElement(sb, >+ indent, >+ MacroConstants.COMMAND_ELEMENT, >+ false, >+ false); >+ MacroUtil.addAttribute(sb, > new String[] { >- getDescriptiveField(), >- getType(), >- objectMineInUse || noWidgetId ? null : getWidgetId().getResolverId(), >- objectMineInUse || noWidgetId ? null : getWidgetId().getContextId().toString(), >- objectMineInUse || noWidgetId ? null : getWidgetId().getObjectId().toString(), >- objectMineInUse && !noWidgetId ? getWidgetId().getReferenceId() : null >- }, close, end); >- >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE, >+ MacroConstants.TYPE_ATTRIBUTE}, >+ new String[] {getDescriptiveField(), getType()}, >+ close, >+ end); > } >- >- >- public void writeFinish(int indent, StringBuffer writer) >- { >- >+ >+ public void writeFinish(int indent, StringBuffer writer) { >+ > } > >- public long getTimeDifference() >- { >+ public long getTimeDifference() { > return timeDifference; > } > >- public void setTimeDifference(long timeDifference) >- { >+ public void setTimeDifference(long timeDifference) { > this.timeDifference = timeDifference; > } > >- >- > /** >- * Returns the class name of the object passed in (excluding the package name) >- * This is useful for adding a descriptive field to the command >+ * Added by ANy >+ * >+ * @param macroObject >+ */ >+ protected void setFocus(IMacroObject macroObject) { >+ ensureVisible(macroObject); >+ Widget widget = macroObject.getUIObject().getWidget(); >+ Display display = widget.getDisplay(); >+ if (widget instanceof Control) { >+ Control c = (Control) widget; >+ if (!c.equals(display.getFocusControl())) >+ c.setFocus(); >+ } >+ } >+ >+ /* >+ * Added by ANy >+ */ >+ private void ensureVisible(IMacroObject macroObject) { >+ if (macroObject.getContext() instanceof Window) { >+ Window window = (Window) macroObject.getContext(); >+ window.getShell().setActive(); >+ } >+ else if (macroObject.getContext() instanceof IEditorPart) { >+ IEditorPart editor = (IEditorPart) macroObject.getContext(); >+ IWorkbenchPage page = editor.getEditorSite().getPage(); >+ page.activate(editor); >+ } >+ else if (macroObject.getContext() instanceof IViewPart) { >+ IViewPart view = (IViewPart) macroObject.getContext(); >+ IWorkbenchPage page = view.getViewSite().getPage(); >+ page.activate(view); >+ } >+ } >+ >+ /** >+ * Returns the class name of the object passed in (excluding the package name) This is useful for adding a descriptive field to the command > * >- * @param object The object >+ * @param object >+ * The object > * @return The object class name > */ >- protected String getObjectClassName (Object object) >- { >- String className = object == null ? "" : object.getClass().getName(); >+ public String getObjectClassName(Object object) { >+ String className = object == null >+ ? "" >+ : object.getClass().getName(); > int lastDotInx = className.lastIndexOf('.'); > if (lastDotInx != -1 && lastDotInx + 1 < className.length()) > return className.substring(lastDotInx + 1); >Index: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/NonTrivialWidgetResolver.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/NonTrivialWidgetResolver.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/resolvers/NonTrivialWidgetResolver.java >--- src/org/eclipse/tptp/test/auto/gui/internal/resolvers/NonTrivialWidgetResolver.java 18 Apr 2008 13:45:30 -0000 1.7 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,538 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2008 IBM Corporation and others. >- * 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 >- * $Id: NonTrivialWidgetResolver.java,v 1.7 2008/04/18 13:45:30 dmorris Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.resolvers; >- >-import org.eclipse.hyades.models.hierarchy.TRCAgentProxy; >-import org.eclipse.swt.custom.CTabItem; >-import org.eclipse.swt.graphics.Point; >-import org.eclipse.swt.widgets.Button; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Group; >-import org.eclipse.swt.widgets.Item; >-import org.eclipse.swt.widgets.Label; >-import org.eclipse.swt.widgets.Menu; >-import org.eclipse.swt.widgets.MenuItem; >-import org.eclipse.swt.widgets.TabItem; >-import org.eclipse.swt.widgets.Text; >-import org.eclipse.swt.widgets.ToolBar; >-import org.eclipse.swt.widgets.ToolItem; >-import org.eclipse.swt.widgets.Tree; >-import org.eclipse.swt.widgets.TreeItem; >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.trace.ui.internal.launcher.core.AnalysisType; >-import org.eclipse.tptp.trace.ui.internal.launcher.core.DataCollectorTreeContentProvider.ParentChildNode; >-import org.eclipse.ui.dialogs.FileSystemElement; >-import org.eclipse.ui.model.IWorkbenchAdapter; >-import org.eclipse.ui.views.IViewCategory; >- >-/** >- * <p> >- * The purpose of this class is to resolve widgets that cannot be resolved using the >- * AdaptiveWidgetResolver. These widgets will likely require nested calls in order to >- * be determined. >- * </p> >- * <p> >- * Some of the properties used to resolve a widget are locale dependent (e.g. the name >- * of a button or the closest label to a text box) >- * </p> >- * >- * @since 4.1 >- * @author Ali Mehregani >- */ >-public class NonTrivialWidgetResolver implements IWidgetResolver >-{ >- /** >- * The id of this resolver -- must be in sync with the id registered with >- * the widgetResolver extension. >- */ >- private static final String ID = "org.eclipse.tptp.test.auto.gui.nontrivial"; >- >- public IWidgetId getUniqueId(Widget parent, Object object) >- { >- if (!(object instanceof Widget)) >- return null; >- >- Widget widget = (Widget) object; >- Object data = widget.getData(); >- >- IWidgetId widgetId = null; >- >- >- /* Resolve the object based on the data type of the widget */ >- /* An agent */ >- if (data instanceof TRCAgentProxy) >- { >- widgetId = resolveAgentProxy (widget); >- } >- /* A file system element */ >- else if (data instanceof FileSystemElement) >- { >- widgetId = resolveFileSystemElement (widget); >- } >- /* A view catgory */ >- else if (data instanceof IViewCategory) >- { >- String id = ((IViewCategory)data).getId(); >- if (id != null && id.length() > 0) >- { >- widgetId = new PrimitiveWidgetId(); >- ((PrimitiveWidgetId)widgetId).setId(id); >- } >- } >- /* Analysis type */ >- else if (data instanceof ParentChildNode) >- { >- Object child = ((ParentChildNode)data).child; >- if (child instanceof AnalysisType) >- { >- widgetId = resolveAnalysisType((AnalysisType)child); >- } >- } >- >- /* Resolve the object based on its widget type */ >- /* A menu item or a tree item*/ >- else if (widget instanceof MenuItem || widget instanceof TreeItem) >- { >- widgetId = resolveItem ((Item)widget); >- } >- /* A button */ >- else if (widget instanceof Button) >- { >- widgetId = resolveButton (parent, (Button)widget, null); >- } >- /* A text box */ >- else if (widget instanceof Text) >- { >- widgetId = resolveText ((Text)widget); >- } >- /* A CTab item */ >- else if (widget instanceof CTabItem) >- { >- widgetId = validateText(((CTabItem)widget).getText()); >- } >- /* A tab item */ >- else if (widget instanceof TabItem) >- { >- widgetId = validateText(((TabItem)widget).getText()); >- } >- /* A toolbar */ >- else if (widget instanceof ToolBar) >- { >- widgetId = resolveToolBar ((ToolBar)widget); >- } >- /* A tool item */ >- else if (widget instanceof ToolItem) >- { >- widgetId = resolveToolbarItem ((ToolItem)widget); >- } >- >- >- if (widgetId != null) >- { >- widgetId.setResolverId(ID); >- } >- >- return widgetId; >- } >- >- >- >- private IWidgetId resolveAnalysisType(AnalysisType analysisType) >- { >- Object[] properties = >- { >- new Object[] {analysisType.getId(), "1.0"}, >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- >- >- >- private IWidgetId resolveToolBar(ToolBar toolbar) >- { >- int itemCount = toolbar.getItemCount(); >- String firstItem = itemCount > 1 ? limitText(toolbar.getItem(0).getToolTipText()) : null, >- lastItem = itemCount > 2 ? limitText(toolbar.getItem(itemCount - 1).getToolTipText()) : null; >- int style = toolbar.getStyle(); >- >- if (firstItem == null && lastItem == null) >- return null; >- >- Object[] properties = >- { >- new Object[] {convertText(firstItem), "0.5"}, >- new Object[] {convertText(lastItem), "0.5"}, >- new Object[] {String.valueOf(itemCount), "0.3"}, >- new Object[] {String.valueOf(style), "0.2"} >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- >- >- >- private IWidgetId resolveToolbarItem(ToolItem item) >- { >- String text = convertText(limitText(item.getToolTipText())); >- String actionId = MacroUtil.getActionId(item).toString(); >- String style = String.valueOf(item.getStyle()); >- >- Object[] properties = >- { >- new Object[] {text, "0.7"}, >- new Object[] {actionId, "0.7"}, >- new Object[] {style, "0.3"} >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- >- >- >- private String limitText(String str) >- { >- final int MAX_HOVER_TEXT_SIZE = 20; >- if (str != null && str.length() > MAX_HOVER_TEXT_SIZE) >- { >- return str.substring(0,MAX_HOVER_TEXT_SIZE) + "..."; >- } >- return str; >- } >- >- >- >- private IWidgetId resolveButton(Widget parent, Button button, Object id) >- { >- String text = null, hoverText = null, size = null, location = null; >- if ((text = button.getText()) != null) >- { >- text = convertText(text.replaceAll("\\&", "")); >- } >- /* First 20 characters of the hover text */ >- hoverText = convertText(limitText(button.getToolTipText())); >- Point sizePt = button.getSize(); >- Point locationPt = button.getLocation(); >- size = "(" + sizePt.x + "," + sizePt.y + ")"; >- location = "(" + locationPt.x + "," + locationPt.y + ")"; >- >- if (id != null && WeightedPropertyWidgetId.countTokens(id.toString()) == 3) >- { >- >- Object[] properties = >- { >- new Object[] {text, "0.5"}, >- new Object[] {hoverText, "0.5"}, >- new Object[] {size, "0.5"} >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- else >- { >- if (parent instanceof Composite) >- { >- Control[] children = ((Composite)parent).getChildren(); >- int buttonInx = 0; >- // if there are multiple buttons with the same text label >- int sameTextButtons = 0; >- String indexWeight = "0.2"; >- String lengthWeight = "0.3"; >- >- /* Find the index of the button */ >- for (int i = 0; i < children.length; i++) >- { >- if (text != null && children[i] instanceof Button){ >- String label = ((Button)children[i]).getText(); >- if (label != null){ >- label = convertText(label.replaceAll("\\&", "")); >- if (label.compareTo(text) == 0) >- sameTextButtons++; >- } >- } >- if (button == children[i]) >- { >- buttonInx = i; >- break; >- } >- } >- if (sameTextButtons > 0){ >- // two or more buttons with the same label in the >- // same child list under a composite parent >- // so shift the weighting to favor the button index >- // to get the right weighting >- indexWeight = "0.4"; >- lengthWeight = "0.1"; >- } >- >- Object[] properties = >- { >- new Object[] {text, "0.3"}, >- new Object[] {hoverText, "0.3"}, >- new Object[] {String.valueOf(children.length), lengthWeight}, >- new Object[] {size, "0.1"}, >- new Object[] {location, "0.1"}, >- new Object[] {String.valueOf(buttonInx), indexWeight}, >- >- }; >- >- float threshold = 0.7f; >- threshold += text != null ? 0.3 : 0; >- threshold += hoverText != null ? 0.3 : 0; >- >- if (threshold >= 1.0) >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- } >- >- return null; >- } >- >- >- /** >- * Replace "#", "\n" and "\r" with space to avoid having "#" generated in the >- * object id. The "#" is taken as the separator between widget Class name and >- * rest of object id (see MacroObjectLocator.locateVisibleChild). >- * >- * @param label >- * @return >- */ >- private String convertText(String label) { >- return label == null ? null : label.replaceAll("#", " ").replaceAll("\n", " ").replaceAll("\r", " "); >- } >- >- >- /** >- * The text of the closest label to a text box is used as a unique >- * identifier of the text box. The label must be in a limited >- * vicinity of the text box for its text to be considered as an identifier. >- * If the text box is owned by a group and the group only owns one text box, >- * then the group text is used to identify the widget. >- * >- * @param text The text box >- * @return The widget id for text >- */ >- private IWidgetId resolveText(Text text) >- { >- Composite parent = text.getParent(); >- Control[] children = parent.getChildren(); >- >- String groupText = null; >- if (parent instanceof Group && (groupText = ((Group)parent).getText()) != null && (groupText = groupText.replaceAll("\\&", "")).length() > 0) >- { >- int textBoxNum = 0; >- for (int i = 0; i < children.length && textBoxNum <= 1; i++) >- { >- if (children[i] instanceof Text) >- textBoxNum++; >- } >- >- if (textBoxNum <= 1) >- return new PrimitiveWidgetId(convertText(groupText)); >- } >- >- Label closestLabel = null; >- Point textLocation = text.getLocation(); >- Point currentDistance = new Point(0,0); >- Point tempDistance = new Point(0,0); >- for (int i = 0; i < children.length; i++) >- { >- Point childLocation = children[i].getLocation(); >- if (children[i] instanceof Label && >- (closestLabel == null || (tempDistance = isLabelCloser(childLocation, currentDistance, textLocation)) != null)) >- { >- boolean firstLabel = closestLabel == null; >- closestLabel = (Label)children[i];; >- if (firstLabel) >- { >- currentDistance = new Point (Math.abs(childLocation.x - textLocation.x), Math.abs(childLocation.y - textLocation.y)); >- } >- else >- { >- currentDistance = tempDistance; >- } >- } >- } >- >- String closestLabelText = null; >- if (closestLabel != null && currentDistance.x + currentDistance.y <= 100 && >- closestLabel.getText() != null && (closestLabelText = closestLabel.getText().replaceAll("\\&", "")).length() > 0) >- return new PrimitiveWidgetId(convertText(closestLabelText)); >- return null; >- } >- >- >- private Point isLabelCloser(Point newlblLocation, Point currentDistance, Point textLocation) >- { >- Point tempLocation = new Point (Math.abs(newlblLocation.x - textLocation.x), Math.abs(newlblLocation.y - textLocation.y)); >- if (tempLocation.x + tempLocation.y < currentDistance.x + currentDistance.y) >- return tempLocation; >- return null; >- } >- >- >- private IWidgetId validateText(String text) >- { >- if (text != null && (text = text.replaceAll("\\&", "")).length() > 0) >- return new PrimitiveWidgetId(convertText(text)); >- return null; >- } >- >- >- /** >- * Computes the item id based on the following properties >- * and weights. The threshold is set to 1.0: >- * >- * <ul> >- * <li> (Descriptive name of the item, 1.0) </li> >- * </ul> >- * @param item The item >- * @return The weighted id >- */ >- private IWidgetId resolveItem(Item item) >- { >- StringBuffer descriptiveText = new StringBuffer(); >- findItemText(item, descriptiveText); >- >- /* Remove the ampersands */ >- String itemText = convertText(descriptiveText.toString().replaceAll("\\&", "")); >- >- Object[] properties = >- { >- new Object[] {itemText, "1.0"}, >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- >- >- /** >- * Walk through the item and return a descriptive text that corresponds >- * to all item selections leading to the item. (e.g. File-New-Project) >- * >- * @param item The item >- * @param descriptiveText In the end, this buffer will contain a >- * descriptive text of all items leading to the item that >- * is passed in as argument >- */ >- private void findItemText(Item item, StringBuffer descriptiveText) >- { >- if (item == null) >- return; >- >- String descriptiveTextStr = item.getText(); >- if (descriptiveText.length() > 0) >- descriptiveTextStr += "-"; >- >- descriptiveText.insert(0, descriptiveTextStr); >- >- Item parentItem = null; >- if (item instanceof MenuItem) >- { >- Menu menu = ((MenuItem)item).getParent(); >- parentItem = (menu == null ? null : menu.getParentItem()); >- } >- else if (item instanceof TreeItem) >- { >- parentItem = ((TreeItem)item).getParentItem(); >- } >- >- if (parentItem != null) >- findItemText(parentItem, descriptiveText); >- } >- >- >- private IWidgetId resolveFileSystemElement(Widget widget) >- { >- >- FileSystemElement fileSystemElement = (FileSystemElement) widget.getData(); >- if (fileSystemElement.isDirectory()) >- return null; >- >- Object[] properties = >- { >- new Object[] {((IWorkbenchAdapter)fileSystemElement.getAdapter(IWorkbenchAdapter.class)).getLabel(null), "1.0"} >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)1.0); >- } >- >- private WeightedPropertyWidgetId resolveAgentProxy(Widget widget) >- { >- StringBuffer treeIndex = new StringBuffer(); >- if (widget instanceof TreeItem) >- findTreeItemIndex((TreeItem)widget, treeIndex); >- else >- return null; >- >- TRCAgentProxy proxy = (TRCAgentProxy) widget.getData(); >- Object[] properties = >- { >- new Object[] {treeIndex.toString(), "0.4"}, >- new Object[] {proxy.getProcessProxy().getName(), "0.2"}, >- new Object[] {proxy.getProcessProxy().getVmArguments(), "0.1"}, >- new Object[] {proxy.getProcessProxy().getClasspath(), "0.1"}, >- new Object[] {proxy.getProcessProxy().getLocation(), "0.1"}, >- new Object[] {proxy.getProcessProxy().getParameters(), "0.1"}, >- new Object[] {proxy.getProfileFile(), "0.1"}, >- new Object[] {proxy.getName(), "0.1"}, >- new Object[] {String.valueOf(proxy.isAttached()), "0.1"}, >- new Object[] {String.valueOf(proxy.isMonitored()), "0.1"}, >- new Object[] {String.valueOf(proxy.isToProfileFile()), "0.1"}, >- }; >- >- return WeightedPropertyWidgetId.constructId (properties, (float)0.7); >- } >- >- >- >- >- private void findTreeItemIndex(TreeItem treeItem, StringBuffer sb) >- { >- TreeItem parentItem = treeItem.getParentItem(); >- if (parentItem != null) >- { >- int index = parentItem.indexOf(treeItem); >- if (index != -1) >- sb.append("|" + String.valueOf(index + 1)); >- >- findTreeItemIndex (parentItem, sb); >- } >- Tree tree = treeItem.getParent(); >- int index = tree.indexOf(treeItem); >- if (index != -1) >- sb.append("|" + String.valueOf(index)); >- >- } >- >- >- >- public boolean foundWidget(Object object, Object id) >- { >- Object objectId = null; >- if (object instanceof Button) >- { >- Button button = (Button) object; >- objectId = resolveButton(button.getParent(), button, id); >- } >- >- if (objectId == null) >- objectId = getUniqueId(object instanceof Control ? ((Control)object).getParent() : null, object); >- return id == null ? false : objectId == null ? false : objectId.equals(id); >- } >- >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/PrimitiveWidgetId.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/PrimitiveWidgetId.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/resolvers/PrimitiveWidgetId.java >--- src/org/eclipse/tptp/test/auto/gui/internal/resolvers/PrimitiveWidgetId.java 10 Jul 2006 14:49:04 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,80 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.resolvers; >- >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >- >- >-/** >- * A primitive string widget id. The string object must be an exact match >- * for the two given ids to equal. Contributors can extend this class or >- * provide a direct implementation of {@link IWidgetId} >- * >- * @author Ali Mehregani >- */ >-public class PrimitiveWidgetId implements IWidgetId >-{ >- /** The resolver id */ >- private String resolverId; >- >- /** The string id of the widget */ >- private String id; >- >- >- public PrimitiveWidgetId() >- { >- >- } >- >- public PrimitiveWidgetId(String id) >- { >- this.id = id; >- } >- >- public String getResolverId() >- { >- return resolverId; >- } >- >- public void setResolverId(String resolverId) >- { >- this.resolverId = resolverId; >- } >- >- /** >- * @return the id >- */ >- public String getId() >- { >- return id; >- } >- >- /** >- * @param id the id to set >- */ >- public void setId(String id) >- { >- this.id = id; >- } >- >- public boolean equals(Object o) >- { >- if (id == null) >- return o == null; >- return id.equals(o); >- } >- >- public String toString() >- { >- return id; >- } >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/WeightedPropertyWidgetId.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/WeightedPropertyWidgetId.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/resolvers/WeightedPropertyWidgetId.java >--- src/org/eclipse/tptp/test/auto/gui/internal/resolvers/WeightedPropertyWidgetId.java 4 Dec 2006 02:55:08 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,230 +0,0 @@ >-/********************************************************************** >- * Copyright (c) 2005, 2006 IBM Corporation and others. >- * 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 >- * $Id: WeightedPropertyWidgetId.java,v 1.3 2006/12/04 02:55:08 amehregani Exp $ >- * >- * Contributors: >- * IBM - Initial API and implementation >- **********************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.resolvers; >- >-import java.util.regex.Matcher; >-import java.util.regex.Pattern; >- >-import org.eclipse.hyades.test.common.util.XMLUtil; >- >-/** >- * Defines a widget Id by a set of properties that the widget must have. Each >- * property is assigned a weight and if the total weight exceeds the threshold, then >- * the widget is identified as a match >- * >- * @author Ali Mehregani >- */ >-public class WeightedPropertyWidgetId extends PrimitiveWidgetId >-{ >- /* Stored elements are of type Object[2], where the first element is the value returned by the >- * method corresponding to the property and the second value is the weight associated with that >- * property. */ >- private Object[] propertyWeightPair; >- private float threshold; >- >- private final static Pattern pairPattern = Pattern.compile(".*?\\{\\{([^\\}]+)\\}\\}-\\{\\{([^\\}]+)\\}\\}.*"); >- >- public boolean equals(Object obj) >- { >- String stringToCompare = null; >- boolean compare = false; >- >- /* The object is of our own kind */ >- if (obj instanceof WeightedPropertyWidgetId) >- { >- WeightedPropertyWidgetId idToCompareWith = (WeightedPropertyWidgetId)obj; >- >- if (this == idToCompareWith) >- return true; >- >- compare = true; >- stringToCompare = idToCompareWith.toString(); >- } >- >- /* The object is a string (most likely coming from a macro) */ >- else if (obj instanceof String) >- { >- compare = true; >- stringToCompare = (String)obj; >- } >- >- if (!compare) >- return false; >- >- /* Use regular expression to distinguish the returned value of each method >- * from the weight */ >- float accumMatchRate = 0; >- int loopIterationNo = -1; >- >- while (stringToCompare.length() > 0 && (loopIterationNo + 1) < propertyWeightPair.length) >- { >- loopIterationNo++; >- Matcher pairTokenMatcher = pairPattern.matcher(stringToCompare); >- >- /* Discontinue if there is no match */ >- if (!pairTokenMatcher.matches() || pairTokenMatcher.groupCount() != 2) >- break; >- >- /* Otherwise walk through each token */ >- String originalProperty = pairTokenMatcher.group(1); >- String prop = originalProperty; >- if (prop.length() > 0) >- prop = XMLUtil.removeXMLSymbols(prop); >- float weight = Float.parseFloat(pairTokenMatcher.group(2)); >- >- /* The ordering of the tokens for the IDs being compared must be the same. */ >- Object[] propertyWeightPair = (Object[])this.propertyWeightPair[loopIterationNo]; >- if (!prop.equals("null") && >- (prop.length() > 0 ? prop.charAt(0) == ((String)propertyWeightPair[0]).charAt(0) || prop.charAt(0) == '&' : true) && >- (prop.equals(propertyWeightPair[0]) || prop.replaceAll("\\&", "").equals(propertyWeightPair[0]) || prop.replace('/', '\\').equals(propertyWeightPair[0]))) >- accumMatchRate += Float.parseFloat((String)propertyWeightPair[1]); >- >- String currentToken = "{{" + originalProperty + "}}-{{" + weight + "}}"; >- if (currentToken.equals(stringToCompare)) >- break; >- >- int inx = stringToCompare.indexOf(currentToken); >- if (inx != -1) >- stringToCompare = stringToCompare.substring(inx + currentToken.length(), stringToCompare.length()); >- >- else >- break; /* The control flow should never reach this block */ >- >- } >- >- if (accumMatchRate >= threshold) >- return true; >- return false; >- } >- >- >- /** >- * Return a string representation of this identifier. The property, weight information >- * is organized in this format: {{property-value1}}-{{weight1}}{{property-value2}}:{{weight2}} >- */ >- public String toString() >- { >- String retValue = ""; >- for (int i = 0; i < this.propertyWeightPair.length; i++) >- retValue += "{{" + ((Object[])this.propertyWeightPair[i])[0] + "}}-{{" + ((Object[])this.propertyWeightPair[i])[1] + "}}"; >- >- return XMLUtil.useXMLSymbols(retValue); >- } >- >- >- public float getThreshold() >- { >- return threshold; >- } >- >- >- public void setThreshold(float threshold) >- { >- this.threshold = threshold; >- } >- >- >- public Object[] getPropertyWeightPair() >- { >- return propertyWeightPair; >- } >- >- >- public void setPropertyWeightPair(Object[] propertyWeightPair) >- { >- this.propertyWeightPair = propertyWeightPair; >- } >- >- /** >- * Walk through the properties and return true for as long as one of them is not null. >- * >- * @return true if at least one property is not null; false otherwise >- */ >- public boolean noValidProperties() >- { >- if (propertyWeightPair == null) >- return true; >- >- for (int i = 0; i < propertyWeightPair.length; i++) >- { >- String property = (String)((Object[])propertyWeightPair[i])[0]; >- if (property != null && !property.equals("null")) >- return false; >- } >- return true; >- } >- >- >- /** >- * Convenient method available for clients to use in order to construct a >- * weighted property id >- * >- * @param properties The (properties, weight) pairs of the item (weights should be a value between (0, 1]) >- * @param threshold The threshold that this property should meet (should be a value between (0-1]) >- * @return Returns an instance of this class with the appropriate fields set. >- */ >- protected static WeightedPropertyWidgetId constructId(Object[] properties, float threshold) >- { >- /* Step through the properties and replace null values with the literal string null */ >- for (int i = 0; i < properties.length; i++) >- { >- String property = (String)((Object[])properties[i])[0]; >- if (property == null || property.length() <= 0) >- ((Object[])properties[i])[0] = "null"; >- >- } >- >- WeightedPropertyWidgetId widgetId = new WeightedPropertyWidgetId (); >- widgetId.setPropertyWeightPair(properties); >- widgetId.setThreshold(threshold); >- >- if (widgetId.noValidProperties()) >- return null; >- return widgetId; >- } >- >- >- /** >- * Given a string representation of the id, this method will return the number of tokens >- * that it contains. A token is a name, value pair in the format. >- * >- * @param id The string representation of the id >- * @return The number of tokens of the id >- */ >- protected static int countTokens(String id) >- { >- if (id == null) >- return 0; >- >- char[] characters = id.toCharArray(); >- boolean braceInxHit = false; >- int tokenCount = 0; >- for (int i = 0; i < characters.length; i++) >- { >- if (characters[i] == '{') >- { >- if (braceInxHit) >- { >- tokenCount++; >- } >- else >- { >- braceInxHit = true; >- continue; >- } >- } >- braceInxHit = false; >- } >- >- return tokenCount / 2; >- } >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/AdaptiveWidgetResolver.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/resolvers/AdaptiveWidgetResolver.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/resolvers/AdaptiveWidgetResolver.java >--- src/org/eclipse/tptp/test/auto/gui/internal/resolvers/AdaptiveWidgetResolver.java 26 Apr 2007 20:03:22 -0000 1.6 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,613 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2007 IBM Corporation and others. >- * 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 >- * $Id: AdaptiveWidgetResolver.java,v 1.6 2007/04/26 20:03:22 paules Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.resolvers; >- >-import java.io.IOException; >-import java.io.InputStream; >-import java.lang.reflect.Method; >-import java.net.URL; >-import java.util.Hashtable; >-import java.util.Vector; >- >-import org.eclipse.hyades.test.common.util.XMLUtil; >-import org.eclipse.jface.dialogs.MessageDialog; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.osgi.framework.Bundle; >-import org.w3c.dom.Element; >-import org.w3c.dom.NodeList; >- >-/** >- * The following widget resolver attempts to resolve widgets using a static >- * XML file stored under the auto-gui folder under this plugin. >- * >- * @since 4.1 >- * @author Ali Mehregani >- */ >-public class AdaptiveWidgetResolver implements IWidgetResolver >-{ >- /** >- * The id of this resolver -- must be in sync with the id registered with >- * the widgetResolver extension. >- */ >- private static final String ID = "org.eclipse.tptp.test.auto.gui.adaptive"; >- >- /** The assumed file name relative to this plugin */ >- public final static String WIDGET_REG_FILE = "auto-gui/widgetReg.xml"; >- >- /** The widget registerations */ >- private IWidgetRegistration widgetReg; >- >- >- public AdaptiveWidgetResolver() >- { >- widgetReg = new WidgetRegistration (this, WIDGET_REG_FILE); >- } >- >- >- public IWidgetId getUniqueId(Widget parent, Object object) >- { >- if (!(object instanceof Widget)) >- return null; >- >- widgetReg.load(); >- IWidgetId widgetId = widgetReg.getWidgetId((Widget)object); >- if (widgetId != null) >- widgetId.setResolverId(ID); >- return widgetId; >- } >- >- /** >- * Clients have the option of overwriting this in order to be able to locate >- * the widget them self in the registeration entries that exist. >- */ >- public WidgetRegValue findWidget (Hashtable registerations, Widget widget) >- { >- return null; >- } >- >- >- public class WidgetRegistration implements IWidgetRegistration >- { >- /* The file name */ >- private String fileName; >- >- /* The last size of the file when it was properly read */ >- private long lastModifiedDate; >- >- /* The file size (stored in case there was an error last time reading the file */ >- private long lastModifiedDateDetected; >- >- /* Indicates if there was an error in parsing the file */ >- private boolean errorOccurred; >- >- /* The data structures holding the registered widgets. >- * Key = class name; Value = WidgetRegValue */ >- private Hashtable regWidgets; >- >- /* The global match threshold */ >- private float globalMatchThreshold; >- >- /* The class name used for the default entry */ >- public static final String DEFAULT_ENTYR = "0_DEFAULT_ENTRY"; >- >- /* The adaptive widget resolver used as the driver for resolving widgets */ >- private AdaptiveWidgetResolver adaptiveWidgetResolver; >- >- public WidgetRegistration (AdaptiveWidgetResolver adaptiveWidgetResolver, String fileName) >- { >- this.fileName = fileName; >- this.lastModifiedDate = 0; >- this.lastModifiedDateDetected = 0; >- this.errorOccurred = false; >- this.regWidgets = new Hashtable(); >- this.adaptiveWidgetResolver = adaptiveWidgetResolver; >- } >- >- >- public void load() >- { >- InputStream regXMLInputStream = null; >- try >- { >- >- >- Bundle guiBundle = GuiPlugin.getDefault().getBundle(); >- long currentModifiedDate = guiBundle.getLastModified();// added for defect 169733 Liz Dancy >- >- /* Checking the file size doesn't guarantee to us that the file hasn't changed. This is >- * the best we can do. Replace this with last modified date if API is available. */ >- if (currentModifiedDate > 0 && (currentModifiedDate == lastModifiedDate || (errorOccurred && lastModifiedDateDetected == currentModifiedDate))) >- return; >- >- URL regFileURL = GuiPlugin.getDefault().getBundle().getEntry(fileName); >- lastModifiedDateDetected = currentModifiedDate; >- >- /* Parse the XML file */ >- regXMLInputStream = regFileURL.openStream(); >- Element rootElement = XMLUtil.loadDom(regXMLInputStream, "widgetResolverRule"); >- if (rootElement == null) >- { >- lastModifiedDate = 0; >- errorOccurred = true; >- >- /* Display an error message if we are recording */ >- if (MacroManager.getInstance().getGlobalState() == MacroManager.RECORDING_MODE) >- { >- AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, >- AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, MessageDialog.WARNING); >- } >- return; >- } >- this.regWidgets.clear(); >- parseRegFile(rootElement); >- lastModifiedDate = currentModifiedDate; >- } >- catch (Throwable t) >- { >- /* Set the file size to zero to invalidate this widget resolver */ >- lastModifiedDate = 0; >- errorOccurred = true; >- >- /* Display an error message if we are recording */ >- if (MacroManager.getInstance().getGlobalState() == MacroManager.RECORDING_MODE) >- { >- AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, >- AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, MessageDialog.WARNING); >- } >- } >- finally >- { >- if (regXMLInputStream != null) >- { >- try >- { >- regXMLInputStream.close(); >- } catch (IOException e) >- { >- /* Ignore the error */ >- } >- } >- } >- >- } >- >- public float getGlobalThreshold() >- { >- return globalMatchThreshold; >- } >- >- /** >- * parse the registation file that has already been loaded >- */ >- private void parseRegFile(Element rootElement) >- { >- if (rootElement == null) >- return; >- >- NodeList classList = XMLUtil.getChildrenByName(rootElement, "class"); >- parseClassElements (classList); >- globalMatchThreshold = Float.parseFloat(XMLUtil.getValue (rootElement, "globalMatchThreshold")); >- NodeList defaultList = XMLUtil.getChildrenByName(rootElement, "default"); >- parseDefaultElements (defaultList); >- } >- >- >- private void parseDefaultElements(NodeList defaultList) >- { >- if (defaultList == null || defaultList.getLength() < 1) >- return; >- >- /* We only expect one default element */ >- if(defaultList.item(0) instanceof Element) >- { >- Element defaultElement = (Element)defaultList.item(0); >- NodeList methodList = XMLUtil.getChildrenByName(defaultElement, "method"); >- WidgetRegValue widgetReg = new WidgetRegValue(); >- >- parseMethod (methodList, widgetReg); >- if (widgetReg != null) >- regWidgets.put(DEFAULT_ENTYR, widgetReg); >- >- } >- } >- >- >- /** >- * Parse the class elements >- */ >- private void parseClassElements(NodeList classList) >- { >- if (classList == null || classList.getLength() <= 0) >- return; >- >- for(int i = 0; i < classList.getLength(); i++) >- { >- if(classList.item(i) instanceof Element) >- { >- >- Element classElement = (Element)classList.item(i); >- String className = XMLUtil.getValue(classElement, "name"); >- NodeList methodList = XMLUtil.getChildrenByName(classElement, "method"); >- WidgetRegValue widgetReg = new WidgetRegValue(); >- String matchThreshold = XMLUtil.getValue(classElement, "matchThreshold"); >- if (matchThreshold != null) >- widgetReg.setClassMatchThreshold(Float.parseFloat (matchThreshold)); >- >- parseMethod (methodList, widgetReg); >- if (widgetReg != null) >- regWidgets.put(className, widgetReg); >- >- >- } >- } >- } >- >- >- /** >- * Parse the method element and return a widget registration entry >- * >- * @param methodList The method list >- * @param widgetReg the widget registration entry that will be augmented >- * @return A widget registeration entry >- */ >- private void parseMethod(NodeList methodList, WidgetRegValue widgetReg) >- { >- if (methodList == null || methodList.getLength() <= 0) >- return; >- >- for(int i = 0; i < methodList.getLength(); i++) >- { >- if(methodList.item(i) instanceof Element) >- { >- Element methodElement = (Element)methodList.item(i); >- String methodName = XMLUtil.getValue(methodElement, "name"); >- float weight = Float.parseFloat(XMLUtil.getValue(methodElement, "weight")); >- PropertyValue propertyVal = new PropertyValue(); >- propertyVal.setWeight(weight); >- >- NodeList argumentList = XMLUtil.getChildrenByName(methodElement, "argument"); >- if (argumentList != null) >- parseArguments(argumentList, propertyVal); >- >- widgetReg.addProperty(methodName, propertyVal); >- } >- } >- } >- >- >- /** >- * Parse the arguments >- * >- * @param argumentList The arugment list >- * @param propertyVal The property value entry that will be augmented to. >- */ >- private void parseArguments(NodeList argumentList, PropertyValue propertyVal) >- { >- if (argumentList == null || argumentList.getLength() <= 0) >- return; >- >- Vector arguments = new Vector(); >- for(int i = 0; i < argumentList.getLength(); i++) >- { >- if(argumentList.item(i) instanceof Element) >- { >- Element argumentElement = (Element)argumentList.item(i); >- String argumentValue = XMLUtil.getValue(argumentElement, "value"); >- arguments.add(argumentValue); >- } >- } >- >- propertyVal.setArguments(arguments); >- } >- >- >- public IWidgetId getWidgetId(Widget widget) >- { >- /* Use this resolver if we were able to successfully resolve parse the XML file */ >- if (lastModifiedDate > 0) >- { >- /* First attempt the widget itself. If that fails, then try its data attribute */ >- Object data = widget; >- >- WidgetRegValue widgetValue = (WidgetRegValue)regWidgets.get(data.getClass().getName()); >- if (widgetValue == null && widget.getData() != null) >- { >- data = widget.getData(); >- widgetValue = (WidgetRegValue)regWidgets.get(data.getClass().getName()); >- >- /* If that fails, then walk throught the class heirarchy (the interafaces and superclasses */ >- if (widgetValue == null) >- { >- widgetValue = walkThroughClassHeirarchy (data.getClass()); >- >- } >- } >- >- /* As a final resolution, try and call the driver class to resolve the widget */ >- if (widgetValue == null) >- widgetValue = adaptiveWidgetResolver.findWidget(regWidgets, widget); >- >- >- Vector propertyWeightPair = new Vector (5); >- WeightedPropertyWidgetId adaptiveWidgetId = new WeightedPropertyWidgetId(); >- boolean specificValidEntry = false; >- boolean defaultValidEntry = false; >- >- if (widgetValue != null) >- { >- float threshold = widgetValue.getClassMatchThreshold(); >- if (threshold == 0) >- threshold = globalMatchThreshold; >- adaptiveWidgetId.setThreshold(threshold); >- >- /* Specific properties associated with this type */ >- specificValidEntry = appendProperties (data, propertyWeightPair, widgetValue); >- } >- >- /* Default properties */ >- Vector defaultEntries = new Vector(); >- defaultValidEntry = appendProperties (widget, defaultEntries, (WidgetRegValue)regWidgets.get(DEFAULT_ENTYR), true); >- if (defaultValidEntry) >- propertyWeightPair.addAll(propertyWeightPair); >- >- >- /* Return null if we weren't able to get any of the widgets properties */ >- if (propertyWeightPair.size() <= 0) >- return null; >- >- adaptiveWidgetId.setPropertyWeightPair(propertyWeightPair.toArray()); >- if (specificValidEntry || defaultValidEntry) >- return adaptiveWidgetId; >- return null; >- } >- >- return null; >- } >- >- >- private WidgetRegValue walkThroughClassHeirarchy(Class widgetClass) >- { >- WidgetRegValue widgetValue = null; >- >- widgetValue = (WidgetRegValue)regWidgets.get(widgetClass.getName()); >- if (widgetValue != null) >- return widgetValue; >- >- Class[] interfaces = widgetClass.getInterfaces(); >- >- /* Try the interfaces first */ >- for (int i = 0; i < interfaces.length; i++) >- { >- widgetValue = (WidgetRegValue)regWidgets.get(interfaces[i].getName()); >- widgetValue = (widgetValue == null ? walkThroughClassHeirarchy(interfaces[i]) : widgetValue); >- if (widgetValue != null) >- return widgetValue; >- } >- >- /* We failed with the interfaces, now try the super class */ >- Class extendedClass = widgetClass.getSuperclass(); >- if (extendedClass != null) >- widgetValue = walkThroughClassHeirarchy(extendedClass); >- >- return widgetValue; >- } >- >- >- private boolean appendProperties(Object data, Vector propertyWeightPair, WidgetRegValue widgetValue) >- { >- return appendProperties(data, propertyWeightPair, widgetValue, false); >- } >- >- private boolean appendProperties(Object data, Vector propertyWeightPair, WidgetRegValue widgetValue, boolean isDefault) >- { >- boolean validEntry = false; >- if (widgetValue == null) >- return false; >- >- Vector properties = widgetValue.getProperties(); >- for (int i = 0, propertySize = properties.size(); i < propertySize; i++) >- { >- String property = (String) properties.get(i); >- PropertyValue propertyValue = widgetValue.getPropertyValue(property); >- String retValue = invokeProperty (data, property, propertyValue); >- >- if ((retValue == null || retValue.length() <= 0) && isDefault) >- retValue = invokeProperty (((Widget)data).getData(), property, propertyValue); >- >- /* Don't add it if the return value is null or of zero length */ >- if (retValue == null || retValue.length() <= 0) >- retValue = "null"; /* Set the value to the literal string 'null' */ >- else >- validEntry = true; >- >- >- propertyWeightPair.add(new Object[] {retValue, String.valueOf(propertyValue.getWeight())}); >- } >- return validEntry; >- } >- >- >- /** >- * Invoke the appropriate method to get the property value >- * >- * @param data The data corresponding to the widget or the data attribute of the widget >- * @param theMethod The method corresponding to the property value >- * @param propertyValue The property information container >- * >- * @return The returned value of the method corresponding to the argument >- */ >- private String invokeProperty(Object data, String theMethod, PropertyValue propertyValue) >- { >- try >- { >- Class theClass = data.getClass(); >- int paramCount = 0; >- Vector args = propertyValue.getArguments(); >- if (args != null && args.size() > 0) >- paramCount = args.size(); >- >- /* We only support method with string parameters */ >- Class[] params = new Class[paramCount]; >- for (int i = 0; i < params.length; i++) >- params[i] = String.class; >- >- Method method = theClass.getMethod(theMethod, params); >- >- Object[] methodArgs = null; >- if (paramCount > 0) >- methodArgs = propertyValue.getArguments().toArray(); >- >- Object retValue = method.invoke(data, methodArgs); >- return retValue.toString(); >- } >- catch (Throwable t) >- { >- /* Return null if in case we can retrieve the property value */ >- return null; >- } >- >- } >- >- >- public WidgetRegValue getDefaultWidgetReg() >- { >- if (regWidgets == null) >- return null; >- return (WidgetRegValue)regWidgets.get(DEFAULT_ENTYR); >- } >- >- } >- >- >- /** >- * Can be used to provide any alternative implementation of how the widget registration file >- * is loaded and queried. >- * >- * @author Ali Mehregani >- */ >- public interface IWidgetRegistration >- { >- /** >- * Used to load the necessary file and store the data in a datastructure that >- * will later be used to query the registrations. >- */ >- public void load(); >- >- /** >- * Retrieve the widget id from the registrations >- * >- * @param widget The widget in question >- * @return The persistent identifier for the widget >- */ >- public IWidgetId getWidgetId (Widget widget); >- } >- >- >- /** >- * A container class for the registeration value of a widget >- * >- * @author Ali Mehregani >- */ >- private class WidgetRegValue >- { >- /* Key = method names, value = propertyValue */ >- private Hashtable properties; >- >- /* Class match treshold */ >- private float classMatchThreshold; >- >- /* This vector is used to preserve the ordering of the properties inserted in the hashtable */ >- private Vector hashKeys; >- >- public WidgetRegValue() >- { >- properties = new Hashtable(); >- classMatchThreshold = 0; >- hashKeys = new Vector(); >- } >- >- public Vector getProperties() >- { >- return hashKeys; >- } >- >- public PropertyValue getPropertyValue (String propertyValue) >- { >- return (PropertyValue) properties.get(propertyValue); >- } >- >- public PropertyValue getPropertyValue (int inx) >- { >- if (inx >= hashKeys.size()) >- return null; >- return (PropertyValue) properties.get(hashKeys.get(inx)); >- } >- >- public void addProperty (String methodName, PropertyValue propertyValue) >- { >- hashKeys.add(methodName); >- properties.put (methodName, propertyValue); >- } >- >- public float getClassMatchThreshold() >- { >- return classMatchThreshold; >- } >- >- public void setClassMatchThreshold(float classMatchThreshold) >- { >- this.classMatchThreshold = classMatchThreshold; >- } >- >- } >- >- /** >- * Container class for property values >- * >- * @author Ali Mehregani >- */ >- private class PropertyValue >- { >- private Vector arguments; >- private float weight; >- >- public Vector getArguments() >- { >- return arguments; >- } >- public void setArguments(Vector arguments) >- { >- this.arguments = arguments; >- } >- public float getWeight() >- { >- return weight; >- } >- public void setWeight(float weight) >- { >- this.weight = weight; >- } >- } >- >- public boolean foundWidget(Object object, Object id) >- { >- Object objectId = getUniqueId(object instanceof Control ? ((Control)object).getParent() : null, object); >- return id == null ? false : objectId == null ? false : objectId.equals(id); >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetId.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetId.java,v >retrieving revision 1.1 >diff -u -r1.1 IWidgetId.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetId.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetId.java 26 Jul 2008 19:22:05 -0000 >@@ -18,6 +18,7 @@ > * and {@link java.lang.Object#toString()}. > * > * @since 4.3 >+ * @deprecated > * @author Ali Mehregani > */ > public interface IWidgetId >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetResolver.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetResolver.java,v >retrieving revision 1.2 >diff -u -r1.2 IWidgetResolver.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetResolver.java 4 Dec 2006 02:55:08 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetResolver.java 26 Jul 2008 19:22:05 -0000 >@@ -13,37 +13,46 @@ > import org.eclipse.swt.widgets.Widget; > > /** >- * This interface is registered using extension point <code>org.eclipse.tptp.test.auto.gui.widgetResolver</code> >- * which is expected to return a unique identifier from a provided widget. The identifier must be reproducable >- * between sessions so that it can be used to locate the widget on playback. >+ * This interface is registered using extension point >+ * <code>org.eclipse.tptp.test.auto.gui.widgetResolver</code> which is expected >+ * to return a unique identifier from a provided widget. The identifier must be >+ * reproducable between sessions so that it can be used to locate the widget on >+ * playback. > * > * @since 3.1 >+ * @deprecated > */ >-public interface IWidgetResolver >-{ >+public interface IWidgetResolver { > /** > * Returns a unique identifier for the provided widget. > * >- * @param widget The parent object. The value of this parameter can be null if the parent >- * of object cannot be resolved. >- * @param object The object whose id is suppose to be resolved. The type of this object is >- * <b>usually</b> a widget, but it can also be a <code>java.lang.String</code> or any other >- * arbitrary type depending on the implementation of the widget. For example, when attempting >- * to resolve a combo box item, parent will point to the combo box and object will point to >- * a <code>java.lang.String</code> item representing the item selected. >- * >+ * @param widget >+ * The parent object. The value of this parameter can be null if >+ * the parent of object cannot be resolved. >+ * @param object >+ * The object whose id is suppose to be resolved. The type of >+ * this object is <b>usually</b> a widget, but it can also be a >+ * <code>java.lang.String</code> or any other arbitrary type >+ * depending on the implementation of the widget. For example, >+ * when attempting to resolve a combo box item, parent will point >+ * to the combo box and object will point to a >+ * <code>java.lang.String</code> item representing the item >+ * selected. >+ * > * @return unique identifier that can be used to locate the widget or > * <code>null</code> if none can be found. > */ > public IWidgetId getUniqueId(Widget parent, Object object); > >- > /** >- * Given an object and an id, this method should return true if and only if the id >- * of object as determined by this resolver equals the 'id' passed in. >- * >- * @param object An object >- * @param id The being searched for >+ * Given an object and an id, this method should return true if and only if >+ * the id of object as determined by this resolver equals the 'id' passed >+ * in. >+ * >+ * @param object >+ * An object >+ * @param id >+ * The being searched for > * @return true iff object's id is equalled to 'id' > */ > public boolean foundWidget(Object object, Object id); >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IMacroInstruction.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IMacroInstruction.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IMacroInstruction.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IMacroInstruction.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,88 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import java.util.Hashtable; >- >-import org.eclipse.core.runtime.CoreException; >-import org.w3c.dom.Node; >- >- >-/** >- * Represents a macro instruction. The instruction is expected to >- * both be writable and playable. >- * >- * @author Ali Mehregani >- */ >-public interface IMacroInstruction extends IWritable, IPlayable >-{ >- /** >- * Invoked to load the macro instruction based on its corresponding >- * XML node. >- * >- * @param node The XML node representing this macro instruction >- * @param lineTable Contains line level information >- * >- * @throws CoreException In case of an unexpected error >- */ >- public void load(Node node, Hashtable lineTable) throws CoreException; >- >- >- /** >- * Returns the corresponding widget id of this instruction >- * >- * @return The widget id >- */ >- public WidgetIdentifier getWidgetId(); >- >- >- /** >- * Sets the widget identifier for this macro instruction >- * >- * @return widgetIdentifier The widget identifier >- */ >- public void setWidgetId(WidgetIdentifier widgetIdentifier); >- >- >- /** >- * Returns the corresponding IUIObject of this macro instruction. >- * If an object is not supported then null will be returned. >- * >- * @return The corresponding object of this instruction >- */ >- public IUIObject getCorrespondingObject(); >- >- >- /** >- * Sets the UI object for this macro instruction. >- * >- * @param uiObject The corresponding object >- */ >- public void setCorrespondingObject(IUIObject uiObject); >- >- >- /** >- * Returns the starting line number of this macro instruction in the >- * macro script that it belongs to. >- * >- * @return The starting line >- */ >- public int getStartLine(); >- >- >- /** >- * Returns the last line number of this macro instruction in the >- * macro script that it belongs to. >- * >- * @return The last line >- */ >- public int getStopLine(); >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoader.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoader.java,v >retrieving revision 1.1 >diff -u -r1.1 WidgetResolverLoader.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoader.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoader.java 26 Jul 2008 19:22:05 -0000 >@@ -10,71 +10,84 @@ > *******************************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.core; > >+import java.util.Hashtable; >+import java.util.Vector; >+ > import org.eclipse.core.runtime.CoreException; > import org.eclipse.core.runtime.IConfigurationElement; >+import org.eclipse.core.runtime.Platform; > > /** >- * Represents each widgetResolver element that appears under a >- * widgetResolver extension >+ * Represents each widgetResolver element that appears under a widgetResolver >+ * extension > * > * @author Ali Mehregani >+ * @deprecated > */ >-public class WidgetResolverLoader >-{ >+public class WidgetResolverLoader { >+ private static final String EXTENSION_POINT = "widgetResolver"; >+ > /** The id of the widget resolver */ > private String id; >- >+ > /** The widget resolver class */ > private IWidgetResolver widgetResolver; >- >+ > /** The priority of this widget resolver registeration */ > private int priority; >- >- >+ >+ /* Keeps an ordered list of the resolver ids */ >+ private static String[] resolverIds; >+ >+ /* >+ * The widget resolver: KEY = resolver id VALUE = A class of type >+ * WidgetResolverLoader >+ */ >+ private static Hashtable widgetResolvers = new Hashtable(); >+ > /** > * Limit the visibility of the constructor > */ >- private WidgetResolverLoader(String id, IWidgetResolver resolver, int priority) >- { >+ private WidgetResolverLoader(String id, IWidgetResolver resolver, >+ int priority) { > this.id = id; > this.widgetResolver = resolver; > this.priority = priority; > } >- >- >+ > /** >- * Constructs an instance of this class based on the configuration >- * element passed in >+ * Constructs an instance of this class based on the configuration element >+ * passed in > * >- * @param confiugrationElement The configuration element to be loaded >- * @return An instance of this class based on the configuration element passed in. >- * null will be returned if there is an error loading the configuration element. >- */ >- public static WidgetResolverLoader constructInstance(IConfigurationElement configuraitonElement) >- { >- if (!"widgetResolver".equals(configuraitonElement.getName())) >+ * @param confiugrationElement >+ * The configuration element to be loaded >+ * @return An instance of this class based on the configuration element >+ * passed in. null will be returned if there is an error loading the >+ * configuration element. >+ */ >+ public static WidgetResolverLoader constructInstance( >+ IConfigurationElement configuraitonElement) { >+ if (!EXTENSION_POINT.equals(configuraitonElement.getName())) > return null; >- >- try >- { >+ >+ try { > String id = configuraitonElement.getAttribute("id"); >- IWidgetResolver widgetResolver = (IWidgetResolver) configuraitonElement.createExecutableExtension("class"); >- int priority = Integer.parseInt(configuraitonElement.getAttribute("priority")); >- >+ IWidgetResolver widgetResolver = (IWidgetResolver) configuraitonElement >+ .createExecutableExtension("class"); >+ int priority = Integer.parseInt(configuraitonElement >+ .getAttribute("priority")); >+ > if (id == null || widgetResolver == null) > return null; >- >- return new WidgetResolverLoader (id, widgetResolver, priority); > >+ return new WidgetResolverLoader(id, widgetResolver, priority); >+ >+ } catch (CoreException e) { > } >- catch (CoreException e) >- { >- } >- >+ > return null; > } > >- > /** > * @return the id > */ >@@ -82,7 +95,6 @@ > return id; > } > >- > /** > * @return the priority > */ >@@ -90,13 +102,83 @@ > return priority; > } > >- > /** > * @return the widgetResolver > */ > public IWidgetResolver getWidgetResolver() { > return widgetResolver; > } >- > >+ public static WidgetResolverLoader[] getWidgetResolverLoaders() { >+ if (resolverIds == null) { >+ loadWidgetResolvers(); >+ } >+ >+ WidgetResolverLoader[] resolvers = new WidgetResolverLoader[resolverIds.length]; >+ for (int i = 0; i < resolverIds.length; i++) { >+ resolvers[i] = ((WidgetResolverLoader) widgetResolvers >+ .get(resolverIds[i])); >+ } >+ return resolvers; >+ } >+ >+ private static void loadWidgetResolvers() { >+ IConfigurationElement[] elements = Platform.getExtensionRegistry() >+ .getConfigurationElementsFor( >+ "org.eclipse.tptp.test.auto.gui.widgetResolver"); >+ Vector tempContainer = new Vector(elements.length); >+ >+ for (int i = 0; i < elements.length; i++) { >+ WidgetResolverLoader widgetResolverLoader = WidgetResolverLoader >+ .constructInstance(elements[i]); >+ if (widgetResolverLoader != null) { >+ tempContainer.add(findIndex(widgetResolverLoader.getPriority(), >+ tempContainer), widgetResolverLoader); >+ widgetResolvers.put(widgetResolverLoader.getId(), >+ widgetResolverLoader); >+ } >+ } >+ >+ resolverIds = new String[tempContainer.size()]; >+ for (int i = 0; i < resolverIds.length; i++) { >+ resolverIds[i] = ((WidgetResolverLoader) tempContainer.get(i)) >+ .getId(); >+ } >+ } >+ >+ private static int findIndex(int desiredPriority, Vector container, >+ int startIntervalInx, int endIntervalInx, int length) { >+ if (startIntervalInx == endIntervalInx >+ || startIntervalInx == endIntervalInx - 1) { >+ if (length > 0) { >+ WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader) container >+ .get(startIntervalInx); >+ int priority = widgetResolverReg.getPriority(); >+ if (desiredPriority < priority) >+ return startIntervalInx; >+ } >+ return endIntervalInx; >+ } >+ >+ /* What's in the middle? */ >+ int middleInx = startIntervalInx >+ + (int) Math.ceil((endIntervalInx - startIntervalInx) / 2); >+ WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader) container >+ .get(middleInx); >+ int middleElementPriority = widgetResolverReg.getPriority(); >+ >+ if (middleElementPriority > desiredPriority) >+ endIntervalInx = middleInx; >+ else if (middleElementPriority < desiredPriority) >+ startIntervalInx = middleInx; >+ else >+ return middleInx; >+ return findIndex(desiredPriority, container, startIntervalInx, >+ endIntervalInx, length); >+ } >+ >+ private static int findIndex(int priority, Vector container) { >+ int length = container.size(); >+ return findIndex(priority, container, 0, length, length); >+ } > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/VerifHookClassLoader.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/VerifHookClassLoader.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/VerifHookClassLoader.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/VerifHookClassLoader.java 14 Jul 2006 23:17:02 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,104 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2006 IBM Corporation and others. >- * 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 >- * $Id: VerifHookClassLoader.java,v 1.2 2006/07/14 23:17:02 amehregani Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import java.net.URL; >-import java.net.URLClassLoader; >-import java.util.Vector; >- >-import org.eclipse.core.runtime.Platform; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >- >-/** >- * A custom class loader that is used to resolve a class that the verificaiton hook is in along >- * with any other classes that are imported by the verification class. >- * >- * @author Ali Mehregani >- */ >-public class VerifHookClassLoader extends URLClassLoader >-{ >- /* The plugins that the verification plugin requires */ >- private Vector reqPluginNames; >- >- public VerifHookClassLoader (URL[] urls, ClassLoader parent, Vector requiredPluginNames) >- { >- super (urls, parent); >- reqPluginNames = requiredPluginNames; >- } >- >- >- /** >- * Invoked when a class can't be resolved by the upper level class loaders associated with >- * this class. >- */ >- protected Class findClass(final String name) >- throws ClassNotFoundException >- { >- >- /* Try and walk through the required plugins of the plugin >- * containing the test suite */ >- try >- { >- Class classFile = loadFromReqPlugins(name, 0); >- if (classFile != null) >- return classFile; >- } >- catch (Throwable t) >- { >- /* Doesn't need to be handled */ >- } >- >- >- try >- { >- Class classFile = super.findClass(name); >- if (classFile != null) >- return classFile; >- } >- catch (Throwable t) >- { >- /* Doesn't need to be handled */ >- } >- >- >- >- throw new ClassNotFoundException (NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_FS, name)); >- } >- >- >- /** >- * Attempt to load the class from the required plugins. >- * >- * @param name >- * @param inx >- * @return >- */ >- private Class loadFromReqPlugins(String name, int inx) >- { >- try >- { >- if (reqPluginNames == null || inx >= reqPluginNames.size()) >- return null; >- >- Class classFile = Platform.getBundle(((String)reqPluginNames.get(inx))).loadClass(name); >- if (classFile != null) >- return classFile; >- } >- catch (Throwable t) >- { >- /* Handled by next statement */ >- } >- >- return loadFromReqPlugins(name, inx + 1); >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IPlayable.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IPlayable.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IPlayable.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IPlayable.java 27 Oct 2006 14:39:10 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,20 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import org.eclipse.core.runtime.*; >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.swt.widgets.*; >-import org.eclipse.swt.widgets.Composite; >- >-public interface IPlayable { >- boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException; >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetIdentifier.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetIdentifier.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,177 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.Path; >- >- >-/** >- * Used as an identifier for widgets. At a minimum, a context id and a widget id >- * is required as part of a widget identifier. >- * >- * @author Ali Mehregani >- */ >-public class WidgetIdentifier >-{ >- /** A null identifier */ >- public static final WidgetIdentifier NULL_IDENTIFIER = new WidgetIdentifier(new Path(""), new Path(""), null); >- >- /** The context id */ >- private IPath contextId; >- >- /** The widget id */ >- private IPath objectId; >- >- /** The id that is used to reference this widget in the object mine */ >- private String referenceId; >- >- /** The resolver id that resovled this widget */ >- private String resolverId; >- >- >- /** >- * Constructor >- * >- * @param contextId The context id >- * @param widgetId The widget id >- */ >- public WidgetIdentifier(IPath contextId, IPath widgetId, String resolverId) >- { >- this.contextId = contextId; >- this.objectId = widgetId; >- this.resolverId = resolverId; >- } >- >- >- /** >- * Returns the fully qualified path of this widget id. The fully qualified >- * path is the context id/path appended with the widget path/id. >- * >- * @return The fully qualified path of this identifier. >- */ >- public IPath getFullyQualifiedPath() >- { >- return contextId.append(objectId); >- } >- >- >- /** >- * Equivalent to getFullyQualifiedPath().toString(). >- * >- * @return The fully qualified id >- */ >- public String getFullyQualifiedId() >- { >- return getFullyQualifiedPath().toString(); >- } >- >- >- /** >- * An object in question is equalled to this object iff the object is of the same type and >- * the context and the widget ids are the same. >- * >- * @param object The object in question >- * >- * @return A boolean indicating whether object is equalled to this object or not. >- */ >- public boolean equals(Object object) >- { >- if (object == null) >- return false; >- if (object == this) >- return true; >- if (object instanceof WidgetIdentifier) >- { >- WidgetIdentifier wid = (WidgetIdentifier) object; >- return wid.contextId.equals(contextId) && wid.objectId.equals(objectId); >- } >- return false; >- } >- >- >- /** >- * Returns the context id of this identifier >- * >- * @return The context id >- */ >- public IPath getContextId() >- { >- return contextId; >- } >- >- >- >- /** >- * @param contextId the contextId to set >- */ >- public void setContextId(IPath contextId) >- { >- this.contextId = contextId; >- } >- >- >- /** >- * Returns the widget id of this identifier >- * >- * @return The widget id >- */ >- public IPath getObjectId() >- { >- return objectId; >- } >- >- >- /** >- * @param objectId the objectId to set >- */ >- public void setObjectId(IPath objectId) >- { >- this.objectId = objectId; >- } >- >- >- /** >- * @return the referenceId >- */ >- public String getReferenceId() >- { >- return referenceId; >- } >- >- >- /** >- * @param referenceId the referenceId to set >- */ >- public void setReferenceId(String referenceId) >- { >- this.referenceId = referenceId; >- } >- >- >- /** >- * @return the resolverId >- */ >- public String getResolverId() >- { >- return resolverId; >- } >- >- >- /** >- * @param resolverId the resolverId to set >- */ >- public void setResolverId(String resolverId) >- { >- this.resolverId = resolverId; >- } >- >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IObjectMine.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IObjectMine.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IObjectMine.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IObjectMine.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,244 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import java.util.List; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound; >-import org.w3c.dom.Node; >- >- >-/** >- * Represents an object mine that belongs to a particular test suite. The mine >- * keeps track of the objects that the test cases depends on. Object mines >- * can be shared among multiple test suites, allowing users to centralize the objects >- * identified by test cases spanning multiple test suites. The output source of an object >- * mine can be different from the test suite that owns the mine. >- * >- * <p> >- * The inclusion and output source options introduce some ambiguities in registering a new >- * object with an object mine. The general contract when registering a new object is outlined below. >- * </p> >- * >- * <p> >- * Assume object mine om1 includes om2 and outputs to om3: >- * </p> >- * >- * <ul> >- * <li> If object o is infant, then it is registered with om3 </li> >- * <li> If object o has a parent that belongs to om1, then it is registered with om1 </li> >- * <li> If object o has a parent that belongs to om2, then it is registered with om2 </li> >- * <li> If object o has a parent that belongs to om3, then it is registered with om3 </li> >- * </ul> >- * >- * Changing the output source of an object mine to an alternative test suite does not guarantee >- * that new objects will be written to the set test suite's object mine. >- * >- * @author Ali Mehregani >- */ >-public interface IObjectMine >-{ >- >- /** >- * The test suite that owns this object mine. The owner and the output source >- * can be different. >- * >- * @return The owner >- */ >- public ITestSuite getOwner(); >- >- >- /** >- * Sets the owner of this test suite. The owner and the output source >- * can be different. >- * >- * @param testSuite The owner >- */ >- public void setOwner(ITestSuite testSuite); >- >- >- /** >- * Set the output source to the object mine that is passed in. If >- * the user uses the test suite that is the owner of this mine to >- * record a test case that results in finding a new object, then the >- * object will be contributed to the object mine of the output source, not >- * the owner of this object mine (some exceptions apply - see class comment). >- * >- * @param objectMine The object mine that will act as the output source >- * for this mine >- */ >- public void setOutputSource(IObjectMine objectMine); >- >- >- /** >- * Returns the output of this object mine >- * >- * @return The output source >- */ >- public IObjectMine getOutputSource(); >- >- >- /** >- * Includes another object mine as part of this mine. The lookup method for >- * an object is required to walk through the registered objects of this object >- * mine and the registered objects of included object mines. >- * >- * @param objectMine The object mine to include >- */ >- public void addInclude(IObjectMine objectMine); >- >- >- /** >- * Returns the external object mines that have been added to this >- * object mine >- * >- * @return The added external object mines >- */ >- public List getIncludes(); >- >- >- /** >- * Looks up the UI object with the reference id passed in. null should be >- * returned if the objct can't be found. Time complexity = T(h) = h (where h is the height of the >- * object mine tree) >- * >- * @param parent The parent of the object >- * @param referenceId The reference id of the object >- * >- * @return The object with the reference id passed in; or null if none is found. >- * >- * @throws UIObjectNotFound If the parent object is not found >- */ >- public IUIObject lookupUIObject(IUIObject parent, String referenceId); >- >- >- /** >- * Looks up the UI object based on the context id and the object id that is passed in. This >- * lookup operation is more expensive than lookup(parent, referenceId). The latter should be >- * used where possible. Time complexity = T(h, n) = h + n (where h is the height of the >- * object mine tree and n is the number of nodes owned by the parent node) >- * >- * @param parent The parent of the object >- * @param contextId The context id of the object >- * @param objectId The object id of the object >- * >- * @return The object with the matching context and object id; or null if none is found. >- * >- * @throws UIObjectNotFound If the parent object is not found >- */ >- public IUIObject lookupUIObject(IUIObject parent, String contextId, String objectId); >- >- >- /** >- * Returns the direct children of the root object that this object mine points to >- * >- * @return The children of the root object >- */ >- public IUIObject[] getChildren(); >- >- >- /** >- * Register the object embedded in the node passed in. The parent of the >- * registered object should be set to the parent argument. If the object is already >- * registered, then this method will not have any effects. >- * >- * @param parent The parent of the object to be registered >- * @param node The node containing the object information to be registered >- * >- * @return The object that gets registered. >- * >- * @throws IDCollisionException If there is a reference id collision >- * @throws UIObjectNotFound If the parent object is not found >- * @throws CoreException Wraps any unexpected error >- */ >- public IUIObject registerObject(IUIObject parent, Node currentNode) throws IDCollisionException, UIObjectNotFound, CoreException; >- >- >- /** >- * Registers uiObject under the parent object passed in. If the object is already >- * registered, then this method will not have any effects. >- * >- * @param uiObject The object to be registered >- * @return The object that gets registered (i.e. uiObject). >- * >- * @throws IDCollisionException If there is a reference id collision >- * @throws UIObjectNotFound If the parent object of uiObject is not found >- * @throws CoreException Wraps any unexpected error >- */ >- public IUIObject registerObject(IUIObject uiObject) throws IDCollisionException, UIObjectNotFound, CoreException; >- >- >- /** >- * Serializes this object mine to a string representation that can be stored >- * and retrieved for later use. This is often the result of <code>serializeHeaderToString()</code> >- * appended to the result of <code>serializeObjetsToString()</code>. >- * >- * @return The string representation of this object mine >- */ >- public String serializeToString(); >- >- >- /** >- * Serializes only the header of this object mine to a string representation that >- * can be stored and retrieved for later use. >- * >- * @return The string representation of the header of this object mine >- */ >- public String serializeHeaderToString(); >- >- >- /** >- * Serializes only the objects of this object mine to a string representation that >- * can be stored and retrieved for later use. >- * >- * @return The string representation of the object directly owned by this object mine >- */ >- public String serializeObjetsToString(); >- >- >- /** >- * Sets the active object of this object mine. This is commonly used to determine the active >- * object corresponding to the active shell. >- * >- * @param activeObject The active object. >- */ >- public void setActiveObject(IUIObject activeObject); >- >- >- /** >- * Returns the active object of this object mine. This is commonly used to determine the active >- * object corresponding to the active shell. >- * >- * @return The active object. >- */ >- public IUIObject getActiveObject(); >- >- >- /** >- * Returns the next available unique reference id that can be used. The id's returned will be an >- * integer even though the type is set to String. >- * >- * @return The next available reference id. >- */ >- public String getUniqueReferenceId(); >- >- >- /** >- * Returns the roo object >- * >- * @return The root object >- */ >- public IUIObject getRoot(); >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IUIObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IUIObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IUIObject.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IUIObject.java 10 Jul 2006 14:49:03 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,226 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-import java.util.LinkedList; >-import java.util.Map; >- >-import org.eclipse.core.runtime.CoreException; >- >- >-/** >- * Represents a UI object such as a widget. >- * >- * @author Ali Mehregani >- */ >-public interface IUIObject >-{ >- /** >- * Returns the hierarchical relationshipt of this object relative to its parents. >- * A linked list is returned whose first element is the child of the root UI object node and >- * its last node is this UI object. An object directly above a node is the parent of that >- * node. >- * >- * @return A linked list indicating the hierarchical relationship between this node and >- * its parents. >- */ >- public LinkedList getHierarchicalRelation(); >- >- >- /** >- * Set the reference id of this object. >- * >- * @param referenceId The reference id >- */ >- public void setReferenceId(String referenceId); >- >- >- /** >- * Return the reference id of this object >- * >- * @return reference id >- */ >- public String getReferenceId(); >- >- >- /** >- * Sets the context id of this object >- * >- * @param contextId The context id of this object >- */ >- public void setContextId(String contextId); >- >- >- /** >- * Returns the context id of this object >- * >- * @return The context id >- */ >- public String getContextId(); >- >- >- /** >- * Sets the id of this object. This is the id used by the playback operations to >- * identify the UI object. >- * >- * @param id The id of this UI object >- */ >- public void setObjectId(String objectId); >- >- >- /** >- * Returns the id of this object. This is the id used by the playback operations to >- * identify the UI object. >- * >- * @return object id >- */ >- public String getObjectId(); >- >- >- /** >- * Returns the descriptive field of this object. The descriptive field is human readable >- * label that is used to easily recognize the object. >- * >- * @param descriptive field >- */ >- public void setDescriptive(String descriptive); >- >- >- /** >- * Returns the descriptive field of this object. The descriptive field is human readable >- * label that is used to easily recognize the object. >- * >- * @return descriptive field >- */ >- public String getDescriptive(); >- >- >- /** >- * Add a property to this UI object. >- * >- * @param name The name of the property >- * @param value The value of the property >- */ >- public void addProperty (String name, String value); >- >- >- /** >- * Returns the property of this object >- * >- * @param name The name of the property. >- * @return The value of the property with the name passed in. null is returned if the >- * property can't be found. >- */ >- public String getProperty (String name); >- >- >- /** >- * Returns the properties of this UI object. >- * >- * @return The properties of this UI object >- */ >- public Map getProperties (); >- >- >- /** >- * Set the parent of this UI object >- * >- * @param parent The parent >- */ >- public void setParent(IUIObject parent); >- >- >- /** >- * Returns the parent of this UI object >- * >- * @return The parent >- */ >- public IUIObject getParent(); >- >- >- /** >- * Sets the resolver id for this object. >- * >- * @param resolverId The resolver id. >- */ >- public void setResolver(String resolverId); >- >- >- /** >- * Returns the resolver id that has resolved this object >- * >- * @return A resolver id >- */ >- public String getResolverId(); >- >- >- /** >- * Returns the number of children that this UI object has >- * >- * @return the number of children of this object >- */ >- public int childCount(); >- >- >- /** >- * Returns the children of this UI object >- * >- * @return The children of this UI object >- */ >- public IUIObject[] getChildren(); >- >- >- /** >- * Adds a child to this object. Has no effects if child is already >- * part of this object's children >- * >- * @param child The child to add >- * @throws CoreException In case of any unexpected error >- */ >- public void addChild(IUIObject child) throws CoreException; >- >- >- /** >- * Removes a child from this object >- * >- * @param child The child to remove >- * @return The child removed >- */ >- public IUIObject removeChild(IUIObject child); >- >- >- /** >- * Returns the data associated with this object. >- * >- * @return The associated data >- */ >- public Object getData(); >- >- >- /** >- * Can be used to associate a general data object with this object. >- * >- * @param data The data >- */ >- public void setData(Object data); >- >- >- /** >- * Returns the child with a matching reference id passed in; null if none is found >- * >- * @param referenceId The reference id of the child >- * @return A IUIObject with a matching referenceId or null if none is found. >- */ >- public IUIObject findChild(String referenceId); >- >-} >- >- >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/VerificationMetaData.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/VerificationMetaData.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/VerificationMetaData.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/VerificationMetaData.java 27 Oct 2006 14:39:10 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,103 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2006 IBM Corporation and others. >- * 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 >- * $Id: VerificationMetaData.java,v 1.2 2006/10/27 14:39:10 amehregani Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >- >-/** >- * A container class for the data that the verificaiton command will need >- * >- * @author Ali Mehregani >- */ >-public class VerificationMetaData >-{ >- /* The possible types */ >- public static final byte EDITOR = 0x01; >- public static final byte VIEW = 0x02; >- public static final byte SHELL = 0x03; >- >- >- /* The context id is the id of the editor, viewer, etc... that will be used to retrieve it */ >- private String contextId; >- >- /* The location is the plugin that contains the hook source code */ >- private String location; >- >- /* The resource is the class name containing the hook */ >- private String resource; >- >- /* The hook is the method name representing the verification point */ >- private String hook; >- >- /* The focus type indicates whether the type of context being retrieved */ >- private byte focusType; >- >- public VerificationMetaData() >- { >- focusType = -1; >- } >- >- public String getContextId() >- { >- return contextId; >- } >- >- public void setContextId(String contextId) >- { >- this.contextId = contextId; >- } >- >- public byte getFocusType() >- { >- return focusType; >- } >- >- public void setFocusType(byte focusType) >- { >- this.focusType = focusType; >- } >- >- public String getHook() >- { >- return hook; >- } >- >- public void setHook(String hook) >- { >- this.hook = hook; >- } >- >- public String getLocation() >- { >- return location; >- } >- >- public void setLocation(String location) >- { >- this.location = location; >- } >- >- public String getResource() >- { >- return resource; >- } >- >- public void setResource(String resource) >- { >- this.resource = resource; >- } >- >- public boolean isComplete() >- { >- return contextId != null && location != null && resource != null && hook != null && focusType != -1; >- } >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IRecorderListener.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IRecorderListener.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IRecorderListener.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IRecorderListener.java 27 Oct 2006 14:39:10 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,26 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >-public interface IRecorderListener { >- int STOP = 1; >- int INDEX = 2; >- void recordingStarted(); >- void recordingStopped(); >-/** >- * Called when the user pressed Ctrl+Shift+F10 (index) >- * or Ctrl+Shift+F11 (stop) to interrupt >- * the recording process. Clients may use this event >- * to insert named indexes, stop the recording etc. >- * @param type <code>STOP</code> or <code>INDEX</code> >- */ >- void recordingInterrupted(int type); >-} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/IWritable.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/IWritable.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/IWritable.java >--- src/org/eclipse/tptp/test/auto/gui/internal/core/IWritable.java 27 Oct 2006 14:39:08 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,53 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2000, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.core; >- >- >-/** >- * A writable object is capable of serializing itself to string and writing the string >- * version to a PrintWriter that is passed to parameters to the methods that are described >- * below. >- * <br/> >- * The ideal order of the method invocations are: >- * <ul> >- * <li> writeStart(String indent, gPrintWriter writer) </li> >- * <li> write(String indent, PrintWriter writer) </li> >- * <li> writeFinish(String indent, PrintWriter writer) </li> >- * </ul> >- */ >-public interface IWritable >-{ >- /** >- * Invoked at start of the write of a writable object >- * >- * @param indent The indents >- * @param sb The buffer that the string serialization should be written to >- */ >- public void writeStart(int indent, StringBuffer sb); >- >- >- /** >- * Invoked after writeStart >- * >- * @param indent The indents >- * @param sb The buffer that the string serialization should be written to >- */ >- public void write(int indent, StringBuffer sb); >- >- >- /** >- * Invoked in the end of the write of a writable object >- * >- * @param indent The indents >- * @param sb The buffer that the string serialization should be written to >- */ >- public void writeFinish(int indent, StringBuffer sb); >-} >Index: plugin.properties >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/plugin.properties,v >retrieving revision 1.11 >diff -u -r1.11 plugin.properties >--- plugin.properties 16 Apr 2008 14:58:24 -0000 1.11 >+++ plugin.properties 26 Jul 2008 19:21:47 -0000 >@@ -27,4 +27,6 @@ > TST_SUITE_AUTO_GUI_DESC = Use this suite to create Automated GUI test cases in the Eclipse platform > TST_CASE_AUTO_GUI_NAME = TPTP Automated GUI Test Case > TST_CASE_AUTO_GUI_DESC = Test Case which can store events recorded on the UI and be used to play them back >-widgetResolver = Widget Resolver Extension >\ No newline at end of file >+widgetResolver = Widget Resolver Extension (Deprecated) >+uiObjectResolverDelegate = UI Object Resolver Delegate Extension >+macroCommandFactory = MacroCommandFactory Replacement Extension >\ No newline at end of file >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/plugin.xml,v >retrieving revision 1.14 >diff -u -r1.14 plugin.xml >--- plugin.xml 14 Jan 2008 11:59:19 -0000 1.14 >+++ plugin.xml 26 Jul 2008 19:21:47 -0000 >@@ -14,6 +14,8 @@ > --> > <?eclipse version="3.0"?> > <plugin> >+ <extension-point id="uiObjectResolverDelegate" name="%uiObjectResolverDelegate" schema="schema/uiObjectResolverDelegate.exsd"/> >+ <extension-point id="macroCommandFactory" name="%macroCommandFactory" schema="schema/macroCommandFactory.exsd"/> > <extension-point id="widgetResolver" name="%widgetResolver" schema="schema/widgetResolver.exsd"/> > <extension > point="org.eclipse.hyades.ui.typeDescriptions"> >@@ -93,26 +95,26 @@ > </extension> > > >- <!-- The widget resolvers --> >+ <!-- ANy: Migrated extension point to new UI object resolver delegate interface --> >+ <!-- The UI object resolvers --> > <extension >- point="org.eclipse.tptp.test.auto.gui.widgetResolver"> >+ point="org.eclipse.tptp.test.auto.gui.uiObjectResolverDelegate">--> > > <!-- The adaptive widget resolver --> >- <widgetResolver >+ <uiObjectResolverDelegate > id = "org.eclipse.tptp.test.auto.gui.adaptive" >- class="org.eclipse.tptp.test.auto.gui.internal.resolvers.AdaptiveWidgetResolver" >+ class="org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.AdaptiveUIObjectResolverDelegate" > priority="10" > /> > > <!-- Non trivial widget resolver. Use this if adaptive widget resolver can't be used --> > <!-- (e.g. Nested calls are required) --> >- <widgetResolver >+ <uiObjectResolverDelegate > id = "org.eclipse.tptp.test.auto.gui.nontrivial" >- class="org.eclipse.tptp.test.auto.gui.internal.resolvers.NonTrivialWidgetResolver" >+ class="org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate" > priority="11" >- /> >- >- </extension> >+ /> >+ </extension> > > > <!-- Make the test type launchable --> >@@ -256,4 +258,13 @@ > </verdictProvider> > </extension> > >+ <extension >+ point="org.eclipse.tptp.test.auto.gui.macroCommandFactory"> >+ <macroCommandFactory >+ id="org.eclipse.tptp.test.auto.gui.macroCommandFactory" >+ class="org.eclipse.tptp.test.auto.gui.internal.commands.factory.MacroCommandFactory" >+ priority="10"> >+ </macroCommandFactory> >+ </extension> >+ > </plugin> >Index: .project >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/.project,v >retrieving revision 1.1 >diff -u -r1.1 .project >--- .project 19 Aug 2005 21:40:03 -0000 1.1 >+++ .project 26 Jul 2008 19:21:47 -0000 >@@ -1,6 +1,6 @@ > <?xml version="1.0" encoding="UTF-8"?> > <projectDescription> >- <name>org.eclipse.tptp.test.auto.gui</name> >+ <name>Copy of org.eclipse.tptp.test.auto.gui</name> > <comment></comment> > <projects> > </projects> >Index: src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIRecordAction.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIRecordAction.java,v >retrieving revision 1.9 >diff -u -r1.9 AutoGUIRecordAction.java >--- src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIRecordAction.java 5 Mar 2008 18:27:00 -0000 1.9 >+++ src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIRecordAction.java 26 Jul 2008 19:21:53 -0000 >@@ -31,7 +31,6 @@ > import org.eclipse.tptp.test.auto.gui.internal.codegen.AutoGUIGenerator; > import org.eclipse.tptp.test.auto.gui.internal.codegen.CodeGeneratorHelper; > import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand; >-import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData; > import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUIInputCollectorDialog; > import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog; > import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog.AutoGUIControllerListener; >@@ -39,11 +38,10 @@ > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties; > import org.eclipse.tptp.test.auto.gui.internal.macro.Macro; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager; >+import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.GlobalStateListener; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.VerificationHookListener; >-import org.eclipse.ui.IEditorPart; >-import org.eclipse.ui.IViewPart; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; > import org.eclipse.ui.IWorkbench; > import org.eclipse.ui.IWorkbenchWindow; > import org.eclipse.ui.WorkbenchException; >@@ -54,467 +52,465 @@ > * > * @author Ali Mehregani > * @author Paul E. Slauenwhite >+ * @author Alexander Nyssen > * @version March 5, 2008 > * @since March 17, 2006 > */ >-public class AutoGUIRecordAction extends AddTestCase implements AutoGUIControllerListener >-{ >- >+public class AutoGUIRecordAction extends AddTestCase implements AutoGUIControllerListener { >+ > /* The test suite provider */ > private IITestSuiteProvider suiteProvider; >- >+ > /* The perspective the user was in before adding a test case */ > private String perspectiveId; >- >+ > /* Control center dialog */ > private AutoGUITestControllerDialog controllerDialog; >- >+ > /* A global state listener */ > private CustomGlobalStateListener globalStateListener; >- >+ > /* Start record dialog */ > private AutoGUIInputCollectorDialog inputCollectorDialog; >- >+ > /* Stores the user input collected from the input dialog */ > private AutoGUIInputCollectorDialog.AutoGUIInputContainer userInput; > > /* The test suite provider */ > private IITestSuiteProvider testSuiteProvider; >- >+ > /** > * The constructor > * >- * @param testSuiteProvider The test suite provider used to get the test suite associated with this action >- * @param baseName The base name of the test case >+ * @param testSuiteProvider >+ * The test suite provider used to get the test suite associated with this action >+ * @param baseName >+ * The base name of the test case > */ >- public AutoGUIRecordAction(IITestSuiteProvider testSuiteProvider, String baseName) >- { >- super(testSuiteProvider, GuiPlugin.getTestSuiteType(), baseName); >+ public AutoGUIRecordAction(IITestSuiteProvider testSuiteProvider, String baseName) { >+ super(testSuiteProvider, >+ GuiPlugin.getTestSuiteType(), >+ baseName); > this.suiteProvider = testSuiteProvider; > this.testSuiteProvider = testSuiteProvider; > setToolTipText(AutoGUIMessages.TST_SUITE_AUTO_MACRO_RECORD); >- setImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.RECORD)); >- >+ setImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("e", >+ AutoGUIImages.RECORD)); >+ > IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); > IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); > Shell activeShell = activeWorkbenchWindow.getShell(); >- inputCollectorDialog = new AutoGUIInputCollectorDialog (activeShell); >+ inputCollectorDialog = new AutoGUIInputCollectorDialog(activeShell); > } >- >- >+ > /** > * Invoked when this action is create > */ >- public void run() >- { >- setActionPerformed(false); >+ public void run() { >+ setActionPerformed(false); > IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); > IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow(); > Shell activeShell = activeWorkbenchWindow.getShell(); > userInput = inputCollectorDialog.openDialog(); >- >- >+ > /* We don't need to do anything if cancel is pressed */ >- if (userInput == null || !userInput.isOkPressed()) >- { >- setActionPerformed (true); >+ if (userInput == null || !userInput.isOkPressed()) { >+ setActionPerformed(true); > return; > } >- >- /* Otherwise, we'll need to add the test case. Here are the phases: >- * - Switch to the perspective that corresponds to the starting point of the test case >- * - Display the control center dialog box >- * - Begin recording user actions */ >- userInput.setDescription(userInput.getDescription() == null ? "" : userInput.getDescription()); >- >- /* Switch the perspecitve */ >- try >- { >+ >+ /* >+ * Otherwise, we'll need to add the test case. Here are the phases: - Switch to the perspective that corresponds to the starting point of the >+ * test case - Display the control center dialog box - Begin recording user actions >+ */ >+ userInput.setDescription(userInput.getDescription() == null >+ ? "" >+ : userInput.getDescription()); >+ >+ /* Switch the perspecitve */ >+ try { > /* Store the perspective that we're in before switching it */ > perspectiveId = activeWorkbenchWindow.getActivePage().getPerspective().getId(); >- workbench.showPerspective(userInput.getStartingPoint(), activeWorkbenchWindow); >- } catch (WorkbenchException e) >- { >- /* Something wrong happened while chaning the perspective. Show an error */ >+ workbench.showPerspective(userInput.getStartingPoint(), >+ activeWorkbenchWindow); >+ } >+ catch (WorkbenchException e) { >+ /* Something wrong happened while chaning the perspective. Show an error */ > String[] errorArgs = {userInput.getStartingPoint(), e.getMessage()}; >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, errorArgs), >- e); >+ AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE, >+ NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, >+ errorArgs), >+ e); > } >- >+ > /* Display the control center dialog box asynchronously */ > controllerDialog = new AutoGUITestControllerDialog(activeShell); > controllerDialog.registerListener(this); >- controllerDialog.openDialog(); >- >+ controllerDialog.openDialog(); >+ > MacroManager macroManagerInstance = MacroManager.getInstance(); > globalStateListener = new CustomGlobalStateListener(false); > macroManagerInstance.registerGlobalStateListener(globalStateListener); >- macroManagerInstance.setGlobalState(MacroManager.RECORDING_MODE); >+ macroManagerInstance.setGlobalState(ModeConstants.RECORDING_MODE); > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); > > startRecording(userInput.isObjectMineOn()); > setActionPerformed(true); > } >- >- >- private void startRecording(boolean isObjectMineOn) >- { >- /* The control center is now open. Start recording the user's actions */ >- try >- { >- MacroManager.getInstance().startRecording(suiteProvider.getTestSuite(), isObjectMineOn); >- } >- catch (Exception e) >- { >- MacroManager.getInstance().setObjectMine(null);; >- if (controllerDialog != null) >- { >+ >+ private void startRecording(boolean isObjectMineOn) { >+ /* The control center is now open. Start recording the user's actions */ >+ try { >+ MacroManager.getInstance().startRecording(suiteProvider.getTestSuite(), >+ isObjectMineOn); >+ } >+ catch (Exception e) { >+ MacroManager.getInstance().setObjectMine(null); >+ ; >+ if (controllerDialog != null) { > controllerDialog.terminate(); > } >- >- AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC_TITLE, AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, e); >- } >- } >- >- >- protected void adjusTestCase(ITestCase testCase) >- { >+ >+ AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC_TITLE, >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, >+ e); >+ } > } > >+ protected void adjusTestCase(ITestCase testCase) { >+ } > >- public void handleEvent(byte event, Object value) >- { >+ public void handleEvent(byte event, Object value) { > MacroManager macroManager = MacroManager.getInstance(); >- >- switch (event) >- { >- /* When user terminates, we have to take the macro and transfer it to the test suite. >- * We'll also need to reset the perspective back to what it was */ >- case AutoGUITestControllerDialog.TERMINATE: >- try >- { >+ >+ switch (event) { >+ /* >+ * When user terminates, we have to take the macro and transfer it to the test suite. We'll also need to reset the perspective back to >+ * what it was >+ */ >+ case AutoGUITestControllerDialog.TERMINATE: >+ try { > /* Stop the macro */ > Macro macro = macroManager.stopRecording(false); >- >+ > /* Something went wrong in the macro manager */ >- if (macro == null) >- { >+ if (macro == null) { > /* Display error message and switch to the original perspective of the user */ >- IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); >+ IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); > MessageDialog.openError(workbench.getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE_T, >- AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE); >- >- try >- { >- workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow()); >- } >- catch (WorkbenchException e) >- { >- /* Not a huge deal if we can't restore the perspective */ >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE); >+ >+ try { >+ workbench.showPerspective(perspectiveId, >+ workbench.getActiveWorkbenchWindow()); >+ } >+ catch (WorkbenchException e) { >+ /* Not a huge deal if we can't restore the perspective */ > } >- >- return; >+ >+ return; > } >- >- >+ > StringWriter swriter = null; >- try >- { >+ try { > swriter = new StringWriter(); > PrintWriter pwriter = new PrintWriter(swriter); >- macro.write(0, pwriter); >+ macro.write(0, >+ pwriter); > pwriter.close(); > swriter.close(); > } >- catch (Exception e) >- { >+ catch (Exception e) { > String messageWithOrigin = AutoGUIUtil.getOriginOfException(e); > String cause = messageWithOrigin + "\n" + AutoGUIUtil.getExceptionStackTrace(e); >- AutoGUIUtil.openErrorWithDetail( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP_TITLE, >- AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP, >- cause); >- >+ AutoGUIUtil.openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP_TITLE, >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP, >+ cause); >+ > return; > } >- >+ > /* Create the test case and add the required properties */ > ITestSuite testSuite = getTestSuite(); > boolean isExternalBehavior = testSuite.getImplementor().isExternalImplementor(); >- ITestCase testcase = TestCommonUtil.createTestCase(testSuite, getType(), isExternalBehavior, userInput.getName()); >+ ITestCase testcase = TestCommonUtil.createTestCase(testSuite, >+ getType(), >+ isExternalBehavior, >+ userInput.getName()); > testcase.setDescription(userInput.getDescription()); >- >+ > /* Add the starting point */ >- ((AutoGUITestCasesForm)suiteProvider).addProperty(testcase, GUITestCaseProperties.STARTING_PT, userInput.getStartingPoint()); >- >+ ((AutoGUITestCasesForm) suiteProvider).addProperty(testcase, >+ GUITestCaseProperties.STARTING_PT, >+ userInput.getStartingPoint()); >+ > /* Add the macro */ > String contents = swriter.toString(); >- >+ > /* Get rid of the last line break */ > int lastLineBreak = contents.lastIndexOf(GlobalConstants.LINE_SEPARATOR); > if (lastLineBreak != -1 && contents.substring(lastLineBreak).trim().length() <= 0) >- contents = contents.substring(0, lastLineBreak); >- >- ((AutoGUITestCasesForm)suiteProvider).addProperty(testcase, GUITestCaseProperties.MACRO_FRAGMENT, contents); >- >+ contents = contents.substring(0, >+ lastLineBreak); >+ >+ ((AutoGUITestCasesForm) suiteProvider).addProperty(testcase, >+ GUITestCaseProperties.MACRO_FRAGMENT, >+ contents); >+ > /* Switch the perspective to where we were before */ >- try >- { >+ try { > IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); >- workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow()); >- } >- catch (WorkbenchException e) >- { >- /* Not a huge deal if we can't restore the perspective */ >+ workbench.showPerspective(perspectiveId, >+ workbench.getActiveWorkbenchWindow()); > } >- >+ catch (WorkbenchException e) { >+ /* Not a huge deal if we can't restore the perspective */ >+ } >+ > adjusTestCase(testcase); >- >+ > /* Cause a selection event */ >- if (testSuiteProvider instanceof AutoGUITestCasesForm) >- { >- AutoGUITestCasesForm testCaseForm = (AutoGUITestCasesForm)testSuiteProvider; >+ if (testSuiteProvider instanceof AutoGUITestCasesForm) { >+ AutoGUITestCasesForm testCaseForm = (AutoGUITestCasesForm) testSuiteProvider; > testCaseForm.getLogicalRepresentationListener().selectionChanged(null); > testCaseForm.getLogicalTreeRepresentaion().selectionChanged(null); > testCaseForm.getObjectMineTreeStruct().refresh(); > } > } >- catch (Throwable t) >- { >+ catch (Throwable t) { > t.printStackTrace(); > } >- >+ > break; >- >+ > /* A verificaiton point is inserted */ >- case AutoGUITestControllerDialog.VERIFICATION_HOOK_INSERT: >- >+ case AutoGUITestControllerDialog.VERIFICATION_HOOK_INSERT: >+ > /* Make sure the verification hook name conforms to the standard defined */ > String hookName = (String) value; >- boolean validName = hookName != null && !hookName.equals("") && hookName.length() < 100 && !containSpecialChars (hookName); >- if (!validName) >- { >+ boolean validName = hookName != null && !hookName.equals("") && hookName.length() < 100 && !containSpecialChars(hookName); >+ if (!validName) { > /* display an error */ >- macroManager.setGlobalState(MacroManager.SUSPEND_MODE); >- >- AutoGUIUtil.openErrorWithDetail( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM_T, >- AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM, >- (String)null >- ); >- >- macroManager.setGlobalState(MacroManager.RECORDING_MODE); >+ macroManager.setGlobalState(ModeConstants.SUSPEND_MODE); >+ >+ AutoGUIUtil.openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM, >+ (String) null); >+ >+ macroManager.setGlobalState(ModeConstants.RECORDING_MODE); > return; > } >- > >- macroManager.setGlobalState(MacroManager.SUSPEND_MODE); >+ macroManager.setGlobalState(ModeConstants.SUSPEND_MODE); > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_GEN); >- >- AutoGUIGenerator generator = new AutoGUIGenerator (((AutoGUITestCasesForm)suiteProvider).getTestSuite(), CodeGeneratorHelper.AUTO_GUI_VERIFICATION_HOOK_CLASS); >- try >- { >+ >+ AutoGUIGenerator generator = >+ new AutoGUIGenerator(((AutoGUITestCasesForm) suiteProvider).getTestSuite(), CodeGeneratorHelper.AUTO_GUI_VERIFICATION_HOOK_CLASS); >+ try { > generator.createChange(new NullProgressMonitor()).perform(new NullProgressMonitor()); >- } >- catch (Exception e) >- { >+ } >+ catch (Exception e) { > /* There was an error in generating the source code */ >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC_T, >- AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC, >- e); >+ AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC, >+ e); > > return; > } >- >- macroManager.setGlobalState(MacroManager.RECORDING_MODE); >+ >+ macroManager.setGlobalState(ModeConstants.RECORDING_MODE); > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); > >- > /* Allow the user to select an editor or a view */ > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_VER); >- macroManager.setVerListener(new CustomVerHookListener(generator, hookName)); >- macroManager.setGlobalState(MacroManager.VERIFICATION_MODE); >- >+ macroManager.setVerListener(new CustomVerHookListener(generator, hookName, controllerDialog.isVerficationScopeExtended())); >+ macroManager.setGlobalState(ModeConstants.VERIFICATION_MODE); >+ > if (globalStateListener != null) > globalStateListener.turnOn(true); >- >+ > break; >- >+ > /* The restart button is pressed */ >- case AutoGUITestControllerDialog.RESTART: >+ case AutoGUITestControllerDialog.RESTART: > /* Restart recording */ > macroManager.stopRecording(true); >- ObjectMineManager.getInstance().clearCache(); >- AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG_T, >- AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG, >- MessageDialog.INFORMATION); >+ MacroObjectDescriptorMineManager.getInstance().clearCache(); >+ AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG_T, >+ AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG, >+ MessageDialog.INFORMATION); > startRecording(MacroManager.getInstance().isObjectMineOn()); >- >+ > if (!controllerDialog.isPositionBasedOn()) > break; >- >- /* The position based recording option is turned on/off */ >+ >+ /* The position based recording option is turned on/off */ > case AutoGUITestControllerDialog.POSITION_BASED: > boolean success = MacroManager.getInstance().togglePositionBasedRec(controllerDialog.isPositionBasedOn()); > >- if (success) >- { >+ if (success) { > if (controllerDialog.isPositionBasedOn()) > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_POS); > else > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); > } >- >+ > break; >- >+ > /* Wait time recording is turned on/off */ > case AutoGUITestControllerDialog.WAIT_TIME: >- MacroManager.getInstance().setArtificialWaitOn(controllerDialog.isWaitTimeOn()); >- >+ MacroManager.getInstance().setArtificialWaitOn(controllerDialog.isWaitTimeOn()); >+ > } >- >+ > } >- >- >- private boolean containSpecialChars(String hookName) >- { >+ >+ private boolean containSpecialChars(String hookName) { > boolean condition = false; >- >+ > char currentChar = hookName.charAt(0); > condition = (currentChar < 65 || currentChar > 90) && (currentChar < 97 || currentChar > 122); >- >+ > if (condition) > return condition; >- >- for (int i = 1; i < hookName.length(); i++) >- { >+ >+ for (int i = 1; i < hookName.length(); i++) { > currentChar = hookName.charAt(i); >- condition = (currentChar < 65 || currentChar > 90) && (currentChar < 97 || currentChar > 122) && >- (currentChar < 48 || currentChar > 57) && currentChar != 36 && currentChar != 95; >+ condition = >+ (currentChar < 65 || currentChar > 90) >+ && (currentChar < 97 || currentChar > 122) >+ && (currentChar < 48 || currentChar > 57) >+ && currentChar != 36 >+ && currentChar != 95; > if (condition) > return condition; > } > return false; > } > >+ public class CustomVerHookListener implements VerificationHookListener { > >- public class CustomVerHookListener implements VerificationHookListener >- { > private String verHook; >- private AutoGUIGenerator generator; >+ private boolean extendedScope; >+ private AutoGUIGenerator generator; > private boolean instanceReady; >- >- public CustomVerHookListener(AutoGUIGenerator generator, String verificationHook) >- { >+ >+ public CustomVerHookListener(AutoGUIGenerator generator, String verificationHook, boolean extendedScope) { > this.verHook = verificationHook; >+ this.extendedScope = extendedScope; > this.generator = generator; > this.instanceReady = false; > } >- >- >- public synchronized void error(String error) >- { >+ >+ public synchronized void error(String error) { > if (!instanceReady) >- controllerDialog.setStatus(error); >+ controllerDialog.setStatus(error); > else > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); > } > >- public synchronized void instanceReady(VerificationCommand verificationCommand) >- { >+ public synchronized void instanceReady(VerificationCommand verificationCommand) { > instanceReady = true; > /* We no longer need this class after being notified of the instance construciton */ > MacroManager.getInstance().removeVerListener(); >- >+ > controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_INS); >- >- /* We got the instance that we were looking for. Time to generate the method in the source code that >- * is associated with this test suite */ >- String argument = "Q"; >- byte verificationContextType = verificationCommand.getMetaData().getFocusType(); >- switch (verificationContextType) >- { >- case VerificationMetaData.EDITOR: >- argument += IEditorPart.class.getName(); >- break; >- case VerificationMetaData.VIEW: >- argument += IViewPart.class.getName(); >- break; >- case VerificationMetaData.SHELL: >- argument += Shell.class.getName(); >- break; >- } >- argument = argument + ";"; >- >+ > /* Insert a method in the source file corresponding to the name of the verification hook */ >- try >- { >+ try { >+ /* >+ * We got the instance that we were looking for. Time to generate the method in the source code that is associated with this test >+ * suite >+ */ >+ String contextArgument = "Q"; >+ contextArgument += verificationCommand.getContextClass().getName(); >+ contextArgument += ";"; >+ >+ String[] args; >+ if (!extendedScope) { >+ args = new String[] {contextArgument}; >+ } >+ else { >+ // construct a second argument for the UI object being selected >+ String widgetArgument = "Q"; >+ widgetArgument += verificationCommand.getWidgetClass().getName(); >+ widgetArgument += ";"; >+ >+ String objectArgument = null; >+ if(verificationCommand.getObjectClass() != null){ >+ objectArgument = "Q"; >+ objectArgument += verificationCommand.getObjectClass().getName(); >+ objectArgument += ";"; >+ } >+ >+ args = objectArgument == null ? new String[2] : new String[3]; >+ args[0] = contextArgument; >+ args[1] = widgetArgument; >+ if(objectArgument != null){ >+ args[2] = objectArgument; >+ } >+ } >+ > /* This should never happen */ >- if (argument.length() <= 2) >- throw new Exception (AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON); >- >+ if (contextArgument.length() <= 2) >+ throw new Exception(AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON); >+ > /* Complete the verification command's meta data */ >- ITestSuite testSuite = ((AutoGUITestCasesForm)suiteProvider).getTestSuite(); >- VerificationMetaData metaData = verificationCommand.getMetaData(); >- metaData.setLocation(testSuite.getImplementor().getLocation()); >- metaData.setResource(testSuite.getImplementor().getResource()); >- metaData.setHook(verHook + ":" + argument); >- >- generator.setInput(userInput.getName(), userInput.getDescription()); >- generator.createMethod (verHook, argument); >- } catch (Exception e) >- { >+ ITestSuite testSuite = ((AutoGUITestCasesForm) suiteProvider).getTestSuite(); >+ verificationCommand.setLocation(testSuite.getImplementor().getLocation()); >+ verificationCommand.setResource(testSuite.getImplementor().getResource()); >+ verificationCommand.setHook(verHook + ":" + (args.length > 1 ? (args.length > 2 ? args[0] + args[1] + args[2] : args[0] + args[1]) : args[0])); >+ verificationCommand.setExtendedScope(extendedScope); >+ >+ generator.setInput(userInput.getName(), >+ userInput.getDescription()); >+ generator.createMethod(verHook, >+ args); >+ } >+ catch (Exception e) { > MessageDialog.openWarning(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD_T, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD, e.getLocalizedMessage())); >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD_T, >+ NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD, >+ e.getLocalizedMessage())); > } >- >+ > /* Change the state of the macro manager to recording */ > if (globalStateListener != null) > globalStateListener.turnOn(false); >- MacroManager.getInstance().setGlobalState(MacroManager.RECORDING_MODE); >- controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); >- >+ MacroManager.getInstance().setGlobalState(ModeConstants.RECORDING_MODE); >+ controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); >+ > } >- >+ > } > >- >- public class CustomGlobalStateListener implements GlobalStateListener >- { >+ public class CustomGlobalStateListener implements GlobalStateListener { > > private boolean isOn; >- >- public CustomGlobalStateListener(boolean isOn) >- { >+ >+ public CustomGlobalStateListener(boolean isOn) { > this.isOn = isOn; > } >- >- public void turnOn (boolean isOn) >- { >+ >+ public void turnOn(boolean isOn) { > this.isOn = isOn; > } >- >- public boolean isListenerOn() >- { >+ >+ public boolean isListenerOn() { > return isOn; > } > >- public void globalStateChange(byte oldState, byte newState) >- { >- /* We're only interested when we're in verification mode and we >- * get interrupted */ >- if (oldState == MacroManager.VERIFICATION_MODE && newState == MacroManager.SUSPEND_MODE) >- { >- controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); >+ public void globalStateChange(byte oldState, byte newState) { >+ /* >+ * We're only interested when we're in verification mode and we get interrupted >+ */ >+ if (oldState == ModeConstants.VERIFICATION_MODE && newState == ModeConstants.SUSPEND_MODE) { >+ controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC); > } > } >- >+ > } > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIUpdateTestCaseAction.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIUpdateTestCaseAction.java,v >retrieving revision 1.3 >diff -u -r1.3 AutoGUIUpdateTestCaseAction.java >--- src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIUpdateTestCaseAction.java 7 Dec 2007 20:45:15 -0000 1.3 >+++ src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIUpdateTestCaseAction.java 26 Jul 2008 19:21:54 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2007 IBM Corporation and others. >+ * Copyright (c) 2006 IBM Corporation and others. > * 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 >@@ -15,296 +15,486 @@ > import java.util.Hashtable; > import java.util.Map; > >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm; > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject; >-import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; > import org.w3c.dom.NamedNodeMap; > import org.w3c.dom.Node; > import org.w3c.dom.NodeList; > > /** >- * This action will update the macro of the selected test cases to use the >+ * This action will update the macro of the selected test cases to use the > * latest syntax of the macro. > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ > public class AutoGUIUpdateTestCaseAction extends AutoGUITestCaseAction > { > /** Versions */ > private static final String VERSION_1_0 = "1.0"; >- >- /** The updater table contains the method name that can update a particular version of a macro >- * KEY = The macro version that can be updated >- * VALUE = The method name that will do the update >+ private static final String VERSION_1_1 = "1.1"; >+ >+ /** >+ * The updater table contains the method name that can update a particular >+ * version of a macro KEY = The macro version that can be updated VALUE = >+ * The method name that will do the update > */ > private Map updaterTable; >- >+ > /** The object mine that belongs to the test suite of this action */ >- private IObjectMine objectMine; >- >- >- public AutoGUIUpdateTestCaseAction(AutoGUITestCasesForm testCaseForm, String text, ImageDescriptor imageDescriptor) >- { >+ private MacroObjectDescriptorMine objectMine; >+ >+ public AutoGUIUpdateTestCaseAction(AutoGUITestCasesForm testCaseForm, >+ String text, ImageDescriptor imageDescriptor) { > super(testCaseForm, text, imageDescriptor); > setEnabled(false); >- >+ > /* Initialize the updater table */ >- updaterTable = new Hashtable(); >- final String VERSION_01 = "0.1"; >- final String UPDATER_01 = "updater01"; >- >- updaterTable.put(VERSION_01, UPDATER_01); >+ updaterTable = new Hashtable(); >+ final String VERSION_0_1 = "0.1"; >+ final String UPDATER__0_1__1_0 = "Update_0_1_to_1_0"; >+ final String UPDATER__1_0__1_1 = "Update_1_0_to_1_1"; >+ updaterTable.put(VERSION_0_1, UPDATER__0_1__1_0); >+ updaterTable.put(VERSION_1_0, UPDATER__1_0__1_1); > } >- >- >+ > /** >- * Invoked when the action is executed. Walk through each of the selected test cases >- * and update their corresponding macro. >+ * Invoked when the action is executed. Walk through each of the selected >+ * test cases and update their corresponding macro. > */ >- public void run() >- { >- if (!MessageDialog.openQuestion( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE_TITLE, >- AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE)) >- { >+ public void run() { >+ if (!MessageDialog.openQuestion(GuiPlugin.getDefault().getWorkbench() >+ .getActiveWorkbenchWindow().getShell(), >+ AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE_TITLE, >+ AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE)) { > return; > } >- >- try >- { >- objectMine = ObjectMineManager.getInstance().loadObjectMine(testCaseForm.getTestSuite()); >- } >- catch (Exception e) >- { >+ >+ try { >+ objectMine = MacroObjectDescriptorMineManager.getInstance() >+ .loadObjectMine(testCaseForm.getTestSuite()); >+ } catch (Exception e) { > AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, >- e); >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, e); > return; > } >- >+ > /* For each selected test case */ > boolean updated = false; >- for (int i = 0; i < selectedTestCases.length; i++) >- { >+ for (int i = 0; i < selectedTestCases.length; i++) { > /* Parse the macro of the selected test case */ >- String testCaseMacro = testCaseForm.getProperty(selectedTestCases[i], GUITestCaseProperties.MACRO_FRAGMENT); >+ String testCaseMacro = testCaseForm.getProperty( >+ selectedTestCases[i], GUITestCaseProperties.MACRO_FRAGMENT); > if (testCaseMacro == null || testCaseMacro.length() <= 0) > continue; >- >+ > XMLDefaultHandler handler = null; > Node rootElement = null; >- try >- { >- handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(testCaseMacro.getBytes("UTF-8"))); >+ try { >+ handler = MacroManager.getInstance().createMacroDocument( >+ new ByteArrayInputStream(testCaseMacro >+ .getBytes("UTF-8"))); > rootElement = handler.getDocumentElement(); >- } >- catch (Exception e) >- { >+ } catch (Exception e) { > /* Handled by the next line */ > } >- >- if (rootElement != null && !MacroConstants.MACRO_ELEMENT.equals(rootElement.getNodeName())) >+ >+ if (rootElement == null >+ && !MacroConstants.MACRO_ELEMENT.equals(rootElement >+ .getNodeName())) > continue; >- >- >- /* Look up the current version of the macro and call its corresponding update method */ >- Node macroVersion = rootElement.getAttributes().getNamedItem(MacroConstants.VERSION_ATTRIBUTE); >+ >+ /* >+ * Look up the current version of the macro and call its >+ * corresponding update method >+ */ >+ Node macroVersion = rootElement.getAttributes().getNamedItem( >+ MacroConstants.VERSION_ATTRIBUTE); > String currentVersion; >- if (macroVersion == null || (currentVersion = macroVersion.getNodeValue()) == null) >+ if (macroVersion == null >+ || (currentVersion = macroVersion.getNodeValue()) == null) > continue; >- >+ > /* For every sequential update required */ > String updater = null; > boolean updateTestCaseMacro = false; >- while ((updater = (String)updaterTable.get(currentVersion)) != null) >- { >- try >- { >- Method method = this.getClass().getMethod(updater, new Class[] {XMLDefaultHandler.class, IUIObject.class, Node.class}); >- if (method != null) >- { >- currentVersion = (String)(method.invoke(this, new Object[]{handler, null, rootElement})); >+ while ((updater = (String) updaterTable.get(currentVersion)) != null) { >+ try { >+ Method method = this.getClass().getMethod( >+ updater, >+ new Class[] { XMLDefaultHandler.class, >+ MacroObjectDescriptor.class, Node.class }); >+ if (method != null) { >+ currentVersion = (String) (method.invoke(this, >+ new Object[] { handler, null, rootElement })); > updateTestCaseMacro = true; >- } >- else >- { >+ } else { > break; >- } >- } >- catch (Exception e) >- { >+ } >+ } catch (Exception e) { > /* Should not happen */ > e.printStackTrace(); > break; > } > } >- >+ > /* Update the test case macro and the object mine */ >- if (updateTestCaseMacro) >- { >+ if (updateTestCaseMacro) { > updated = true; > StringBuffer buffer = new StringBuffer(); > serializeXMLToString(buffer, rootElement, 0); >- testCaseForm.updateTestProperty (null, buffer.toString(), false); >- >- ObjectMineManager.getInstance().writeObjectMine(objectMine); >+ testCaseForm.updateTestProperty(null, buffer.toString(), false); >+ >+ MacroObjectDescriptorMineManager.getInstance().writeObjectMine( >+ objectMine); > testCaseForm.refresh(); >- } >- } >- >- if (!updated) >- { >- MessageDialog.openInformation( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- AutoGUIMessages.AUTO_GUI_COMMON_INFORMATION, >+ } >+ } >+ >+ if (!updated) { >+ MessageDialog.openInformation(GuiPlugin.getDefault().getWorkbench() >+ .getActiveWorkbenchWindow().getShell(), >+ AutoGUIMessages.AUTO_GUI_COMMON_INFORMATION, > AutoGUIMessages.AUTO_GUI_TST_CASE_NO_UPDATE); > } > } >- >- private void serializeXMLToString(StringBuffer buffer, Node node, int indent) >- { >+ >+ private void serializeXMLToString(StringBuffer buffer, Node node, int indent) { > /* Write the current element */ > boolean hasChildren = node.hasChildNodes(); > boolean hasAttributes = node.hasAttributes(); > String nodeName = node.getNodeName(); > final String TEXT_NODE_NAME = "#text"; >- >- if (TEXT_NODE_NAME.equals(nodeName)) >- { >+ >+ if (TEXT_NODE_NAME.equals(nodeName)) { > String textContent = node.getNodeValue().trim(); >- boolean isContentEmpty = textContent == null || MacroConstants.EMPTY_STRING.equals(textContent);; >- if (!isContentEmpty) >- { >+ boolean isContentEmpty = textContent == null >+ || MacroConstants.EMPTY_STRING.equals(textContent); >+ ; >+ if (!isContentEmpty) { > MacroUtil.addIndent(buffer, indent); > buffer.append(textContent); > buffer.append(GlobalConstants.LINE_SEPARATOR); > } >- >+ > return; > } >- >- >- MacroUtil.addElement(buffer, indent, nodeName, !hasChildren && !hasAttributes, !hasAttributes); >- >+ >+ MacroUtil.addElement(buffer, indent, nodeName, !hasChildren >+ && !hasAttributes, !hasAttributes); >+ > /* Get the attributes */ >- if (hasAttributes) >- { >+ if (hasAttributes) { > NamedNodeMap attributes = node.getAttributes(); > int attCount = attributes.getLength(); > String[] attributeNames = new String[attCount]; > String[] attributeValues = new String[attCount]; >- for (int i = 0; i < attCount; i++) >- { >+ for (int i = 0; i < attCount; i++) { > Node currentAttribute = attributes.item(i); > attributeNames[i] = currentAttribute.getNodeName(); >- attributeValues[i] = currentAttribute.getNodeValue(); >+ attributeValues[i] = currentAttribute.getNodeValue(); > } >- MacroUtil.addAttribute(buffer, attributeNames, attributeValues, !hasChildren, true); >+ MacroUtil.addAttribute(buffer, attributeNames, attributeValues, >+ !hasChildren, true); > } >- >+ > /* For each child */ > NodeList nodeList = node.getChildNodes(); >- for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) >- { >- serializeXMLToString (buffer, nodeList.item(i), indent + 1); >+ for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) { >+ serializeXMLToString(buffer, nodeList.item(i), indent + 1); > } >- >+ > /* Close the XML node */ >- if (hasChildren) >- { >+ if (hasChildren) { > MacroUtil.addElement(buffer, indent, nodeName, true, true); > } >- >+ > } > >+ /** >+ * Converts a prior 1.1 context id to the new 1.1. format (using separators >+ * instead of PATH.SEPARATOR) >+ * >+ * @param oldContextId >+ * @return >+ */ >+ private String convertSerializedContextId(String oldContextId) { >+ if (oldContextId != null >+ && (oldContextId.startsWith(MacroConstants.LOCAL_TOOLBAR_VALUE) >+ || oldContextId.startsWith(MacroConstants.POPUP_VALUE) || oldContextId >+ .startsWith(MacroConstants.TAB_VALUE)) >+ && oldContextId >+ .indexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR) < 0) { >+ // may be old format (or the context id does not use a >+ // nested serealized macro object id), have to convert >+ IPath wpath = new Path(oldContextId); >+ String widgetId = wpath.lastSegment(); >+ wpath = wpath.removeLastSegments(1); >+ while (widgetId.startsWith("}}")) { >+ widgetId = wpath.lastSegment() + IPath.SEPARATOR + widgetId; >+ wpath = wpath.removeLastSegments(1); >+ } >+ String contextId = wpath.toString() >+ + MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR + widgetId; >+ return contextId; >+ } >+ return oldContextId; >+ } >+ >+ /* >+ * Convert widget id where the object id was stored as suffix into distinct >+ * widget and object ids >+ */ >+ private String[] convertConcatWidgetId(String oldWidgetId) { >+ if (oldWidgetId != null >+ && oldWidgetId >+ .indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) >= 0) { >+ String[] uiObjectId = new String[2]; >+ uiObjectId[0] = oldWidgetId.substring(0, oldWidgetId >+ .indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR)); >+ uiObjectId[1] = oldWidgetId.substring(oldWidgetId >+ .indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) + 3); >+ return uiObjectId; >+ } >+ return new String[] { oldWidgetId }; >+ } > >- public String updater01 (XMLDefaultHandler handler, IUIObject parent, Node rootNode) >- { >+ public String Update_1_0_to_1_1(XMLDefaultHandler handler, >+ MacroObjectDescriptor parent, Node rootNode) { > NodeList nodeList = rootNode.getChildNodes(); > Node currentNode; >+ >+ /* Update the version of the macro */ >+ if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName())) { >+ NamedNodeMap rootAttributes = rootNode.getAttributes(); >+ Node versionAttribute = null; >+ if (rootAttributes != null >+ && (versionAttribute = rootAttributes >+ .getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null) { >+ versionAttribute.setNodeValue(VERSION_1_1); >+ } >+ } >+ >+ /* For each child */ >+ for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) { >+ currentNode = nodeList.item(i); >+ NamedNodeMap attributes = currentNode.getAttributes(); >+ if (attributes == null) >+ continue; >+ >+ // Fix old context identifiers (serialized widget identifiers) >+ if (attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE) != null) { >+ Node contextIdAttributeNode = attributes >+ .getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ String oldContextId = contextIdAttributeNode.getNodeValue(); >+ String newContextId = convertSerializedContextId(oldContextId); >+ if (!oldContextId.equals(newContextId)) { >+ contextIdAttributeNode.setNodeValue(newContextId); >+ } >+ } >+ >+ // Replace old ID attribute of shell with WIDGET_ID (now used >+ // globally) >+ if (attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE) != null) { >+ Node idAttributeNode = attributes >+ .getNamedItem(MacroConstants.ID_ATTRIBUTE); >+ String widgetId = idAttributeNode.getNodeValue(); >+ attributes.removeNamedItem(MacroConstants.ID_ATTRIBUTE); >+ Node widgetIdAttribute = handler.getDocument().createAttribute( >+ MacroConstants.WIDGET_ID_ATTRIBUTE); >+ widgetIdAttribute.setNodeValue(widgetId); >+ attributes.setNamedItem(widgetIdAttribute); >+ } >+ >+ // Fix old widget identifiers (that have the object id as suffix) >+ if (attributes.getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE) != null) { >+ Node widgetIdAttributeNode = attributes >+ .getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE); >+ String oldWidgetId = widgetIdAttributeNode.getNodeValue(); >+ String[] uiObjectId = convertConcatWidgetId(oldWidgetId); >+ if (!oldWidgetId.equals(uiObjectId[0])) { >+ widgetIdAttributeNode.setNodeValue(uiObjectId[0]); >+ // we have an object id, add an object id >+ if (uiObjectId.length > 1) { >+ Node objectIdAttribute = handler.getDocument() >+ .createAttribute( >+ MacroConstants.OBJECT_ID_ATTRIBUTE); >+ objectIdAttribute.setNodeValue(uiObjectId[1]); >+ attributes.setNamedItem(objectIdAttribute); >+ } >+ } >+ } >+ >+ // Replace old PATH attribute of item -> now also WIDGET_ID >+ boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode >+ .getNodeName()) >+ || MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode >+ .getNodeName()); >+ if (isItem >+ && attributes.getNamedItem(MacroConstants.PATH_ATTRIBUTE) != null) { >+ Node idAttributeNode = attributes >+ .getNamedItem(MacroConstants.PATH_ATTRIBUTE); >+ String widgetId = idAttributeNode.getNodeValue(); >+ attributes.removeNamedItem(MacroConstants.PATH_ATTRIBUTE); >+ Node widgetIdAttribute = handler.getDocument().createAttribute( >+ MacroConstants.WIDGET_ID_ATTRIBUTE); >+ widgetIdAttribute.setNodeValue(widgetId); >+ attributes.setNamedItem(widgetIdAttribute); >+ } >+ >+ // // replace the old CHOICE_ID attribute -> now the more general >+ // OBJECT_ID can be used >+ // if (attributes.getNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE) >+ // != null) { >+ // Node idAttributeNode = attributes >+ // .getNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE); >+ // String objectId = idAttributeNode.getNodeValue(); >+ // attributes.removeNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE); >+ // Node objectIdAttribute = handler.getDocument().createAttribute( >+ // MacroConstants.OBJECT_ID_ATTRIBUTE); >+ // objectIdAttribute.setNodeValue(objectId); >+ // attributes.setNamedItem(objectIdAttribute); >+ // } >+ >+ // if the object is stored in the object mine, make sure the old >+ // context id is converted >+ Node refIdNode = attributes >+ .getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ String refId = refIdNode == null ? null : refIdNode.getNodeValue(); >+ boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode >+ .getNodeName()); >+ >+ MacroObjectDescriptor descriptor = null; >+ if (refId != null) { >+ descriptor = objectMine.lookupMacroObjectDescriptor( >+ isShell ? null : parent, refId); >+ // fix the context id >+ if (descriptor != null) { >+ descriptor >+ .setContextId(convertSerializedContextId(descriptor >+ .getContextId())); >+ } >+ >+ // NOTE: the object id was not stored as suffix of the widget id up to now (due to a bug), >+ // so we do not have to convert it here. > >+ // the ID -> WIDGET_ID conversion is done implicitly for the >+ // stored descriptors when saving the object mine >+ } >+ >+ if (currentNode.hasChildNodes()) >+ Update_1_0_to_1_1(handler, descriptor == null ? parent >+ : descriptor, currentNode); >+ >+ } >+ return VERSION_1_1; >+ } >+ >+ public String Update_0_1_to_1_0(XMLDefaultHandler handler, >+ MacroObjectDescriptor parent, Node rootNode) { >+ NodeList nodeList = rootNode.getChildNodes(); >+ Node currentNode; >+ > /* Update the version of the macro */ >- if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName())) >- { >+ if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName())) { > NamedNodeMap rootAttributes = rootNode.getAttributes(); > Node versionAttribute = null; >- if (rootAttributes != null && (versionAttribute = rootAttributes.getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null) >- { >+ if (rootAttributes != null >+ && (versionAttribute = rootAttributes >+ .getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null) { > versionAttribute.setNodeValue(VERSION_1_0); > } > } >- >+ > /* For each child */ >- for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) >- { >+ for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) { > currentNode = nodeList.item(i); > NamedNodeMap attributes = currentNode.getAttributes(); > if (attributes == null) > continue; >- >- Node contextIdNode = attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >- boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode.getNodeName()); >- boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode.getNodeName()) || MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode.getNodeName()); >- String idAttributeName = isShell ? MacroConstants.ID_ATTRIBUTE : isItem ? MacroConstants.PATH_ATTRIBUTE : MacroConstants.WIDGET_ID_ATTRIBUTE; >- Node objectIdNode = attributes.getNamedItem(idAttributeName); >- >- String contextId = contextIdNode == null ? null : contextIdNode.getNodeValue(); >- String objectId = objectIdNode == null ? null : objectIdNode.getNodeValue(); >- >- IUIObject uiObject = null; >- if (objectId != null) >- { >- uiObject = objectMine.lookupUIObject(isShell ? null : parent, contextId, objectId); >- if (uiObject == null) >- { >- try >- { >- uiObject = new UIObject(parent); >- uiObject.setContextId(contextId); >- uiObject.setDescriptive(attributes.getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE) == null ? MacroConstants.OBJECT_ELEMENT : attributes.getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE).getNodeValue()); >- uiObject.setObjectId(objectId); >- uiObject.setParent(isShell ? null : parent); >- uiObject.setReferenceId(objectMine.getUniqueReferenceId()); >- >- objectMine.registerObject(uiObject); >- } >- catch (Exception e) >- { >+ >+ Node contextIdNode = attributes >+ .getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode >+ .getNodeName()); >+ boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode >+ .getNodeName()) >+ || MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode >+ .getNodeName()); >+ String idAttributeName = isShell ? MacroConstants.ID_ATTRIBUTE >+ : isItem ? MacroConstants.PATH_ATTRIBUTE >+ : MacroConstants.WIDGET_ID_ATTRIBUTE; >+ Node widgetIdNode = attributes.getNamedItem(idAttributeName); >+ >+ String contextId = contextIdNode == null ? null : contextIdNode >+ .getNodeValue(); >+ String widgetId = widgetIdNode == null ? null : widgetIdNode >+ .getNodeValue(); >+ >+ MacroObjectDescriptor uiObject = null; >+ if (widgetId != null) { >+ uiObject = objectMine.lookupMacroObjectDescriptor( >+ isShell ? null : parent, contextId, widgetId, null); >+ if (uiObject == null) { >+ try { >+ uiObject = new MacroObjectDescriptor(parent); >+ ((MacroObjectDescriptor) uiObject) >+ .setContextId(contextId); >+ ((MacroObjectDescriptor) uiObject) >+ .setDescriptive(attributes >+ .getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE) == null ? MacroConstants.OBJECT_ELEMENT >+ : attributes >+ .getNamedItem( >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE) >+ .getNodeValue()); >+ ((MacroObjectDescriptor) uiObject) >+ .setWidgetId(widgetId); >+ ((MacroObjectDescriptor) uiObject).setObjectId(null); >+ ((MacroObjectDescriptor) uiObject) >+ .setParent(isShell ? null : parent); >+ objectMine >+ .registerObject((MacroObjectDescriptor) uiObject); >+ } catch (Exception e) { > /* Shouldn't happen */ > e.printStackTrace(); > } > } >- >- if (uiObject != null) >- { >+ >+ if (uiObject != null) { > if (contextId != null) >- attributes.removeNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ attributes >+ .removeNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); > attributes.removeNamedItem(idAttributeName); >- Node refIdAttribute = handler.getDocument().createAttribute(MacroConstants.REFERENCE_ID_ATTRIBUTE); >- refIdAttribute.setNodeValue(uiObject.getReferenceId()); >+ Node refIdAttribute = handler.getDocument() >+ .createAttribute( >+ MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ refIdAttribute.setNodeValue(uiObject.getReferenceId()); > attributes.setNamedItem(refIdAttribute); > } > } >- >+ > if (currentNode.hasChildNodes()) >- updater01(handler, uiObject == null ? parent : uiObject, currentNode); >+ Update_0_1_to_1_0(handler, >+ uiObject == null ? parent : uiObject, currentNode); > } >- >+ > return VERSION_1_0; > } >+ > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIPlayAction.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIPlayAction.java,v >retrieving revision 1.4 >diff -u -r1.4 AutoGUIPlayAction.java >--- src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIPlayAction.java 5 Mar 2008 18:27:00 -0000 1.4 >+++ src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIPlayAction.java 26 Jul 2008 19:21:51 -0000 >@@ -17,6 +17,7 @@ > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm; > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >+import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants; > import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner; > import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser; > import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner.ITestRunnerDelegator; >@@ -31,6 +32,7 @@ > * > * @author Ali Mehregani > * @author Paul E. Slauenwhite >+ * @author Alexander Nyssen > * @version March 5, 2008 > * @since March 17, 2006 > */ >@@ -56,7 +58,7 @@ > public void run() > { > /* Change the state of the macro manager */ >- MacroManager.getInstance().setGlobalState(MacroManager.QUICK_RUN_MODE); >+ MacroManager.getInstance().setGlobalState(ModeConstants.QUICK_RUN_MODE); > > /* This handler attempts to closely simulate the environment set before the > * auto gui runner is executed. This is important in order to make the quick >@@ -98,7 +100,7 @@ > public void run() > { > /* Change the state back to idle */ >- MacroManager.getInstance().setGlobalState(MacroManager.IDLE_MODE); >+ MacroManager.getInstance().setGlobalState(ModeConstants.IDLE_MODE); > > /* Re-store perspective */ > try >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/UIObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/UIObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/UIObject.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/UIObject.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,260 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.macro; >- >-import java.util.ArrayList; >-import java.util.Hashtable; >-import java.util.LinkedList; >-import java.util.Map; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >- >-public class UIObject implements IUIObject >-{ >- /** The context id */ >- private String contextId; >- >- /** The id of the object being resolved */ >- private String objectId; >- >- /** The reference id of this UI object */ >- private String referenceId; >- >- /** The descriptive attribute (a human readable identification) of this UI object */ >- private String descriptive; >- >- /** Keeps track of the hierarchical relationship */ >- private LinkedList hierarchicalRelation; >- >- /** The parent of this UI object */ >- private IUIObject parent; >- >- /** The properties of this UI Object */ >- private Hashtable properties; >- >- /** The id of the resolver that has resolved this object */ >- private String resolverId; >- >- /** The children of this object */ >- private ArrayList children; >- >- /** The associated data of this object */ >- private Object data; >- >- /** Children indexed based on their reference id >- * KEY = Reference id >- * VALUE = IUIObject that is a child of this object >- */ >- private Hashtable idIndexedChildren; >- >- public UIObject(IUIObject parent) >- { >- this.parent = parent; >- properties = new Hashtable(); >- children = new ArrayList(); >- idIndexedChildren = new Hashtable(); >- } >- >- >- /** >- * Creates an instace of this class based on a command passed in. >- * >- * @param objectMine The object mine that this object will be registered with >- * @param command The command that this object will be based on >- * @param parent The parent of this object >- * >- * @return An instance of this class based on widgetIdentifier >- */ >- public static IUIObject createInstance(IObjectMine objectMine, AbstractMacroCommand command, IUIObject parent) >- { >- WidgetIdentifier widgetIdentifier = command.getWidgetId(); >- IUIObject uiObject = new UIObject (parent); >- uiObject.setContextId(widgetIdentifier.getContextId() != null ? widgetIdentifier.getContextId().toString() : MacroConstants.EMPTY_STRING); >- uiObject.setObjectId(widgetIdentifier.getObjectId().toString()); >- uiObject.setReferenceId(objectMine.getUniqueReferenceId()); >- uiObject.setDescriptive(command.getDescriptiveField()); >- uiObject.setResolver(widgetIdentifier.getResolverId()); >- >- return uiObject; >- } >- >- >- public String getContextId() >- { >- return contextId; >- } >- >- public String getDescriptive() >- { >- return descriptive; >- } >- >- public LinkedList getHierarchicalRelation() >- { >- if (hierarchicalRelation != null) >- return hierarchicalRelation; >- >- hierarchicalRelation = new LinkedList(); >- findHierarchicalRelation(this); >- >- return hierarchicalRelation; >- } >- >- private void findHierarchicalRelation(IUIObject currentObject) >- { >- if (currentObject == null) >- return; >- hierarchicalRelation.addFirst(currentObject); >- findHierarchicalRelation(currentObject.getParent()); >- } >- >- public String getObjectId() >- { >- return objectId; >- } >- >- public Map getProperties() >- { >- return properties; >- } >- >- public String getProperty(String name) >- { >- return (String)properties.get(name); >- } >- >- public String getReferenceId() >- { >- return referenceId; >- } >- >- public void setContextId(String contextId) >- { >- this.contextId = contextId; >- } >- >- public void setDescriptive(String descriptive) >- { >- this.descriptive = descriptive; >- } >- >- public void setObjectId(String id) >- { >- this.objectId = id; >- } >- >- public void addProperty(String name, String value) >- { >- properties.put(name, value); >- } >- >- public void setReferenceId(String referenceId) >- { >- this.referenceId = referenceId; >- } >- >- public IUIObject getParent() >- { >- return parent; >- } >- >- public void setParent(IUIObject parent) >- { >- this.parent = parent; >- } >- >- >- public String getResolverId() >- { >- return resolverId; >- } >- >- >- public void setResolver(String resolverId) >- { >- this.resolverId = resolverId; >- } >- >- >- public void addChild(IUIObject child) throws CoreException >- { >- if (!children.contains(child)) >- { >- try >- { >- /* If there is a collision, then try to resolve it */ >- int referenceId = Integer.parseInt(child.getReferenceId()); >- while (idIndexedChildren.get(child.getReferenceId()) != null) >- { >- referenceId++; >- } >- child.setReferenceId(String.valueOf(referenceId)); >- } >- catch (NumberFormatException nfe) >- { >- /* Ignore the error */ >- } >- >- /* If there is still a collision, then throw an exception */ >- if (idIndexedChildren.get(child.getReferenceId()) != null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, child.getReferenceId())); >- >- idIndexedChildren.put(child.getReferenceId(), child); >- children.add(child); >- } >- } >- >- >- public int childCount() >- { >- return children.size(); >- } >- >- >- public IUIObject[] getChildren() >- { >- IUIObject[] objects = new IUIObject[children.size()]; >- children.toArray(objects); >- return objects; >- } >- >- >- public IUIObject removeChild(IUIObject child) >- { >- children.remove(child); >- return child; >- } >- >- >- public Object getData() >- { >- return data; >- } >- >- >- public void setData(Object data) >- { >- this.data = data; >- } >- >- >- public IUIObject findChild(String referenceId) >- { >- return (IUIObject) idIndexedChildren.get(referenceId); >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMineManager.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMineManager.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMineManager.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMineManager.java 7 Mar 2008 17:00:16 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,395 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006, 2008 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.macro; >- >-import java.io.ByteArrayInputStream; >-import java.io.IOException; >-import java.util.Hashtable; >-import java.util.List; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.Path; >-import org.eclipse.emf.common.util.URI; >-import org.eclipse.emf.ecore.EObject; >-import org.eclipse.emf.ecore.resource.Resource; >-import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >-import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil; >-import org.eclipse.hyades.test.core.util.EMFUtil; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound; >-import org.w3c.dom.NamedNodeMap; >-import org.w3c.dom.Node; >-import org.w3c.dom.NodeList; >-import org.xml.sax.SAXException; >- >- >-/** >- * In addition to the macro of each test case, a test suite also contains an object >- * mine keeps a reference of all resolved objects. The purpose of the object mine >- * is to resolve a widget once and use it many times. >- * <p/> >- * This is a singleton class that can be accessed via <code>getInstance()</code> >- * <p/> >- * >- * >- * @author Ali Mehregani >- * @author Paul E. Slauenwhite >- * @version March 7, 2008 >- * @since July 10, 2006 >- */ >-public class ObjectMineManager >-{ >- /** The instance of this class */ >- private static ObjectMineManager instance = new ObjectMineManager(); >- >- >- /** Cached object mines >- * KEY = Test suite id >- * VALUE = An object of type IObjectMine that represents the object mine of the test suite */ >- private Hashtable cachedObjectMines; >- >- >- /** Indicates whether a test suite's object mine is dirty or not >- * KEY = test suite id >- * VALUE = Boolean.TRUE if object mine is dirty; Boolean.FALSE otherwise >- */ >- private Hashtable dirtyStateTable; >- >- >- /** >- * Restrict the visibility of the constructor >- */ >- private ObjectMineManager() >- { >- cachedObjectMines = new Hashtable(); >- dirtyStateTable = new Hashtable(); >- } >- >- >- /** >- * Return the instance of this singleton class >- * >- * @return The instance of this class >- */ >- public static ObjectMineManager getInstance() >- { >- return instance; >- } >- >- >- /** >- * Load the object mine of the passed in test suite >- * >- * @param testSuite The test suite whose object mine is requested >- * @param useCache Uses the cached value if this is set to true; otherwise the >- * object mine is reloaded and returned. >- * >- * @return the object mine of the test suite that is passed in. >- * >- * @throws UIObjectNotFound In case an expected object is not found >- * @throws IDCollisionException In case there is a collision id >- * @throws CoreException In case of any unexpected error >- */ >- public IObjectMine loadObjectMine (ITestSuite testSuite, boolean useCache) throws UIObjectNotFound, IDCollisionException, CoreException >- { >- /* Is the object mine in cache? */ >- String testSuiteId = testSuite.getId(); >- IObjectMine objectMine = null; >- if (useCache && (objectMine = (IObjectMine)cachedObjectMines.get(testSuiteId)) != null) >- { >- objectMine.setOwner(testSuite); >- return objectMine; >- } >- >- >- /* Otherwise, it needs to be loaded. We need: >- * - Get the object mine XML fragment >- * - Parse it and load it */ >- String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuite, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE); >- if (objectMineXML == null || objectMineXML.length() <= 0) >- { >- /* Return a fresh object mine */ >- objectMine = new ObjectMine(testSuite, null); >- } >- >- if (objectMine == null) >- { >- objectMine = loadObjectMine (testSuite, objectMineXML); >- } >- >- if (objectMine != null) >- { >- cachedObjectMines.put(testSuiteId, objectMine); >- } >- >- return objectMine; >- } >- >- private IObjectMine loadObjectMine (ITestSuite testSuite, String objectMineXML) throws UIObjectNotFound, IDCollisionException, CoreException >- { >- if (objectMineXML == null || objectMineXML.length() <= 0) >- return new ObjectMine(testSuite, null); >- >- XMLDefaultHandler handler = null; >- >- try >- { >- handler = MacroUtil.createXMLDocument(new ByteArrayInputStream(objectMineXML.getBytes("UTF-8"))); >- } >- catch (SAXException e) >- { >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >- } >- catch (IOException e) >- { >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >- } >- >- /* Walk through the elemets and parse the document */ >- Node rootElement = handler.getDocumentElement(); >- NodeList children = rootElement.getChildNodes(); >- >- IObjectMine objectMine = new ObjectMine(testSuite, handler); >- for (int i = 0, childCount = children.getLength(); i < childCount; i++) >- { >- Node currentChild = children.item(i); >- String nodeName = currentChild.getNodeName(); >- if (MacroConstants.HEADER_ELEMENT.equals(nodeName)) >- { >- loadHeader(objectMine, currentChild); >- } >- else if (MacroConstants.OBJECTS_ELEMENT.equals(nodeName)) >- { >- loadObjects (objectMine, currentChild); >- } >- } >- >- >- return objectMine; >- } >- >- >- /** >- * This method should be used if the object mine will be loaded for reading purposes. >- * Contributors will not be able to use this returned object mine to write any objects. >- * >- * @param objectMineXML The XML string representing the object mine >- * >- * @return the object mine of the test suite that is passed in. >- * >- * @throws UIObjectNotFound In case an expected object is not found >- * @throws IDCollisionException In case there is a collision id >- * @throws CoreException In case of any unexpected error >- */ >- public IObjectMine loadObjectMine (String objectMineXML) throws UIObjectNotFound, IDCollisionException, CoreException >- { >- return loadObjectMine(null, objectMineXML); >- } >- >- >- private void loadHeader(IObjectMine objectMine, Node headerNode) throws CoreException, UIObjectNotFound, IDCollisionException >- { >- /* Let's first read in the contribute attribute */ >- NamedNodeMap attributes = headerNode.getAttributes(); >- Node contributeAtt = attributes.getNamedItem(MacroConstants.OUTPUT_ATTRIBUTE); >- if (contributeAtt != null) >- { >- ITestSuite testSuite = loadTestSuite(contributeAtt.getNodeValue()); >- if (testSuite == null) >- { >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUT_NF, >- null); >- >- } >- else >- { >- try >- { >- IObjectMine outputObjectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite); >- objectMine.setOutputSource(outputObjectMine); >- } >- catch (Exception e) >- { >- objectMine.setOutputSource(null); >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, testSuite.getName()), >- e); >- } >- } >- } >- >- /* Now load in all includes */ >- NodeList children = headerNode.getChildNodes(); >- for (int i = 0, childCount = children.getLength(); i < childCount; i++) >- { >- Node currentChild = children.item(i); >- String nodeName = currentChild.getNodeName(); >- if (MacroConstants.INCLUDE_ELEMENT.equals(nodeName)) >- { >- Node pathAttribute = currentChild.getAttributes().getNamedItem(MacroConstants.PATH_ATTRIBUTE); >- if (pathAttribute != null) >- { >- ITestSuite testSuite = loadTestSuite(pathAttribute.getNodeValue()); >- IObjectMine includedObjectMine = loadObjectMine(testSuite); >- objectMine.addInclude(includedObjectMine); >- } >- } >- } >- } >- >- >- private void loadObjects(IObjectMine objectMine, Node objectsNode) throws CoreException, UIObjectNotFound, IDCollisionException >- { >- NodeList children = objectsNode.getChildNodes(); >- registerObjects(objectMine, null, children); >- } >- >- >- private void registerObjects(IObjectMine objectMine, IUIObject parent, NodeList children) throws CoreException, UIObjectNotFound, IDCollisionException >- { >- /* For every object */ >- for (int i = 0, childCount = children.getLength(); i < childCount; i++) >- { >- Node currentNode = children.item(i); >- >- NamedNodeMap attributes = currentNode.getAttributes(); >- Node referenceIdNode = attributes.getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE); >- String referenceId = null; >- if (referenceIdNode == null || (referenceId = referenceIdNode.getNodeValue()) == null) >- { >- Node idAttribute = attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE); >- String objectId = idAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN : idAttribute.getNodeValue(); >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REF, objectId), 0); >- } >- >- IUIObject guiObject = objectMine.lookupUIObject(parent, referenceId); >- >- /* Register the object if it's not yet registered */ >- if (guiObject == null) >- { >- guiObject = objectMine.registerObject(parent, currentNode); >- } >- /* Otherwise throw an exception if there is an id collision */ >- else >- { >- Node contextIdNode = attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >- Node objectIdNode = attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE); >- String contextId = contextIdNode == null ? null : contextIdNode.getNodeValue(); >- String objectId = objectIdNode.getNodeValue(); >- >- if (((contextId == null && guiObject.getContextId() != null) || >- (contextId != null && !contextId.equals(guiObject.getContextId()))) || >- !objectId.equals(guiObject.getObjectId())) >- { >- throw new IDCollisionException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, referenceId)); >- } >- } >- >- /* Load the children of this object */ >- if (currentNode.getChildNodes().getLength() > 0) >- registerObjects(objectMine, guiObject, currentNode.getChildNodes()); >- } >- } >- >- >- private ITestSuite loadTestSuite(String testSuitePath) throws CoreException >- { >- if (testSuitePath == null || testSuitePath.length() <= 0) >- return null; >- >- IPath path = new Path(testSuitePath); >- URI uri = URI.createPlatformResourceURI(path.toString()); >- EObject[] eObjects = EMFUtil.getEObjects(uri, true); >- return eObjects != null && eObjects.length > 0 && eObjects[0] instanceof ITestSuite ? (ITestSuite)eObjects[0] : null; >- } >- >- >- public void writeObjectMine(IObjectMine objectMine) >- { >- writeObjectMine (objectMine, false); >- } >- >- private void writeObjectMine(IObjectMine objectMine, boolean autoSave) >- { >- ITestSuite testSuite = objectMine.getOwner(); >- Resource testSuiteResource = ((EObject)testSuite).eResource(); >- autoSave = autoSave && (testSuiteResource != null && !testSuiteResource.isModified()); >- >- String xmlSerialization = objectMine.serializeToString(); >- HyadesUtil.setTestSuiteVariable(testSuite, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE, xmlSerialization); >- >- if (autoSave) >- { >- try >- { >- EMFUtil.save(testSuiteResource); >- } catch (Exception e) >- { >- /* Shouldn't happen */ >- e.printStackTrace(); >- } >- } >- >- /* We also need to update all object mines included by the object mine passed in */ >- List includes = objectMine.getIncludes(); >- for (int i = 0, includeCount = includes.size(); i < includeCount; i++) >- { >- IObjectMine currentObjectMine = (IObjectMine)includes.get(i); >- writeObjectMine (currentObjectMine, true); >- } >- >- >- dirtyStateTable.put(testSuite.getId(), Boolean.TRUE); >- } >- >- >- public IObjectMine loadObjectMine(ITestSuite testSuite) throws UIObjectNotFound, IDCollisionException, CoreException >- { >- Boolean dirtyState = (Boolean)dirtyStateTable.get(testSuite.getId()); >- boolean isObjectMineDirty = dirtyState == null ? false : dirtyState.booleanValue(); >- dirtyStateTable.put(testSuite.getId(), Boolean.FALSE); >- return loadObjectMine(testSuite, !isObjectMineDirty); >- } >- >- >- /** >- * Marks the object mine of the passed in test suite as dirty >- * >- * @param testSuite The test suite >- */ >- public void markObjectMineDirty(ITestSuite testSuite) >- { >- if (testSuite == null) >- return; >- >- dirtyStateTable.put(testSuite.getId(), Boolean.TRUE); >- } >- >- >- /** >- * Removes all entries in cache. >- * This should be carefully used. >- */ >- public void clearCache() >- { >- cachedObjectMines.clear(); >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroUtil.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroUtil.java,v >retrieving revision 1.1 >diff -u -r1.1 MacroUtil.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroUtil.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroUtil.java 26 Jul 2008 19:22:14 -0000 >@@ -13,7 +13,6 @@ > import java.io.IOException; > import java.io.InputStream; > import java.util.Hashtable; >-import java.util.Vector; > > import javax.xml.parsers.ParserConfigurationException; > import javax.xml.parsers.SAXParser; >@@ -23,21 +22,17 @@ > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.Path; > import org.eclipse.hyades.test.common.util.XMLUtil; >-import org.eclipse.jface.action.ActionContributionItem; >+import org.eclipse.jface.action.ContributionManager; > import org.eclipse.jface.action.CoolBarManager; >-import org.eclipse.jface.action.IAction; >-import org.eclipse.jface.action.IContributionItem; > import org.eclipse.jface.action.IMenuManager; > import org.eclipse.jface.action.IToolBarManager; > import org.eclipse.jface.action.MenuManager; > import org.eclipse.jface.action.ToolBarManager; > import org.eclipse.jface.window.ApplicationWindow; >-import org.eclipse.jface.window.Window; > import org.eclipse.jface.wizard.IWizardPage; > import org.eclipse.jface.wizard.WizardDialog; > import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.custom.CTabFolder; >-import org.eclipse.swt.custom.CTabItem; >+import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.Point; > import org.eclipse.swt.graphics.Rectangle; > import org.eclipse.swt.widgets.Button; >@@ -46,12 +41,9 @@ > import org.eclipse.swt.widgets.CoolBar; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; >-import org.eclipse.swt.widgets.Item; > import org.eclipse.swt.widgets.Menu; > import org.eclipse.swt.widgets.MenuItem; > import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.TabFolder; >-import org.eclipse.swt.widgets.TabItem; > import org.eclipse.swt.widgets.ToolBar; > import org.eclipse.swt.widgets.ToolItem; > import org.eclipse.swt.widgets.Widget; >@@ -59,781 +51,281 @@ > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; > import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IEditorReference; > import org.eclipse.ui.IPartListener; >-import org.eclipse.ui.IPluginContribution; > import org.eclipse.ui.IViewPart; > import org.eclipse.ui.IViewReference; > import org.eclipse.ui.IWorkbench; > import org.eclipse.ui.IWorkbenchPage; > import org.eclipse.ui.IWorkbenchPart; >-import org.eclipse.ui.IWorkbenchPartSite; > import org.eclipse.ui.IWorkbenchWindow; >+import org.eclipse.ui.PartInitException; > import org.eclipse.ui.intro.IIntroManager; > import org.eclipse.ui.intro.IIntroPart; >+import org.eclipse.ui.testing.IWorkbenchPartTestable; > import org.w3c.dom.Node; > import org.xml.sax.SAXException; > > /** >- * A helper class that is used while recording a macro. <b>Important: </b> This >- * class uses internal classes. >+ * A helper class that is used while recording a macro. <b>Important: </b> This class uses internal classes. >+ * >+ * @author Alexander Nyssen (moved everything related to resolving/deresolving out of here > */ >-public class MacroUtil >-{ >- private static Hashtable workbenchPartListeners; >- private static WorkbenchPartListener workbenchPartLisntener; >- >+public class MacroUtil { >+ > /** The parser used to parse XML fragments */ > private static SAXParser parser; >- >- static >- { >- workbenchPartListeners = new Hashtable(); >- } >- >- /** >- * Returns the path where counters of the given event are stored, or null if >- * we are not keeping records of the given event. >- * >- * @param event >- * @return >- */ >- public static WidgetIdentifier getWidgetIdentifier(Widget widget) >- { >- IWidgetId widgetId = null; >- if (widget instanceof MenuItem) >- { >+ >+ private static Hashtable workbenchPartListeners = new Hashtable(); >+ private static IPartListener workbenchPartListener = new IPartListener() { >+ >+ public void partActivated(IWorkbenchPart part) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ public void partBroughtToTop(IWorkbenchPart part) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ /** >+ * This method will generate a close workbench part command. We can't determine for sure through events reported by a display of when a >+ * workbench part is closed. This part listener is a work around that allows us to capture close events on workbench parts. >+ * >+ * @param part >+ * The part is closed. >+ */ >+ public void partClosed(IWorkbenchPart part) { >+ Macro currentMacro = MacroManager.getInstance().getCurrentMacro(); >+ Event event = new Event(); >+ >+ event.type = EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED; >+ event.data = part; >+ event.display = part.getSite().getShell().getDisplay(); >+ if (currentMacro != null) { >+ try { >+ currentMacro.addEvent(event); >+ } >+ catch (Exception e) { >+ /* Ignore the error. It doesn't generate the command */ >+ e.printStackTrace(); >+ } >+ } >+ } >+ >+ public void partDeactivated(IWorkbenchPart part) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ public void partOpened(IWorkbenchPart part) { >+ /* Doesn't need to be implemented */ >+ } >+ }; >+ >+ private static IWorkbenchWindow findHookTarget(Widget widget) { >+ if (widget instanceof MenuItem) { > MenuItem menuItem = (MenuItem) widget; >- widgetId = determineItemId (menuItem); > IViewPart view = null; >- if (onMenubar(menuItem)) >- { >- return new WidgetIdentifier(new Path(MacroConstants.MENUS_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$ >- } >- else if ((view = onWorkbenchPartToolbar(menuItem)) != null) >- { >- /* The context id should be the workbench part toolbar */ >+ if ((view = onWorkbenchPartToolbar(menuItem)) != null) { >+ // TODO: check if the toolbar manager has to be used to find the hook target... >+ /* The context id should be the workbench part toolbar */ > IToolBarManager toolbarManager = view.getViewSite().getActionBars().getToolBarManager(); > if (toolbarManager == null || !(toolbarManager instanceof ToolBarManager)) > return null; >- >- view.setFocus(); >- WidgetIdentifier contextId = getControlIdentifier(((ToolBarManager)toolbarManager).getControl()); >- return new WidgetIdentifier(new Path(MacroConstants.LOCAL_TOOLBAR_MENU_VALUE).append(contextId.getFullyQualifiedPath()), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$ >+ >+ // CHECK: setting the focus does not seem to be necessary to find a hook target >+ // -> wihtout it, this method is side effect free >+ // view.setFocus(); >+ return findHookTarget(((ToolBarManager) toolbarManager).getControl()); > } > Control c = widget.getDisplay().getFocusControl(); >- WidgetIdentifier ci = getControlIdentifier(c); >- if (ci == null) >- return null; >- return new WidgetIdentifier(new Path(MacroConstants.POPUP_VALUE).append(ci.getFullyQualifiedPath()), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$ >+ return findHookTarget(c); > } >- else if (widget instanceof ToolItem) >- { >+ else if (widget instanceof ToolItem) { > ToolItem toolItem = (ToolItem) widget; >- widgetId = determineItemId (toolItem); >- >- /* Check to see if this toolbar belongs to the global toolbar of the workbench */ >- if (onToolbar(toolItem)) >- return new WidgetIdentifier(new Path(MacroConstants.TOOLBAR_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$ > > /* Local toolbar somewhere - locate the parent first */ > ToolBar toolBar = toolItem.getParent(); >- WidgetIdentifier controlId = getControlIdentifier(toolBar); >- if (controlId != null) >- { >- IPath localPath = controlId.getFullyQualifiedPath(); >- return new WidgetIdentifier(new Path(MacroConstants.LOCAL_TOOLBAR_VALUE).append(localPath), new Path(widgetId.toString()), widgetId.getResolverId()); >- } >- } >- else if (widget instanceof Shell) >- { >- widgetId = getShellId((Shell) widget, null); >- return new WidgetIdentifier(new Path(MacroConstants.SHELL_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); >- } >- else if (widget instanceof Control) >- { >- return getControlIdentifier((Control) widget); >- } >- else if (widget instanceof Menu) >- { >- widgetId = getActionId((Menu) widget); >- return new WidgetIdentifier(new Path(MacroConstants.MENUS_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); >+ return findHookTarget(toolBar); > } >- return null; >- } >- >- >- public static IWidgetId getShellId(Shell shell, String resolverId) >- { >- IWidgetId widgetId = MacroManager.getInstance().resolveWidget(shell.getParent(), shell, resolverId, newCounter()); >- if (widgetId != null) >- return widgetId; >- return getDefaultShellId(shell); >- } >- >- public static IWidgetId getDefaultShellId(Shell shell) >- { >- Object data = shell.getData(); >- String id = ""; >- if (data instanceof WizardDialog) >- { >- id = data.getClass().getName().toString(); >- } >- else if (data instanceof Window) >- { >- id = data.getClass().getName().toString(); >- } >- >- PrimitiveWidgetId widgetId = new PrimitiveWidgetId(); >- widgetId.setId(id); >- return widgetId; >- } >- >- public static WidgetIdentifier getControlIdentifier(Control control) >- { >- Shell shell = control.getShell(); >- Object data = shell.getData(); >- if (data instanceof WizardDialog) >- { >- // in wizard >- WizardDialog wd = (WizardDialog) data; >- IWizardPage page = wd.getCurrentPage(); >- if (page == null) >- return null; >- Control pageControl = page.getControl(); >- IWidgetId relativePath = computeRelativePath((Composite) pageControl, null, control); >- if (relativePath != null) >- { >- IPath path = new Path(MacroConstants.WIZARD_PAGE_VALUE).append(page.getName()); >- return new WidgetIdentifier(path, new Path(relativePath.toString()), relativePath.getResolverId()); >- } >- // check for wizard buttons >- if (control instanceof Button) >- { >- relativePath = computeRelativePath(shell, (Composite) pageControl, control); >- return new WidgetIdentifier(new Path(MacroConstants.WIZARD_VALUE), new Path(relativePath.toString()), relativePath.getResolverId()); >+ else if (widget instanceof Control) { >+ Shell shell = ((Control) widget).getShell(); >+ Object data = shell.getData(); >+ if (data instanceof IWorkbenchWindow) { >+ IWorkbenchWindow window = (IWorkbenchWindow) data; >+ return window; > } > return null; > } >- else if (data instanceof IWorkbenchWindow) >- { >+ return null; >+ } > >- IWorkbenchWindow window = (IWorkbenchWindow) data; >- IWorkbenchPage page = window.getActivePage(); >+ protected static void hookWorkbenchPartListener(Widget widget) { >+ IWorkbenchWindow workbenchWindow = findHookTarget(widget); >+ if (workbenchWindow != null) { >+ IWorkbenchPage page = workbenchWindow.getActivePage(); > > /** >- * Ali M.: Under some situations, the part that is returned by the >- * 'getActivePart' method is the old active part. Although the >- * control object is coming from the newly active part, the part >- * that is retrieved below will be from the old active part. This >- * will cause MacroUtil.getControlIdentifier to return null when >- * attempting to retrieve the widget id in the wrong context. One >- * situation that this fails under is when: - Macro recorder start >- * while the test suite editor is active - A hook is inserted - The >- * package view is focused (not activated and focused but just >- * focused) >+ * Ali M.: Under some situations, the part that is returned by the 'getActivePart' method is the old active part. Although the control >+ * object is coming from the newly active part, the part that is retrieved below will be from the old active part. This will cause >+ * MacroUtil.getControlIdentifier to return null when attempting to retrieve the widget id in the wrong context. One situation that this >+ * fails under is when: - Macro recorder start while the test suite editor is active - A hook is inserted - The package view is focused >+ * (not activated and focused but just focused) > * >- * To resolve this issue, I have registered a part listener when the >- * client starts recording. When there is a new active part >- * detected, an event is created and fired to the usual onEvent >- * handler in MacroManager. See MacroManager.hookPartListener. >+ * To resolve this issue, I have registered a part listener when the client starts recording. When there is a new active part detected, an >+ * event is created and fired to the usual onEvent handler in MacroManager. See MacroManager.hookPartListener. > */ > IWorkbenchPart part = page.getActivePart(); >- IWorkbenchPartSite site = part.getSite(); >- >- >- /* Ali M.: Register a dispose listener with this workbench part if we have not >- * already done so. This is so that close commands can be generated. */ >- if (workbenchPartListeners.get(page) == null) >- { >- if (workbenchPartLisntener == null) >- workbenchPartLisntener = new WorkbenchPartListener(); >- >- page.addPartListener(workbenchPartLisntener); >- workbenchPartListeners.put(page, workbenchPartLisntener); >- } >- >- IPath path; >- >- if (part instanceof IViewPart) >- { >- path = new Path(MacroConstants.VIEW_VALUE).append(site.getId()); >- } >- else if (part instanceof IEditorPart) >- { >- String inputName = ((IEditorPart) part).getEditorInput().getName(); >- path = new Path(MacroConstants.EDITOR_VALUE).append(site.getId()).append(inputName); >- } >- else >- { >- return null; >- } >- >- Composite paneComposite = MacroObjectLocator.getWorkbenchPartControl(part); >- >- /* If the control we are looking for is a local tool bar, go up one level */ >- if (part instanceof IViewPart && control instanceof ToolBar) >- paneComposite = paneComposite.getParent(); >- IWidgetId relativePath = computeRelativePath(paneComposite, null, control); >- >- if (relativePath != null) >- { >- return new WidgetIdentifier(path, new Path(relativePath.toString()), relativePath.getResolverId()); >- } >- } >- else >- { >- /* unknown shell - fetch controls starting from the shell */ >- IWidgetId relativePath = computeRelativePath(shell, null, control); >- if (relativePath == null) >- return null; >- return new WidgetIdentifier(new Path(MacroConstants.SHELL_VALUE), new Path(relativePath.toString()), relativePath.getResolverId()); >+ /* >+ * Ali M.: Register a dispose listener with this workbench part if we have not already done so. This is so that close commands can be >+ * generated. >+ */ >+ if (workbenchPartListeners.get(page) == null) { >+ page.addPartListener(workbenchPartListener); >+ workbenchPartListeners.put(page, >+ workbenchPartListener); >+ } > } >- return null; >- } >- >- private static IWidgetId computeRelativePath(Composite parent, Composite skip, Control control) >- { >- int[] counter = newCounter(); >- Vector indices = new Vector(); >- boolean result = computeControlIndex(parent, skip, control, counter, indices); >- if (!result && skip == null) >- return null; >- >- int index = result ? ((Integer)indices.get(0)).intValue() : 0; >- IWidgetId widgetId = MacroManager.getInstance().resolveWidget(control, null, newCounter()); >- if (widgetId != null) >- return widgetId; >- return computeDefaultControlId(control, index); > } > >- >- public static int[] newCounter() >- { >+ public static int[] newCounter() { > int[] inx = new int[1]; > inx[0] = 0; > return inx; > } >- >- >- /** >- * Determines the index of the desiredControl relative to the parent control sent in. The >- * Index is stored in index[0]. >- * >- * @param parent The parent control >- * @param skip Indicates whether a composite should be skipped >- * @param desiredControl The desired control >- * @param index The current index calculated thus far (stored in index[0]. The type of this >- * parameter is an int array because its value needs to be preserved between recursive calls. >- * >- * @return true if the index was found; false otherwise. >- */ >- private static boolean computeControlIndex(Composite parent, Composite skip, Control desiredControl, int[] index, Vector indices) >- { >- return recursiveSearch(parent, skip, desiredControl, null, null, index, new Vector(), indices) != null; >- } > >- >- >- public static Control recursiveSearch(Composite parent, Composite skip, Control desiredControl, WidgetIdentifier id, String widgetClassName, int[] index, Vector matches, Vector indices) >- { >- boolean searchForControl = id == null; >- Control[] children = parent.getChildren(); >- boolean[] checkTypeAndEquality; >- Control searchResult; >- boolean isTabFolder, isCTabFolder; >- >- for (int i = 0; i < children.length; i++) >- { >- Control child = children[i]; >- >- if (!child.isVisible()) >- { >- /* If the control is of the same type, then we'll need to increment the index */ >- if ((widgetClassName != null && child.getClass().getName().equals(widgetClassName)) || (desiredControl != null && desiredControl.getClass().getName().equals(child.getClass().getName()))) >- index[0]++; >- >- continue; >- } >- >- checkTypeAndEquality = searchForControl ? checkTypeAndEqual(desiredControl, child, index) : checkTypeAndId (child, id, widgetClassName, index); >- if (checkTypeAndEquality[0]) >- { >- if (checkTypeAndEquality[1]) >- { >- addMatch (matches, indices, child, index[0]); >- } >- >- /* Defect 111371 -- We need to step through the items of a tab */ >- isTabFolder = child instanceof TabFolder; >- isCTabFolder = child instanceof CTabFolder; >- if (isTabFolder || isCTabFolder) >- { >- Object[] tabItems = isTabFolder ? (Object[])((TabFolder)child).getItems() : ((CTabFolder)child).getItems(); >- if (tabItems != null) >- { >- for (int j = 0; j < tabItems.length; j++) >- { >- Control tabItemControl = isTabFolder ? ((TabItem)tabItems[j]).getControl() : ((CTabItem)tabItems[j]).getControl(); >- >- if (tabItemControl == null) >- continue; >- >- checkTypeAndEquality = searchForControl ? checkTypeAndEqual (tabItemControl, desiredControl, index) : checkTypeAndId (tabItemControl, id, widgetClassName, index); >- if (checkTypeAndEquality[0] && checkTypeAndEquality[1]) >- { >- addMatch (matches, indices, tabItemControl, index[0]); >- } >- if ((searchResult = recursiveSearch(tabItemControl, skip, desiredControl, id, widgetClassName, index, matches, indices)) != null) >- { >- addMatch (matches, indices, searchResult, index[0]); >- } >- } >- } >- } >- >- } >- >- if ((searchResult = recursiveSearch (child, skip, desiredControl, id, widgetClassName, index, matches, indices)) != null) >- { >- addMatch (matches, indices, searchResult, index[0]); >- } >- } >- >- if (matches.size() > 0) >- return (Control)matches.get(0); >- >- return null; >- } >- >- private static void addMatch (Vector container, Vector indices, Object item, int index) >- { >- if (!container.contains(item)) >- { >- container.add(item); >- indices.add(new Integer(index)); >- } >- } >- >- private static Control recursiveSearch(Control currentSearchPoint, Composite skip, Control desiredControl, WidgetIdentifier desiredId, String desiredWidgetClassName, int[] index, Vector matches, Vector indices) >- { >- Control searchResult = null; >- if (currentSearchPoint instanceof Composite && !(skip != null && currentSearchPoint.equals(skip)) && currentSearchPoint.isVisible()) >- { >- searchResult = recursiveSearch((Composite) currentSearchPoint, skip, desiredControl, desiredId, desiredWidgetClassName, index, matches, indices); >- } >- >- return searchResult; >- } >- >- >- /** >- * A helper method used to indicate whether expected is of the same type as actual. The >- * return value also indicates if expected == actual. >- * >- * @param expected The expected control >- * @param actual The actual control that 'expected' is checked against >- * @param counter A counter that is used for indexing. >- * >- * @return This method has the side affect of incrementing counter if the class types >- * of the two controls are the same. The return value indicates type and whether expected == actual. >- */ >- private static boolean[] checkTypeAndEqual (Control expected, Control actual, int[] counter) >- { >- boolean[] typeAndEqualCheck = new boolean[2]; >- if (expected.getClass().equals(actual.getClass())) >- { >- typeAndEqualCheck[0] = true; >- >- // same type - increment counter >- counter[0]++; >- if (expected.equals(actual)) >- { >- // bingo >- typeAndEqualCheck[1] = true; >- } >- } >- >- return typeAndEqualCheck; >- } >- >- >- public static boolean[] checkTypeAndId (Control presentControl, WidgetIdentifier desiredId, String desiredWidgetClassName, int[] counter) >- { >- boolean[] checkTypeAndEqualId = new boolean[2]; >- >- if (desiredWidgetClassName == null || presentControl.getClass().getName().equals(desiredWidgetClassName)) >- { >- // same type - increment counter >- if (!presentControl.isVisible()) >- return checkTypeAndEqualId; >- >- checkTypeAndEqualId[0] = true; >- counter[0]++; >- if (MacroObjectLocator.foundWidget(presentControl, desiredId.getResolverId(), desiredId.getObjectId().toString()) || computeDefaultControlId(presentControl, counter[0]).equals(desiredId.getObjectId().toString())) >- { >- checkTypeAndEqualId[1] = true; >- } >- } >- >- return checkTypeAndEqualId; >- } >- >- >- private static IWidgetId computeDefaultControlId(Control control, int controlIndex) >- { >- PrimitiveWidgetId primitiveWidgetId = new PrimitiveWidgetId(); >- primitiveWidgetId.setId(control.getClass().getName() + "#" + controlIndex); >- return primitiveWidgetId; >- } >- >- >- public static boolean isInputControl(Control control) >- { >+ public static boolean isInputControl(Control control) { > return true; > } > >- /** >- * @param menuItem >- * @return >- */ >- private static boolean onMenubar(MenuItem menuItem) >- { >- Menu parent = menuItem.getParent(); >- MenuItem parentItem = parent.getParentItem(); >- >- if (parentItem != null) >- { >- return onMenubar(parentItem); >- } >- >- Shell theShell = parent.getShell(); >- return parent == theShell.getMenuBar(); >- } >- >- private static boolean onToolbar(ToolItem toolItem) >- { >- ToolBar toolBar = toolItem.getParent(); >- Shell shell = toolBar.getShell(); >- Object data = shell.getData(); >- if (data instanceof ApplicationWindow) >- { >- ApplicationWindow window = (ApplicationWindow) data; >- ToolBarManager mng = window.getToolBarManager(); >- if (mng != null) >- { >- if (mng.getControl() != null && mng.getControl() == toolBar) >- return true; >- } >- CoolBarManager cmng = window.getCoolBarManager(); >- if (cmng != null) >- { >- CoolBar cbar = cmng.getControl(); >- Composite parent = toolBar.getParent(); >- while (parent != null) >- { >- if (parent == cbar) >- return true; >- parent = parent.getParent(); >- } >- } >- } >- return false; >- } >- >- private static IViewPart onWorkbenchPartToolbar(MenuItem menuItem) >- { >- IWorkbenchPage[] pages = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getPages(); >- >- /* For evey page */ >- for (int i = 0; i < pages.length; i++) >- { >- IViewReference[] viewReferences = pages[i].getViewReferences(); >- >- /* For evey opened view */ >- for (int j = 0; j < viewReferences.length; j++) >- { >- IViewPart viewPart = viewReferences[j].getView(false); >- if (viewPart == null) >- continue; >- >- IMenuManager menuManager = viewPart.getViewSite().getActionBars().getMenuManager(); >- if (menuManager != null && menuManager instanceof MenuManager && searchForMenuItem(((MenuManager)menuManager).getMenu(), menuItem)) >- return viewPart; >- } >- } >- >- return null; >- } >- >- private static boolean searchForMenuItem(Menu menu, MenuItem menuItem) >- { >- if (menu == null) >- return false; >- >- MenuItem[] items = menu.getItems(); >- for (int i = 0; i < items.length; i++) >- { >- if (items[i] == menuItem) >- return true; >- Menu cascadeMenu = items[i].getMenu(); >- if (cascadeMenu != null && searchForMenuItem (cascadeMenu, menuItem)) >- return true; >- } >- >- return false; >- } >- >- >- /** >- * @param toolItem >- * @return >- */ >- private static String getDisplayName(ToolItem toolItem) >- { >- String name = toolItem.getText(); >- >- if (name != null && !name.equals(MacroConstants.EMPTY_STRING)) >- { >- return name; >- } >- >- name = toolItem.getToolTipText(); >- >- if (name != null) >- { >- return name; >- } >- >- return "unknown"; //$NON-NLS-1$ >- } >- >- /** >- * Returns an identifier for the given MenuItem, based on its user-readable >- * strings >- * >- * @param menuItem >- * @return >- */ >- private static String getDisplayName(MenuItem menuItem) >- { >- if (menuItem.getParent() == null || menuItem.getParent().getParentItem() == null) >- { >- return removeChar(menuItem.getText(), '&'); >- } >- >- return getDisplayName(menuItem.getParent()) + "/" //$NON-NLS-1$ >- + removeChar(menuItem.getText(), '&'); >- } >- >- /** >- * Returns an identifier for the given Menu, based on its user-readable >- * strings >- * >- * @param menu >- * @return >- */ >- private static String getDisplayName(Menu menu) >- { >- >- MenuItem parentItem = menu.getParentItem(); >- >- if (parentItem == null) >- { >- return MacroConstants.EMPTY_STRING; >- } >- >- return getDisplayName(parentItem); >- } >- >- >- /** >- * Defect #: 112668 This method is invoked to retrieve the id of a menu item. >- * Here's the policy that it employs: >- * <ol> >- * <li> Use the contributed widget resolvers </li> >- * <li> If failed, default to what was being used before </li> >- * </ol> >- * >- * @param item The menu item >- * @return The id of the passed item. >- */ >- public static IWidgetId determineItemId (Item item) >- { >- IWidgetId menuItemIdObj = MacroManager.getInstance().resolveWidget(item, null, newCounter()); >- >- /* Give a chance for contributors to resolve the menu item */ >- if (menuItemIdObj != null) >- return menuItemIdObj; >- >- if (item instanceof ToolItem) >- { >- return getActionId((ToolItem)item); >- } >- else if (item instanceof MenuItem) >- { >- return getActionId((MenuItem)item); >- } >- else if (item instanceof IContributionItem) >- { >- return getActionId((IContributionItem)item); >- } >- return null; >- } >- >- >- /** >- * Walks through all parent menus of the menuItem and returns an index of format >- * <num>|<num>|<num>|... For example assuming menuItem is >- * placed as follows: >- * >- * item 1 >- * |_item 2 >- * | |_item 4 >- * |_item 3 >- * |_menuItem >- * >- * then its respective index will be 1|2|1 >- * >- * @param menuItem The menu item whose index will be determined >- * @return The index of the menu item as described above. >- */ >- public static String findMenuItemIndex(MenuItem menuItem, String menuInx) >- { >- if (menuItem == null) >- return menuInx; >- >- if (menuInx.length() > 0) >- menuInx = "|" + menuInx; >- menuInx = menuItem.getParent().indexOf(menuItem) + menuInx; >- return findMenuItemIndex(menuItem.getParent().getParentItem(), menuInx); >- } >- >- > /* > * (non-Javadoc) > * > * @see org.eclipse.instrumentation.IDataProvider#getDefaultValue(org.eclipse.core.runtime.IPath) > */ >- public Object getDefaultValue(IPath node) >- { >+ public Object getDefaultValue(IPath node) { > return null; > } > >- private MenuItem getMenuItem(Menu menu, IPath menuPath) >- { >- if (menuPath.isEmpty()) >- { >+ private MenuItem getMenuItem(Menu menu, IPath menuPath) { >+ if (menuPath.isEmpty()) { > return null; > } > > String toFind = menuPath.segment(0); > MenuItem[] items = menu.getItems(); > >- for (int idx = 0; idx < items.length; idx++) >- { >+ for (int idx = 0; idx < items.length; idx++) { > MenuItem item = items[idx]; > >- String itemName = removeChar(item.getText(), '&'); >+ String itemName = removeChar(item.getText(), >+ '&'); > >- if (itemName.equals(toFind)) >- { >- return getMenuItem(item, menuPath.removeFirstSegments(1)); >+ if (itemName.equals(toFind)) { >+ return getMenuItem(item, >+ menuPath.removeFirstSegments(1)); > } > } > > return null; > } > >- private MenuItem getMenuItem(MenuItem menu, IPath menuPath) >- { >- if (menuPath.isEmpty()) >- { >+ private MenuItem getMenuItem(MenuItem menu, IPath menuPath) { >+ if (menuPath.isEmpty()) { > return menu; > } > > Menu subMenu = menu.getMenu(); >- if (subMenu == null) >- { >+ if (subMenu == null) { > return null; > } > >- return getMenuItem(subMenu, menuPath); >+ return getMenuItem(subMenu, >+ menuPath); > > } > >- public static String removeChar(String input, char toRemove) >- { >- StringBuffer buf = new StringBuffer(input.length()); >- >- int last = 0; >- for (int pos = input.indexOf(toRemove); pos != -1; pos = input.indexOf(toRemove, last)) >- { >- buf.append(input.substring(last, pos)); >- last = pos + 1; >- } >- >- buf.append(input.substring(last, input.length())); >+ public static void forceMenuClosed(Menu menu) { >+ Event e = new Event(); >+ e.type = SWT.Hide; >+ e.widget = menu; >+ >+ menu.notifyListeners(e.type, e); >+ processDisplayEvents(menu.getDisplay()); >+ } > >- return buf.toString(); >+ public static void forceMenuOpen(Menu menu) { >+ Event e = new Event(); >+ e.type = SWT.Show; >+ e.widget = menu; >+ >+ menu.notifyListeners(e.type, e); >+ processDisplayEvents(menu.getDisplay()); > } > >- public static String getAttribute(Node node, String name) >- { >+ public static String getAttribute(Node node, String name) { > Node value = node.getAttributes().getNamedItem(name); > if (value != null) > return value.getNodeValue(); > return null; > } > >- > /** > * Adds an XML element to the string buffer passed in. > * >- * @param stringBuffer The string buffer that the element will be written to >- * @param indent The number of indents that should be prefixed to the element written >- * @param elementName The element name >- * @param close Indicates whether this element should be closed or not. If set, >- * a forward slash is added before theelement is ended. >- * @param end Indicates if the element should be ended with a closed angle bracket. >- * For example elements requring attributes are not ended. >- */ >- public static void addElement (StringBuffer stringBuffer, int indent, String elementName, boolean close, boolean end) >- { >- addIndent(stringBuffer, indent); >+ * @param stringBuffer >+ * The string buffer that the element will be written to >+ * @param indent >+ * The number of indents that should be prefixed to the element written >+ * @param elementName >+ * The element name >+ * @param close >+ * Indicates whether this element should be closed or not. If set, a forward slash is added before theelement is ended. >+ * @param end >+ * Indicates if the element should be ended with a closed angle bracket. For example elements requring attributes are not ended. >+ */ >+ public static void addElement(StringBuffer stringBuffer, int indent, String elementName, boolean close, boolean end) { >+ addIndent(stringBuffer, >+ indent); > stringBuffer.append(MacroConstants.OPEN_ANGLE_BRACKET); >- stringBuffer.append(close ? MacroConstants.FORWARD_SLASH : MacroConstants.EMPTY_STRING); >+ stringBuffer.append(close >+ ? MacroConstants.FORWARD_SLASH >+ : MacroConstants.EMPTY_STRING); > stringBuffer.append(elementName); >- stringBuffer.append(end ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR: MacroConstants.EMPTY_STRING); >+ stringBuffer.append(end >+ ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR >+ : MacroConstants.EMPTY_STRING); > } > >- > /** >- * Adds XML attributes to the string buffer passed in. Attributes with a null value will >- * not be written. >+ * Adds XML attributes to the string buffer passed in. Attributes with a null value will not be written. > * > * Pre-condition: > * <ul> >- * <li> attributes and attributeValues must be valid (i.e. non-null) </li> >- * <li> attributes and attributeValues length must be the same </li> >+ * <li> attributes and attributeValues must be valid (i.e. non-null) </li> >+ * <li> attributes and attributeValues length must be the same </li> > * </ul> >- * >- * @param stringBuffer The string buffer that the attributes will be written to >- * @param attributeNames The attribute names >- * @param attributeValues The attribute values >- * @param close If set, a forward slash is added after the attributes. >- * @param end If set, a closed angle bracket is added after the attributes >- */ >- public static void addAttribute(StringBuffer stringBuffer, String[] attributeNames, String[] attributeValues, boolean close, boolean end) >- { >- for (int i = 0; i < attributeValues.length; i++) >- { >- if (attributeValues[i] == null) >- { >+ * >+ * @param stringBuffer >+ * The string buffer that the attributes will be written to >+ * @param attributeNames >+ * The attribute names >+ * @param attributeValues >+ * The attribute values >+ * @param close >+ * If set, a forward slash is added after the attributes. >+ * @param end >+ * If set, a closed angle bracket is added after the attributes >+ */ >+ public static void addAttribute(StringBuffer stringBuffer, String[] attributeNames, String[] attributeValues, boolean close, boolean end) { >+ for (int i = 0; i < attributeValues.length; i++) { >+ if (attributeValues[i] == null) { > continue; > } > stringBuffer.append(MacroConstants.SINGLE_SPACE); >@@ -843,26 +335,24 @@ > stringBuffer.append(XMLUtil.useXMLSymbols(attributeValues[i])); > stringBuffer.append(MacroConstants.DOUBLE_QUOTE); > } >- >- stringBuffer.append(close ? MacroConstants.FORWARD_SLASH : MacroConstants.EMPTY_STRING); >- stringBuffer.append(end ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR : MacroConstants.EMPTY_STRING); >+ >+ stringBuffer.append(close >+ ? MacroConstants.FORWARD_SLASH >+ : MacroConstants.EMPTY_STRING); >+ stringBuffer.append(end >+ ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR >+ : MacroConstants.EMPTY_STRING); > } >- >- >- public static void addIndent (StringBuffer stringBuffer, int indent) >- { >- for (int i = 0; i < indent; i++) >- { >+ >+ public static void addIndent(StringBuffer stringBuffer, int indent) { >+ for (int i = 0; i < indent; i++) { > stringBuffer.append("\t"); > } > } >- >- >- public static boolean isIgnorableEvent(Event e) >- { >+ >+ public static boolean isIgnorableEvent(Event e) { > Shell shell = e.display.getActiveShell(); >- if (shell != null) >- { >+ if (shell != null) { > Boolean ivalue = (Boolean) shell.getData(MacroManager.IGNORE); > if (ivalue != null && ivalue.equals(Boolean.TRUE)) > return true; >@@ -870,444 +360,434 @@ > return false; > } > >- public static Control getFirstChild(IWorkbenchPart part) >- { >- Composite partControl = MacroObjectLocator.getWorkbenchPartControl(part); >+ public static Control getFirstChild(IWorkbenchPart part) { >+ Composite partControl = getWorkbenchPartControl(part); > return partControl.getChildren()[0]; > } > > /** >- * Given a context id, return the focus type. >- * >- * @param contextId >- * The id of the context >- * @return The type of the context (i.e. focus type). -1 is returned if the >- * focus type is not recognized. >+ * We have to use internal APIs here to get the controls of a part > */ >- public static byte findFocusType(String contextId) >- { >- if (contextId.startsWith(MacroConstants.VIEW_VALUE + "/")) >- return VerificationMetaData.VIEW; >- else if (contextId.startsWith(MacroConstants.EDITOR_VALUE + "/")) >- return VerificationMetaData.EDITOR; >- else if (contextId.startsWith(MacroConstants.SHELL_VALUE + "/")) >- return VerificationMetaData.SHELL; >- >- return -1; >- } >- >- /** >- * Return the class name containing the verification point that this meta >- * data points to. >- * >- * @param metaData >- * The verification point's meta data >- * @return The class name. null is returned if it can't be determined >- */ >- public static String getClassName(VerificationMetaData metaData) >- { >- String className = metaData.getResource(); >- >- if (className == null || className.length() <= 0) >- return null; >- >- int index = className.lastIndexOf('.'); >- if (index != -1) >- return className.substring(index + 1, className.length()); >- return className; >+ public static Composite getWorkbenchPartControl(IWorkbenchPart part) { >+ IWorkbenchPartTestable testable = (IWorkbenchPartTestable) part.getSite().getAdapter(IWorkbenchPartTestable.class); >+ return testable.getControl().getParent(); > } > > /** >- * Find the method name corresponding the verification hook >+ * If str.length() is greater than bound, then the first bound letters of str is returned followed by "..."; otherwise str is returned. > * >- * @param metaData >- * @return >- */ >- public static String findMethodName(VerificationMetaData metaData) >- { >- String methodName = metaData.getHook(); >- >- if (methodName == null || methodName.length() <= 0) >- return null; >- >- int index = methodName.indexOf(':'); >- if (index != -1) >- return methodName.substring(0, index); >- >- return methodName; >- } >- >- /** >- * Find the parameter types of the verificaiton hook >- * >- * @param metaData >- * @return >- */ >- public static Class[] findParameterType(VerificationMetaData metaData) >- { >- Class param = null; >- if (metaData.getFocusType() == VerificationMetaData.EDITOR) >- param = IEditorPart.class; >- else if (metaData.getFocusType() == VerificationMetaData.VIEW) >- param = IViewPart.class; >- else if (metaData.getFocusType() == VerificationMetaData.SHELL) >- param = Shell.class; >- >- if (param != null) >- return new Class[] { param }; >- >- return null; >- } >- >- >- /** >- * If str.length() is greater than bound, then the first bound letters >- * of str is returned followed by "..."; otherwise str is returned. >- * >- * @param str The string to bound >- * @param bound The bound >+ * @param str >+ * The string to bound >+ * @param bound >+ * The bound > * @return A bounded version of str > */ >- public static String boundSize(String str, int bound) >- { >+ public static String boundSize(String str, int bound) { > if (str == null || str.length() <= bound) > return str; >- >- return str.substring(0, bound) + "..."; >+ >+ return str.substring(0, >+ bound) + "..."; > } >- > >- > /** >- * "Cleans" up the descriptive fields. For example, it removes the '&' sign that is usually included >- * as part of button labels. >+ * "Cleans" up the descriptive fields. For example, it removes the '&' sign that is usually included as part of button labels. > * >- * @param descriptiveField The descriptive field >+ * @param descriptiveField >+ * The descriptive field > * @return A "cleaned" up version of the descriptive field. > */ >- public static String normalizeDescriptiveField(String descriptiveField) >- { >+ public static String normalizeDescriptiveField(String descriptiveField) { > if (descriptiveField == null || descriptiveField.length() <= 0) > return descriptiveField; >- >- /* This array holds character array that are of length two. The first item is the unwanted character and the second >- * item is the replacement character. */ >- final char[][] UNWANTED_CHARACTERS = new char[][] {new char[]{'&', 0}, new char[]{'\t', ' '}, new char[]{'\n', ' '}, new char[]{'\r', ' '}}; >+ >+ /* >+ * This array holds character array that are of length two. The first item is the unwanted character and the second item is the replacement >+ * character. >+ */ >+ final char[][] UNWANTED_CHARACTERS = >+ new char[][] {new char[] {'&', 0}, new char[] {'\t', ' '}, new char[] {'\n', ' '}, new char[] {'\r', ' '}}; > String cleanDescription = ""; > char currentCharacter; > boolean isUnwantedChar; >- for (int i = 0, descriptionLength = descriptiveField.length(); i < descriptionLength; i++) >- { >+ for (int i = 0, descriptionLength = descriptiveField.length(); i < descriptionLength; i++) { > currentCharacter = descriptiveField.charAt(i); > isUnwantedChar = false; >- >- for (int j = 0; j < UNWANTED_CHARACTERS.length; j++) >- { >- if (currentCharacter == UNWANTED_CHARACTERS[j][0]) >- { >+ >+ for (int j = 0; j < UNWANTED_CHARACTERS.length; j++) { >+ if (currentCharacter == UNWANTED_CHARACTERS[j][0]) { > if (UNWANTED_CHARACTERS[j][1] > 0) > cleanDescription += UNWANTED_CHARACTERS[j][1]; >- >+ > isUnwantedChar = true; > break; > } > } >- >+ > if (!isUnwantedChar) > cleanDescription += currentCharacter; > } >- >+ > return cleanDescription; > } >- >- public static void closeWelcomePage() >- { >+ >+ public static void closeWelcomePage() { > IIntroManager introManager = GuiPlugin.getDefault().getWorkbench().getIntroManager(); > IIntroPart introPart = introManager.getIntro(); > if (introPart != null) > introManager.closeIntro(introPart); > } > >- >- public static void maximizeWorkbench() >- { >+ public static void maximizeWorkbench() { > IWorkbench workbench = GuiPlugin.getDefault().getWorkbench(); > Shell workbenchShell = workbench.getActiveWorkbenchWindow().getShell(); > Rectangle clientArea = workbench.getDisplay().getClientArea(); >- workbenchShell.setLocation (0, 0); >+ workbenchShell.setLocation(0, >+ 0); > workbenchShell.setSize(new Point(clientArea.width, clientArea.height)); > workbenchShell.redraw(); > } >- public static void clearWorkbenchPartListeners() >- { >- workbenchPartListeners.clear(); >- } >- >- >- private static class WorkbenchPartListener implements IPartListener >- { > >- public void partActivated(IWorkbenchPart part) >- { >- /* Doesn't need to be implemented */ >- } >- >- public void partBroughtToTop(IWorkbenchPart part) >- { >- /* Doesn't need to be implemented */ >- } >- >- /** >- * This method will generate a close workbench part command. We can't determine for sure through >- * events reported by a display of when a workbench part is closed. This part listener is >- * a work around that allows us to capture close events on workbench parts. >- * >- * @param part The part is closed. >- */ >- public void partClosed(IWorkbenchPart part) >- { >- Macro currentMacro = MacroManager.getInstance().getCurrentMacro(); >- Event event = new Event(); >- >- event.type = Macro.WORKBENCH_PART_CLOSED; >- event.data = part; >- event.display = part.getSite().getShell().getDisplay(); >- if (currentMacro != null) >- { >- try >- { >- currentMacro.addEvent(event); >- } >- catch (Exception e) >- { >- /* Ignore the error. It doesn't generate the command */ >- e.printStackTrace(); >- } >- } >- } >- >- public void partDeactivated(IWorkbenchPart part) >- { >- /* Doesn't need to be implemented */ >- } >- >- public void partOpened(IWorkbenchPart part) >- { >- /* Doesn't need to be implemented */ >- } >- >+ public static void clearWorkbenchPartListeners() { >+ workbenchPartListeners.clear(); > } > >- public static WidgetIdentifier getCustomEventIdentifier(Event event) >- { >- if (event.type == Macro.WORKBENCH_PART_CLOSED) >- { >- IWorkbenchPart part = (IWorkbenchPart)event.data; >+ public static IMacroObjectIdentifier getCustomEventIdentifier(Event event) { >+ if (event.type == EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) { >+ IWorkbenchPart part = (IWorkbenchPart) event.data; > String partId = part.getSite().getId(); >- >+ > /* The path to the context */ > IPath contextId = null; > IPath partIdPath = null; >- if (part instanceof IViewPart) >- { >+ if (part instanceof IViewPart) { > contextId = new Path(MacroConstants.VIEW_VALUE); > partIdPath = new Path(partId); > } >- else if (part instanceof IEditorPart) >- { >+ else if (part instanceof IEditorPart) { > contextId = new Path(MacroConstants.EDITOR_VALUE); >- partIdPath = new Path(partId).append(((IEditorPart)part).getEditorInput().getName()); >+ partIdPath = new Path(partId).append(((IEditorPart) part).getEditorInput().getName()); >+ } >+ >+ if (contextId != null && partId != null) { >+ return new MacroObjectIdentifier(contextId.toString(), new PrimitiveUIObjectIdentifier(partIdPath.toString(), null)); > } >- >- if (contextId != null && partId != null) >- return new WidgetIdentifier (contextId, partIdPath, null); > } > return null; > } > >- >- /* Returns an identifier for the verification hook context */ >- public static WidgetIdentifier getVerificationContextIdentifier(Event event) >- { >- /* See if the context is an editor or a view */ >- Control control = null; >- if (event.widget instanceof Control) >- { >- control = (Control)event.widget; >- WidgetIdentifier widgetId = getControlIdentifier(control); >- if (widgetId != null) >- { >- String firstSegment = new Path(widgetId.getContextId().toString()).segment(0); >- if (firstSegment.equals(MacroConstants.VIEW_VALUE) || firstSegment.equals(MacroConstants.EDITOR_VALUE)) >- return widgetId; >- } >- } >- >- /* It's not an editor or a view. See if it's a shell */ >- Shell shellFound = null; >- if (event.widget instanceof Shell) >- shellFound = (Shell) event.widget; >- else if (control != null) >- shellFound = control.getShell(); >- >- /* Make sure that the shell is not the workbench shell */ >- if (shellFound == null || GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().equals(shellFound)) >- return null; >- >- IWidgetId shellPath = getShellId(shellFound, null); >- if (shellPath.toString().length() <= 0) >- return null; >- >- return new WidgetIdentifier (new Path(MacroConstants.SHELL_VALUE).append(shellPath.toString()), null, shellPath.getResolverId()); >- } >- >- > /** >- * This method is provided to close any nested shells that a test case may have >- * activated. >+ * This method is provided to close any nested shells that a test case may have activated. > */ >- public static void closeSecondaryShells(final Display display) >- { >- display.syncExec(new Runnable(){ >- public void run() >- { >+ public static void closeSecondaryShells(final Display display) { >+ display.syncExec(new Runnable() { >+ >+ public void run() { > Shell[] shells = display.getShells(); >- for (int i = 0; i < shells.length; i++) >- { >+ for (int i = 0; i < shells.length; i++) { > if (!shells[i].isDisposed() && shells[i].getData(GlobalConstants.OPENED_SHELL_INDICATOR) == null) > shells[i].close(); >- } >+ } > } > }); > } >- >- public static void processDisplayEvents(Display display) >- { >- for (int i = 0;;i++) >- { >+ >+ public static void processDisplayEvents(Display display) { >+ for (int i = 0;; i++) { > if (!display.readAndDispatch()) > break; > } > } >- >- >- public static XMLDefaultHandler createXMLDocument (InputStream is) throws CoreException, SAXException, IOException >- { >+ >+ public static XMLDefaultHandler createXMLDocument(InputStream is) throws CoreException, SAXException, IOException { > XMLDefaultHandler handler = null; >- try >- { >+ try { > SAXParser parser = getParser(); > handler = new XMLDefaultHandler(); >- parser.parse(is, handler); >+ parser.parse(is, >+ handler); > } >- finally >- { >- try >- { >+ finally { >+ try { > is.close(); > } >- catch (IOException e) >- { >+ catch (IOException e) { > } > } >- >+ > return handler; > } >- >- private static SAXParser getParser() throws CoreException >- { >- if (parser == null) >- { >- try >- { >+ >+ private static SAXParser getParser() throws CoreException { >+ if (parser == null) { >+ try { > return SAXParserFactory.newInstance().newSAXParser(); > } >- catch (ParserConfigurationException e) >- { >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e); >- } >- catch (SAXException e) >- { >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e); >+ catch (ParserConfigurationException e) { >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, >+ e.getLocalizedMessage()), >+ 0, >+ e); >+ } >+ catch (SAXException e) { >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, >+ e.getLocalizedMessage()), >+ 0, >+ e); > } > } > return parser; > } > >- >- private static PrimitiveWidgetId getActionId(IContributionItem contrib) >- { >- String id = null; >- PrimitiveWidgetId widgetId = new PrimitiveWidgetId(); >- >- if (contrib instanceof IPluginContribution) >- { >- id = ((IPluginContribution) contrib).getLocalId(); >- } >- id = id == null ? contrib.getId() : id; >- if (id != null) >- { >- widgetId.setId("contribid/" + id); //$NON-NLS-1$ >- } >- else >- { >- if (contrib instanceof ActionContributionItem) >- { >- ActionContributionItem actionItem = (ActionContributionItem) contrib; >- id = actionItem.getId(); >- if (id != null) >- { >- widgetId.setId("actionid/" + id); //$NON-NLS-1$ >- } >- else >- { >- IAction action = actionItem.getAction(); >- id = action.getActionDefinitionId(); >- if (id != null) >- { >- widgetId.setId("defid/" + id); //$NON-NLS-1$ >- } >- else >- { >- widgetId.setId("actionclass/" + action.getClass().getName()); //$NON-NLS-1$ >- } >+ public static String removeChar(String input, char toRemove) { >+ StringBuffer buf = new StringBuffer(input.length()); >+ >+ int last = 0; >+ for (int pos = input.indexOf(toRemove); pos != -1; pos = input.indexOf(toRemove, >+ last)) { >+ buf.append(input.substring(last, >+ pos)); >+ last = pos + 1; >+ } >+ >+ buf.append(input.substring(last, >+ input.length())); >+ >+ return buf.toString(); >+ } >+ >+ /** >+ * @param menuItem >+ * @return >+ */ >+ public static boolean onMenubar(MenuItem menuItem) { >+ Menu parent = menuItem.getParent(); >+ MenuItem parentItem = parent.getParentItem(); >+ >+ if (parentItem != null) { >+ return onMenubar(parentItem); >+ } >+ >+ Shell theShell = parent.getShell(); >+ return parent == theShell.getMenuBar(); >+ } >+ >+ public static ContributionManager onToolbar(ToolItem toolItem) { >+ ToolBar toolBar = toolItem.getParent(); >+ Shell shell = toolBar.getShell(); >+ Object data = shell.getData(); >+ if (data instanceof ApplicationWindow) { >+ ApplicationWindow window = (ApplicationWindow) data; >+ ToolBarManager mng = window.getToolBarManager(); >+ if (mng != null) { >+ if (mng.getControl() != null && mng.getControl() == toolBar) >+ return mng; >+ } >+ CoolBarManager cmng = window.getCoolBarManager(); >+ if (cmng != null) { >+ CoolBar cbar = cmng.getControl(); >+ Composite parent = toolBar.getParent(); >+ while (parent != null) { >+ if (parent == cbar) >+ return cmng; >+ parent = parent.getParent(); > } > } >- else >- { >- widgetId.setId("contribclass/" + contrib.getClass().getName()); //$NON-NLS-1$ >+ } >+ return null; >+ } >+ >+ public static IViewPart onWorkbenchPartToolbar(MenuItem menuItem) { >+ IWorkbenchPage[] pages = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getPages(); >+ >+ /* For evey page */ >+ for (int i = 0; i < pages.length; i++) { >+ IViewReference[] viewReferences = pages[i].getViewReferences(); >+ >+ /* For evey opened view */ >+ for (int j = 0; j < viewReferences.length; j++) { >+ IViewPart viewPart = viewReferences[j].getView(false); >+ if (viewPart == null) >+ continue; >+ >+ IMenuManager menuManager = viewPart.getViewSite().getActionBars().getMenuManager(); >+ if (menuManager != null && menuManager instanceof MenuManager && searchForMenuItem(((MenuManager) menuManager).getMenu(), >+ menuItem)) >+ return viewPart; > } > } >- >- return widgetId; >+ >+ return null; > } > >+ private static boolean searchForMenuItem(Menu menu, MenuItem menuItem) { >+ if (menu == null) >+ return false; >+ >+ MenuItem[] items = menu.getItems(); >+ for (int i = 0; i < items.length; i++) { >+ if (items[i] == menuItem) >+ return true; >+ Menu cascadeMenu = items[i].getMenu(); >+ if (cascadeMenu != null && searchForMenuItem(cascadeMenu, >+ menuItem)) >+ return true; >+ } > >+ return false; >+ } >+ > /** >- * @param widget >+ * @param wd >+ * @param control > * @return > */ >- public static IWidgetId getActionId(Widget widget) >- { >- Object data = widget.getData(); >- PrimitiveWidgetId widgetId = new PrimitiveWidgetId(); >- if (data != null && (data instanceof IContributionItem)) >- { >- widgetId = getActionId((IContributionItem) data); >- if (!widgetId.toString().equals(MacroConstants.EMPTY_STRING)) >- { >- if (widget instanceof MenuItem) >- { >- String menuInx = findMenuItemIndex((MenuItem)widget, ""); >- widgetId.setId(widgetId.toString() + menuInx); >+ public static boolean onWizardDialog(WizardDialog wd, Button control) { >+ // see if we have a button on the wizard page or on the wizard dialog (i.e. wizard) >+ IWizardPage page = wd.getCurrentPage(); >+ Shell shell = control.getShell(); >+ Control pageControl = page.getControl(); >+ IUIObjectIdentifier relativePath = NonTrivialUIObjectResolverDelegate.computeRelativePath( >+ (Composite) pageControl, >+ null, >+ control); >+ if (relativePath != null) { >+ return false; >+ } >+ // check for wizard buttons >+ if (control instanceof Button) { >+ relativePath = NonTrivialUIObjectResolverDelegate.computeRelativePath( >+ shell, >+ (Composite) pageControl, >+ control); >+ return true; >+ } >+ return false; >+ >+ } >+ >+ /** >+ * Used to located the editor part with the passed id. >+ * >+ * @param shell >+ * The current shell >+ * @param id >+ * The id of the editor part >+ * @param line >+ * The line number of the script (used to indicate the line number if we throw a core exception. Mark as -1 if a script is not being >+ * used) >+ * @param input >+ * If not null, then it attempts to match the input of the identified editor with the input that is passed it. >+ * >+ * @return The editor part with the passed 'id' >+ * >+ * @throws CoreException >+ * If the editor part cannot be located. >+ */ >+ public static IEditorPart locateEditor(Shell shell, String id, String input) throws CoreException { >+ Object data = shell.getData(); >+ IEditorPart editor = null; >+ >+ try { >+ if (data instanceof IWorkbenchWindow) { >+ IWorkbenchWindow window = (IWorkbenchWindow) data; >+ IWorkbenchPage page = window.getActivePage(); >+ >+ if (page != null) { >+ IEditorReference[] erefs = page.getEditorReferences(); >+ >+ for (int i = 0; i < erefs.length; i++) { >+ IEditorReference eref = erefs[i]; >+ if (eref.getId().equals(id)) { >+ // check the input >+ IEditorPart part = eref.getEditor(true); >+ if (input == null) { >+ editor = part; >+ break; >+ } >+ else if (part.getEditorInput().getName().equals(input)) { >+ editor = part; >+ break; >+ } >+ } >+ } >+ } >+ } >+ } >+ catch (Throwable t) { >+ >+ } >+ if (editor != null) { >+ editor.getSite().getPage().activate(editor); >+ return editor; >+ } >+ >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR, >+ id)); >+ return null; >+ } >+ >+ /** >+ * Used to located the view part with the passed id. >+ * >+ * @param shell >+ * The current shell >+ * @param id >+ * The id of the view part >+ * @param line >+ * The line number of the script (used to indicate the line number if we throw a core exception. Mark as -1 if a script is not being >+ * used) >+ * >+ * @return The view part with the passed 'id' >+ * >+ * @throws CoreException >+ * If the view part cannot be located. >+ */ >+ public static IViewPart locateView(Shell shell, String id) throws CoreException { >+ try { >+ Object data = shell.getData(); >+ >+ if (data instanceof IWorkbenchWindow) { >+ IWorkbenchWindow window = (IWorkbenchWindow) data; >+ IWorkbenchPage page = window.getActivePage(); >+ if (page != null) { >+ IViewPart view = page.findView(id); >+ >+ if (view == null) { >+ try { >+ view = page.showView(id); >+ >+ } >+ catch (PartInitException pie) { >+ /* Do a thorough search */ >+ IWorkbenchWindow[] windows = GuiPlugin.getDefault().getWorkbench().getWorkbenchWindows(); >+ >+ /* For every workbench window */ >+ for (int i = 0; i < windows.length && view == null; i++) { >+ /* For every page of a workbench window */ >+ IWorkbenchPage[] pages = windows[i].getPages(); >+ for (int j = 0; j < pages.length && view == null; j++) { >+ view = pages[j].findView(id); >+ >+ } >+ } >+ // need to mke sure that even if it is found in another page, we show it. >+ >+ } >+ } >+ // added for defcet 175320 in order to ensure the page is >+ // given focus no matter where it is found >+ page.showView(id); >+ return view; > } > } > } >- else >- { >- widgetId.setId("readablename/" + ((widget instanceof MenuItem) ? getDisplayName((MenuItem)widget) : getDisplayName((ToolItem)widget))); //$NON-NLS-1$ >+ catch (Throwable t) { >+ /* The next line will throw an exception */ > } >- >- return widgetId; >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW, >+ id)); >+ return null; > } >+ > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroConstants.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroConstants.java,v >retrieving revision 1.1 >diff -u -r1.1 MacroConstants.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroConstants.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroConstants.java 26 Jul 2008 19:22:11 -0000 >@@ -40,20 +40,21 @@ > public static final String OBJECT_ELEMENT = "object"; > public static final String ITEM_ELEMENT = "item"; > public static final String SELECT_ITEM_ELEMENT = "selected-item"; >- public static final String PARENT_ELEMENT = "parent"; >+ //ANy: was never used: public static final String PARENT_ELEMENT = "parent"; > > /** XML Attributes */ > public static final String DESCRIPTIVE_ATTRIBUTE = "descriptive"; > public static final String TYPE_ATTRIBUTE = "type"; > public static final String CONTEXT_ID_ATTRIBUTE = "contextId"; >- public static final String WIDGET_ID_ATTRIBUTE = "widgetId"; >+ public static final String WIDGET_ID_ATTRIBUTE = "widgetId"; >+ public static final String OBJECT_ID_ATTRIBUTE = "objectId"; > public static final String ID_ATTRIBUTE = "id"; > public static final String RETURN_CODE_ATTRIBUTE = "return-code"; > public static final String TIME_TO_WAIT_ATTRIBUTE = "time-to-wait"; > public static final String OUTPUT_ATTRIBUTE = "output"; > public static final String PATH_ATTRIBUTE = "path"; > public static final String REFERENCE_ID_ATTRIBUTE = "referenceId"; >- public static final String RESOLVER_ATTRIBUTE = "resolverId"; >+ public static final String RESOLVER_ID_ATTRIBUTE = "resolverId"; > public static final String VERSION_ATTRIBUTE = "version"; > public static final String X_COORD_ATTRIBUTE = "x-coord"; > public static final String Y_COORD_ATTRIBUTE = "y-coord"; >@@ -75,7 +76,16 @@ > public static final String LOCAL_TOOLBAR_MENU_VALUE = "local-toolbar-menu"; > public static final String TOOLBAR_VALUE = "toolbar"; > public static final String LOCAL_TOOLBAR_VALUE = "local-toolbar"; >+ public static final String TAB_VALUE = "tab"; // ANy: introduced for TabItems and CTabItems > public static final String WIZARD_VALUE = "wizard"; > public static final String WIZARD_PAGE_VALUE = "wizard-page"; > >+ >+ public static final String RESOLVER_ID_SUFFIX_SEPARATOR = "@@@"; >+ public static final String WIDGET_ID_SUFFIX_SEPARATOR = "%%%"; >+ public static final String OBJECT_ID_SUFFIX_SEPARATOR = "$$$"; >+ public static final String WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR = "!!!"; >+ >+ >+ > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMine.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMine.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMine.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMine.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,569 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.macro; >- >-import java.util.ArrayList; >-import java.util.Hashtable; >-import java.util.LinkedList; >-import java.util.List; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.w3c.dom.NamedNodeMap; >-import org.w3c.dom.Node; >- >- >-/** >- * A concrete implementation of IObjectMine. >- * >- * @author Ali Mehregani >- */ >-public class ObjectMine implements IObjectMine >-{ >- /** The root node of the tree structure that contains the objects */ >- private IUIObject root; >- >- /** Included object mines */ >- private ArrayList includes; >- >- /** The test suite that owns this object mine */ >- private ITestSuite owner; >- >- /** The output object mine */ >- private IObjectMine outputObjectMine; >- >- /** The active object */ >- private IUIObject activeObject; >- >- /** Keeps track of the maximum reference id in use. This is used to generate a unique >- * reference id when requested */ >- private int maximumRefId; >- >- /** The xml handler used to parse the object mine */ >- private XMLDefaultHandler defaultXMLHandler; >- >- >- public ObjectMine (ITestSuite testSuite, XMLDefaultHandler defaultXMLHandler) >- { >- owner = testSuite; >- root = new UIObject(null); >- includes = new ArrayList(); >- this.defaultXMLHandler = defaultXMLHandler; >- } >- >- public void addInclude(IObjectMine objectMine) >- { >- includes.add(objectMine); >- if (outputObjectMine != null) >- { >- IObjectMine foundObjectMine = findIncludedObjectMine(outputObjectMine); >- outputObjectMine = foundObjectMine == null ? outputObjectMine : foundObjectMine; >- } >- } >- >- public IUIObject lookupUIObject(IUIObject parent, String referenceId) >- { >- IUIObject uiObject = lookupIncludes(parent, referenceId); >- if (uiObject != null) >- return uiObject; >- >- uiObject = lookupUIObject(parent); >- if (uiObject == null) >- return null; >- >- uiObject = uiObject.findChild(referenceId); >- return uiObject; >- } >- >- >- >- private IUIObject lookupUIObject(IUIObject object, boolean requiresPresence) throws UIObjectNotFound >- { >- if (object == null) >- { >- return root; >- } >- >- LinkedList relationship = object.getHierarchicalRelation(); >- IUIObject currentNode = root; >- for (int i = 0, height=relationship.size(); currentNode != null && i < height; i++) >- { >- currentNode = currentNode.findChild(((IUIObject)relationship.get(i)).getReferenceId()); >- } >- >- if (currentNode == null && requiresPresence) >- throw new UIObjectNotFound(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, object.getReferenceId())); >- >- return currentNode; >- } >- >- >- public IUIObject lookupUIObject(IUIObject parent, String contextId, String objectId) >- { >- IUIObject uiObject = lookupIncludes(parent, contextId, objectId); >- if (uiObject != null) >- return uiObject; >- >- IUIObject parentNode = lookupUIObject(parent); >- if (parentNode == null) >- return null; >- >- IUIObject[] children = parentNode.getChildren(); >- for (int i = 0; i < children.length; i++) >- { >- if (((contextId == null && children[i].getContextId() == null) || (contextId != null && contextId.equals(children[i].getContextId()))) && >- objectId.equals(children[i].getObjectId())) >- { >- return children[i]; >- } >- >- } >- return null; >- } >- >- public IUIObject[] getChildren() >- { >- return root.getChildren(); >- } >- >- >- >- private IUIObject lookupUIObject (IUIObject parent) >- { >- try >- { >- return lookupUIObject(parent, false); >- } >- catch (UIObjectNotFound e) >- { >- return null; >- } >- } >- >- >- /** >- * Looks up the included object mine to determine if they have a corresponding object >- * with the reference id passed in. >- * >- * @param parent The parent of the object >- * @param referenceId The reference id of the object >- * >- * @return The object with the reference id passed in; null if none is found. >- * @throws UIObjectNotFound In case the parent can't be found. >- */ >- private IUIObject lookupIncludes(IUIObject parent, String referenceId) >- { >- IUIObject[] uiObject = lookupIncludes (parent, referenceId, null, null); >- return uiObject != null && uiObject.length > 0 ? uiObject[0] : null; >- } >- >- >- /** >- * Looks up the included object mine to determine if they have a corresponding object >- * with the contextId id and object id passed in. >- * >- * @param parent The parent of the object >- * @param contextId The context id of the object >- * @param objectId The id of the object >- * >- * @return The object with the matching context and object id passed in; null if none is found. >- * @throws UIObjectNotFound In case the parent can't be found. >- */ >- private IUIObject lookupIncludes(IUIObject parent, String contextId, String objectId) >- { >- IUIObject[] uiObject = lookupIncludes (parent, null, contextId, objectId); >- return uiObject != null && uiObject.length > 0 ? uiObject[0] : null; >- } >- >- >- /** >- * Looks up the included object mines to find an object that has been requested. >- * If reference id happens to be null, then context/object id are used. >- * >- * @param parent The parent of the object >- * @param referenceId The reference id of the object. >- * @param contextId The context id of the object >- * @param objectId The id of the object >- * >- * @return The objects to look for >- */ >- private IUIObject[] lookupIncludes(IUIObject parent, String referenceId, String contextId, String objectId) >- { >- boolean useReferenceId = referenceId != null; >- boolean useObjectId = objectId != null; >- >- IUIObject objectRequested = null; >- IUIObject[] children = null; >- for (int i = 0, includeCount = includes.size(); i < includeCount; i++) >- { >- IObjectMine objectMine = (IObjectMine)includes.get(i); >- if (useReferenceId) >- { >- objectRequested = objectMine.lookupUIObject(parent, referenceId); >- } >- else if (useObjectId) >- { >- objectRequested = objectMine.lookupUIObject(parent, contextId, objectId); >- } >- >- children = objectRequested == null ? children : new IUIObject[] {objectRequested}; >- if (children != null) >- { >- return children; >- } >- } >- >- return null; >- } >- >- >- public IUIObject getRoot() >- { >- return root; >- } >- >- >- public IUIObject registerObject(IUIObject parent, Node objectNode) throws IDCollisionException, UIObjectNotFound, CoreException >- { >- NamedNodeMap attributes = objectNode.getAttributes(); >- IUIObject uiObject = new UIObject(parent); >- >- IUIObject node = lookupUIObject(parent, true); >- >- /* Set the attributes of the object */ >- String referenceIdStr = getAttribute(attributes, MacroConstants.REFERENCE_ID_ATTRIBUTE); >- updateMaxReferenceId(referenceIdStr); >- >- Hashtable lineLevelDetail = null; >- if (defaultXMLHandler != null) >- lineLevelDetail = defaultXMLHandler.getLineTable(); >- uiObject.setReferenceId(referenceIdStr); >- uiObject.setContextId(getAttribute(attributes, MacroConstants.CONTEXT_ID_ATTRIBUTE)); >- uiObject.setObjectId(getAttribute(attributes, MacroConstants.ID_ATTRIBUTE)); >- uiObject.setDescriptive(getAttribute(attributes, MacroConstants.DESCRIPTIVE_ATTRIBUTE)); >- uiObject.setResolver(getAttribute(attributes, MacroConstants.RESOLVER_ATTRIBUTE)); >- if (lineLevelDetail != null) >- uiObject.setData(((Integer[])lineLevelDetail.get(objectNode))); >- node.addChild(uiObject); >- >- return uiObject; >- } >- >- public IUIObject registerObject(IUIObject uiObject) throws IDCollisionException, UIObjectNotFound, CoreException >- { >- updateMaxReferenceId(uiObject.getReferenceId()); >- >- IUIObject parentObject = uiObject.getParent(); >- >- /* If the object that is about to be registered happens to be at the first level (i.e. >- * it is an infant), then it needs to be registered with the output destination of this object mine */ >- if (parentObject == null && outputObjectMine != null) >- { >- outputObjectMine.registerObject(uiObject); >- includes.contains(outputObjectMine); >- return uiObject; >- } >- >- if (parentObject == null) >- { >- root.addChild(uiObject); >- } >- else >- { >- parentObject.addChild(uiObject); >- } >- >- >- return uiObject; >- } >- >- private void updateMaxReferenceId(String referenceIdStr) >- { >- try >- { >- int referenceId = Integer.parseInt(referenceIdStr); >- int maximumIncludedRefId = findMaximumIncludedRefId(); >- maximumRefId = Math.max(Math.max(referenceId, maximumIncludedRefId), maximumRefId); >- >- if (referenceId == maximumRefId) >- maximumRefId++; >- } >- catch (NumberFormatException nfe) >- { >- /* Doesn't need to be handled */ >- } >- } >- >- >- /** >- * Walks through the included object mines of this object mine to determine the >- * unique reference id. >- * >- * @return A unique reference id that is global to all included object mines. >- */ >- private int findMaximumIncludedRefId() >- { >- int uniqueRefId = 0; >- >- for (int i = 0, includeCount = includes.size(); i < includeCount; i++) >- { >- IObjectMine currentObjectMine = (IObjectMine)includes.get(i); >- try >- { >- uniqueRefId = Math.max(Integer.parseInt(currentObjectMine.getUniqueReferenceId()), uniqueRefId); >- } >- catch (NumberFormatException nfe) >- { >- /* Ignore the exception */ >- } >- } >- return uniqueRefId; >- } >- >- private String getAttribute(NamedNodeMap attributes, String attributeName) >- { >- Node attr = attributes.getNamedItem(attributeName); >- return attr == null ? null : attr.getNodeValue(); >- } >- >- public void setOutputSource(IObjectMine objectMine) >- { >- outputObjectMine = objectMine == null ? null : findIncludedObjectMine(objectMine); >- if (outputObjectMine == null) >- outputObjectMine = objectMine; >- } >- >- >- public IObjectMine getOutputSource() >- { >- return outputObjectMine; >- } >- >- >- private IObjectMine findIncludedObjectMine(IObjectMine objectMine) >- { >- for (int i = 0, includeCount = includes.size(); i < includeCount; i++) >- { >- IObjectMine currentObjectMine = (IObjectMine)includes.get(i); >- if (currentObjectMine.equals(objectMine)) >- return currentObjectMine; >- } >- >- return null; >- } >- >- public ITestSuite getOwner() >- { >- return owner; >- } >- >- >- public static class UIObjectNotFound extends Exception >- { >- static final long serialVersionUID = 4699726279267599112L; >- >- public UIObjectNotFound(String message) >- { >- super(message); >- } >- } >- >- >- public static class IDCollisionException extends Exception >- { >- static final long serialVersionUID = -6526030843455792891L; >- >- public IDCollisionException(String message) >- { >- super(message); >- } >- } >- >- >- public String serializeToString() >- { >- StringBuffer objectMineSerialized = new StringBuffer(); >- int indent = 0; >- >- /* <object-mine> */ >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECT_MINE_ELEMENT, false, true); >- >- serializeHeader(objectMineSerialized, indent + 1, true); >- serializeObjects(objectMineSerialized, indent + 1, true); >- >- /* </object-mine> */ >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECT_MINE_ELEMENT, true, true); >- >- return objectMineSerialized.toString(); >- } >- >- >- private void serializeHeader(StringBuffer objectMineSerialized, int indent, boolean includeHeader) >- { >- /* Don't write anything if the header is empty */ >- if (outputObjectMine == null && (includes == null || includes.size() <= 0)) >- return; >- >- boolean outputElement = outputObjectMine != null; >- >- /* <header output="..."/>*/ >- if (includeHeader) >- { >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.HEADER_ELEMENT, false, !outputElement); >- if (outputElement) >- MacroUtil.addAttribute(objectMineSerialized, new String[] {MacroConstants.OUTPUT_ATTRIBUTE}, new String[] {AutoGUIUtil.resolveTestSuitePath(outputObjectMine.getOwner())}, false, true); >- } >- >- /* Add the <include .../> elements */ >- for (int i = 0, includeCount = includes.size(); i < includeCount; i++) >- { >- IObjectMine currentInclude = (IObjectMine)includes.get(i); >- ITestSuite testSuite = currentInclude.getOwner(); >- String path = AutoGUIUtil.resolveTestSuitePath(testSuite); >- >- if (path != null) >- { >- MacroUtil.addElement(objectMineSerialized, indent + 1, MacroConstants.INCLUDE_ELEMENT, false, false); >- MacroUtil.addAttribute(objectMineSerialized, >- new String[] {MacroConstants.PATH_ATTRIBUTE}, >- new String[] {path}, >- true, true); >- } >- } >- >- if (includeHeader) >- { >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.HEADER_ELEMENT, true, true); >- } >- } >- >- >- private void serializeObjects(StringBuffer objectMineSerialized, int indent, boolean includeHeader) >- { >- IUIObject[] rootChildren = root.getChildren(); >- if (rootChildren == null || rootChildren.length <= 0) >- return; >- >- /* Add the objects */ >- if (includeHeader) >- { >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECTS_ELEMENT, false, true); >- addObject(objectMineSerialized, indent + 1, rootChildren); >- MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECTS_ELEMENT, true, true); >- return; >- } >- >- addObject(objectMineSerialized, indent + 1, rootChildren); >- } >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine#serializeHeaderToString() >- */ >- public String serializeHeaderToString() >- { >- StringBuffer sb = new StringBuffer(); >- serializeHeader(sb, 0, false); >- return sb.toString(); >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine#serializeObjetsToString() >- */ >- public String serializeObjetsToString() >- { >- StringBuffer sb = new StringBuffer(); >- serializeObjects(sb, 0, false); >- return sb.toString(); >- } >- >- private void addObject(StringBuffer objectMapSerialized, int indent, IUIObject[] rootChildren) >- { >- if (rootChildren == null) >- return; >- >- for (int i = 0; i < rootChildren.length; i++) >- { >- IUIObject currentUIObject = rootChildren[i]; >- IUIObject[] children = rootChildren[i].getChildren(); >- >- /* If the object is a shell without any children, then skip it */ >- if (currentUIObject.getParent() == null && (children == null || children.length <= 0)) >- continue; >- >- boolean hasChildren = children!= null && children.length > 0; >- MacroUtil.addElement (objectMapSerialized, indent, MacroConstants.OBJECT_ELEMENT, false, false); >- MacroUtil.addAttribute(objectMapSerialized, >- new String[] {MacroConstants.DESCRIPTIVE_ATTRIBUTE, >- MacroConstants.REFERENCE_ID_ATTRIBUTE, >- MacroConstants.CONTEXT_ID_ATTRIBUTE, >- MacroConstants.RESOLVER_ATTRIBUTE, >- MacroConstants.ID_ATTRIBUTE}, >- new String[] {currentUIObject.getDescriptive(), >- currentUIObject.getReferenceId(), >- currentUIObject.getContextId(), >- currentUIObject.getResolverId(), >- currentUIObject.getObjectId()} >- , !hasChildren, true); >- if (hasChildren) >- { >- addObject(objectMapSerialized, indent + 1, rootChildren[i].getChildren()); >- MacroUtil.addElement (objectMapSerialized, indent, MacroConstants.OBJECT_ELEMENT, true, true); >- } >- } >- >- } >- >- >- public IUIObject getActiveObject() >- { >- return activeObject; >- } >- >- public void setActiveObject(IUIObject activeObject) >- { >- this.activeObject = activeObject; >- } >- >- public String getUniqueReferenceId() >- { >- int maximumIncludedRefId = findMaximumIncludedRefId(); >- maximumRefId = Math.max(maximumIncludedRefId, maximumRefId); >- >- /* Restart the reference id */ >- if (maximumRefId >= Integer.MAX_VALUE - 10) >- { >- maximumRefId = 0; >- } >- return String.valueOf(maximumRefId); >- } >- >- public List getIncludes() >- { >- return includes; >- } >- >- public boolean equals(Object o) >- { >- return o instanceof IObjectMine ? getOwner().getId().equals(((IObjectMine)o).getOwner().getId()) : false; >- } >- >- public void setOwner(ITestSuite testSuite) >- { >- this.owner = testSuite; >- } >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroManager.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroManager.java,v >retrieving revision 1.2 >diff -u -r1.2 MacroManager.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroManager.java 4 Dec 2006 02:55:08 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroManager.java 26 Jul 2008 19:22:13 -0000 >@@ -13,11 +13,9 @@ > import java.io.IOException; > import java.io.InputStream; > import java.lang.reflect.InvocationTargetException; >-import java.util.Hashtable; > import java.util.Vector; > > import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.IConfigurationElement; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.NullProgressMonitor; > import org.eclipse.core.runtime.Platform; >@@ -29,23 +27,22 @@ > import org.eclipse.jface.operation.IRunnableContext; > import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.SWT; >-import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Listener; > import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.Widget; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.commands.MacroCommandShell; > import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound; >+import org.eclipse.tptp.test.auto.gui.internal.commands.factory.IMacroCommandFactory; >+import org.eclipse.tptp.test.auto.gui.internal.commands.factory.MacroCommandFactoryLoader; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound; > import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; > import org.eclipse.ui.IPartListener; > import org.eclipse.ui.IWorkbench; > import org.eclipse.ui.IWorkbenchPage; >@@ -57,16 +54,18 @@ > import org.xml.sax.SAXException; > > /** >- * A singleton class that manages the macro recording and playback. Clients should always keep in >- * mind that there is only one instance of a macro manager always running. Proper synchronization >- * and clean up is left to the client >+ * A singleton class that manages the macro recording and playback. Clients >+ * should always keep in mind that there is only one instance of a macro manager >+ * always running. Proper synchronization and clean up is left to the client > */ >-public class MacroManager >-{ >+public class MacroManager { >+ > public static final String IGNORE = "__macro_ignore__"; > >- /* The state of jobs. This is used to listen for on going jobs and adding wait commands when >- * there is a job running */ >+ /* >+ * The state of jobs. This is used to listen for on going jobs and adding >+ * wait commands when there is a job running >+ */ > public static final int IDLE = 0; > > public static final int RUNNING = 1; >@@ -78,30 +77,17 @@ > /* The instance that this singleton class holds */ > private static MacroManager macroManagerInstance; > >- /* Keeps track of the global states that the macro manager is in. See the >- * global state events for the possible states that this macro manager can be in. This >- * variable must be locked when it is read/written from/to. Use globalStateLock to lock >- * this field. */ >+ /* >+ * Keeps track of the global states that the macro manager is in. See the >+ * global state events for the possible states that this macro manager can >+ * be in. This variable must be locked when it is read/written from/to. Use >+ * globalStateLock to lock this field. >+ */ > private byte globalState; > > /* Global state lock */ > private Boolean globalStateLock; > >- /* Global states */ >- public static final byte RECORDING_MODE = 0x00; /* Recording mode */ >- public static final byte VERIFICATION_MODE = 0x01; /* Verificaiton mode */ >- public static final byte SUSPEND_MODE = 0x02; /* Suspend mode */ >- public static final byte QUICK_RUN_MODE = 0x03; /* Quick run mode (when current workbench is used as the context) */ >- public static final byte EXECUTION_RUN_MODE = 0x04; /* Execution run mode (when proper launch configuration is used) */ >- public static final byte IDLE_MODE = 0x05; /* Idle mode */ >- public static final byte POSITION_BASED_REC_MODE = 0x06; /* Position based recording */ >- >- /* Custom event details */ >- public static final int POSITION_BASED_EVENT = Integer.MIN_VALUE; >- >- /* The verification command */ >- private VerificationCommand verificationCommand; >- > /* Verification hook listener */ > private VerificationHookListener verificationHooksListener; > >@@ -111,8 +97,10 @@ > /* The part listener */ > private IPartListener partListener; > >- /* Global state listeners that will be invoked when the global state >- * of this macro manager changes */ >+ /* >+ * Global state listeners that will be invoked when the global state of this >+ * macro manager changes >+ */ > private Vector globalStateListeners; > > /* Stores the dependecies of the current test suite that is being executed */ >@@ -120,46 +108,45 @@ > > /* Stores the runner that is running the current test suite */ > private AutoGUIRunner runner; >- >+ > /* Indicates whether artificial wait time is on/off */ > private boolean artificialWaitOn; >- >- /* Stores the allowable time-out threshold time for individual command execution */ >+ >+ /* >+ * Stores the allowable time-out threshold time for individual command >+ * execution >+ */ > private int commandTimeoutThreshold; >- >- /* Points to the object mine loaded for the operation (e.g. record/playback) that is in progress */ >- private IObjectMine objectMine; >- >+ >+ /* >+ * Points to the object mine loaded for the operation (e.g. record/playback) >+ * that is in progress >+ */ >+ private MacroObjectDescriptorMine objectMine; >+ >+ private IMacroCommandFactory commandFactory; >+ > /* Points to the test suite that is being used to record a test case */ > private ITestSuite testSuite; >- >- /* Indicates whether object mines should be used for a recording session or not */ >- private boolean objectMineOn; >- >- /* Keeps an ordered list of the resolver ids */ >- private String[] resolverIds; >- >- /* The widget resolver: >- * KEY = resolver id >- * VALUE = A class of type WidgetResolverLoader >+ >+ /* >+ * Indicates whether object mines should be used for a recording session or >+ * not > */ >- private Hashtable widgetResolvers; >- >+ private boolean objectMineOn; >+ > /* The display listeners */ > private DisplayListener listener; > > /* The job listeners */ > private JobListener jobListener; > >- >- class DisplayListener implements Listener >- { >- public void handleEvent(Event event) >- { >+ class DisplayListener implements Listener { >+ >+ public void handleEvent(Event event) { > /* Bail out if we are in the suspend mode */ >- synchronized (globalStateLock) >- { >- if (globalState == SUSPEND_MODE) >+ synchronized (globalStateLock) { >+ if (globalState == ModeConstants.SUSPEND_MODE) > return; > } > >@@ -167,29 +154,25 @@ > } > } > >- class JobListener extends JobChangeAdapter >- { >+ class JobListener extends JobChangeAdapter { >+ > private int state = IDLE; > >- public void running(IJobChangeEvent event) >- { >+ public void running(IJobChangeEvent event) { > if (!event.getJob().isSystem() && state == IDLE) > state = RUNNING; > } > >- public void done(IJobChangeEvent event) >- { >+ public void done(IJobChangeEvent event) { > if (!event.getJob().isSystem() && state == RUNNING) > state = DONE; > } > >- public void reset() >- { >+ public void reset() { > state = IDLE; > } > >- public int getState() >- { >+ public int getState() { > return state; > } > } >@@ -197,13 +180,14 @@ > /** > * Private constructor. Use getInstance() > */ >- private MacroManager() >- { >+ private MacroManager() { > listener = new DisplayListener(); >- jobListener = new JobListener(); >+ jobListener = new JobListener(); > globalStateLock = new Boolean(false); >- globalState = RECORDING_MODE; /* The initial global state is recording */ >- widgetResolvers = new Hashtable(); >+ globalState = ModeConstants.RECORDING_MODE; /* >+ * The initial global state >+ * is recording >+ */ > } > > /** >@@ -211,127 +195,122 @@ > * > * @return An instance of this class > */ >- public static MacroManager getInstance() >- { >+ public static MacroManager getInstance() { > if (macroManagerInstance == null) > macroManagerInstance = new MacroManager(); > > return macroManagerInstance; > } > >- public boolean isRecording() >- { >+ public boolean isRecording() { > return currentMacro != null; > } > > /** > * Invoked to start a recording session > * >- * @param testSuite The test suite >- * @param objectMineOn Indicates whether object mines should be used or not >+ * @param testSuite >+ * The test suite >+ * @param objectMineOn >+ * Indicates whether object mines should be used or not > * >- * @throws CoreException In case of an unexpected error >- * @throws UIObjectNotFound If an expected UI object is not found >- * @throws IDCollisionException If there is a ID collision between UI objects >+ * @throws CoreException >+ * In case of an unexpected error >+ * @throws UIObjectNotFound >+ * If an expected UI object is not found >+ * @throws IDCollisionException >+ * If there is a ID collision between UI objects > */ >- public void startRecording(ITestSuite testSuite, boolean objectMineOn) throws CoreException, UIObjectNotFound, IDCollisionException >- { >+ public void startRecording(ITestSuite testSuite, boolean objectMineOn) >+ throws CoreException, UIObjectNotFound, IDCollisionException { > this.objectMineOn = objectMineOn; > Display display = PlatformUI.getWorkbench().getDisplay(); > hookListeners(display); > MacroUtil.clearWorkbenchPartListeners(); > currentMacro = new Macro(); > currentMacro.initializeForRecording(display); >- >- this.testSuite = testSuite; >- objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite); >- >- hookPartListener(); >+ >+ this.testSuite = testSuite; >+ objectMine = MacroObjectDescriptorMineManager.getInstance() >+ .loadObjectMine(testSuite); >+ >+ hookPartListener(); > } > >- > /** >- * Stops the current macro that this macro manager maintains. The macro returned >- * can be null, if a previous error has caused the current macro to be null >+ * Stops the current macro that this macro manager maintains. The macro >+ * returned can be null, if a previous error has caused the current macro to >+ * be null > * >- * @param interrupted true if it is interrupted and false if it is normally stopped. >- * @return The macro to be stopped (null if a previous error has occurred in macro manager) >+ * @param interrupted >+ * true if it is interrupted and false if it is normally stopped. >+ * @return The macro to be stopped (null if a previous error has occurred in >+ * macro manager) > */ >- public Macro stopRecording(boolean interrupted) >- { >+ public Macro stopRecording(boolean interrupted) { > removePartListener(); > > /* Write the object mine to the test suite */ >- if (testSuite != null && objectMine != null && objectMineOn) >- { >+ if (testSuite != null && objectMine != null && objectMineOn) { > if (!interrupted) >- ObjectMineManager.getInstance().writeObjectMine(objectMine); >+ MacroObjectDescriptorMineManager.getInstance().writeObjectMine( >+ objectMine); > testSuite = null; > objectMine = null; > } >- >+ > if (currentMacro != null) > currentMacro.stopRecording(); > > Macro newMacro = currentMacro; >- currentMacro = null; >+ currentMacro = null; > > shutdown(); > return newMacro; > } >- >- > > /** > * Register a part listener > */ >- private void hookPartListener() >- { >- activePage = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); >- partListener = new IPartListener() >- { >- public void partActivated(IWorkbenchPart part) >- { >+ private void hookPartListener() { >+ activePage = GuiPlugin.getDefault().getWorkbench() >+ .getActiveWorkbenchWindow().getActivePage(); >+ partListener = new IPartListener() { >+ >+ public void partActivated(IWorkbenchPart part) { > Event event = null; > > /* Simulate a focus in event */ >- try >- { >+ try { > event = new Event(); > event.type = SWT.FocusIn; >- Shell shell = part.getSite().getPage().getWorkbenchWindow().getShell(); >+ Shell shell = part.getSite().getPage().getWorkbenchWindow() >+ .getShell(); > event.display = shell.getDisplay(); > event.widget = MacroUtil.getFirstChild(part); >- } >- catch (Exception e) >- { >+ } catch (Exception e) { > /* Don't report an event if there is an error */ > System.err.println(e.getMessage()); > } > >- if (event != null) >- { >+ if (event != null) { > listener.handleEvent(event); > } > } > >- public void partBroughtToTop(IWorkbenchPart part) >- { >+ public void partBroughtToTop(IWorkbenchPart part) { > /* Does not need to be implmented */ > } > >- public void partClosed(IWorkbenchPart part) >- { >+ public void partClosed(IWorkbenchPart part) { > /* Does not need to be implmented */ > } > >- public void partDeactivated(IWorkbenchPart part) >- { >+ public void partDeactivated(IWorkbenchPart part) { > /* Does not need to be implmented */ > } > >- public void partOpened(IWorkbenchPart part) >- { >+ public void partOpened(IWorkbenchPart part) { > /* Does not need to be implmented */ > } > >@@ -343,8 +322,7 @@ > /** > * Remove the part listener > */ >- private void removePartListener() >- { >+ private void removePartListener() { > if (activePage == null) > return; > >@@ -352,16 +330,12 @@ > activePage = null; > partListener = null; > } >- >- public Macro getCurrentMacro() >- { >+ >+ public Macro getCurrentMacro() { > return currentMacro; > } > >- >- >- public void hookListeners(Display display) >- { >+ public void hookListeners(Display display) { > display.addFilter(SWT.MouseUp, listener); > display.addFilter(SWT.KeyUp, listener); > display.addFilter(SWT.KeyDown, listener); >@@ -370,28 +344,27 @@ > display.addFilter(SWT.Expand, listener); > display.addFilter(SWT.Collapse, listener); > display.addFilter(SWT.Modify, listener); >- display.addFilter(SWT.Activate, listener); >+ display.addFilter(SWT.Activate, listener); > display.addFilter(SWT.Close, listener); >- display.addFilter(SWT.FocusIn, listener); >+ display.addFilter(SWT.FocusIn, listener); > IJobManager jobManager = Platform.getJobManager(); > jobManager.addJobChangeListener(jobListener); > } >- >- public void hookPositionBasedListeners(Display display) >- { >- display.addFilter(SWT.Activate, listener); >+ >+ public void hookPositionBasedListeners(Display display) { >+ display.addFilter(SWT.Activate, listener); > display.addFilter(SWT.Close, listener); > display.addFilter(SWT.MouseUp, listener); > display.addFilter(SWT.MouseDown, listener); >+ display.addFilter(SWT.MouseMove, listener); > display.addFilter(SWT.KeyUp, listener); > display.addFilter(SWT.KeyDown, listener); >- >+ > IJobManager jobManager = Platform.getJobManager(); > jobManager.addJobChangeListener(jobListener); > } > >- public void unhookListeners(Display display) >- { >+ public void unhookListeners(Display display) { > display.removeFilter(SWT.MouseUp, listener); > display.removeFilter(SWT.KeyUp, listener); > display.removeFilter(SWT.KeyDown, listener); >@@ -406,22 +379,21 @@ > IJobManager jobManager = Platform.getJobManager(); > jobManager.removeJobChangeListener(jobListener); > } >- >- public void unhookPositionBasedListeners(Display display) >- { >- display.removeFilter(SWT.Activate, listener); >+ >+ public void unhookPositionBasedListeners(Display display) { >+ display.removeFilter(SWT.Activate, listener); > display.removeFilter(SWT.Close, listener); > display.removeFilter(SWT.MouseUp, listener); > display.removeFilter(SWT.MouseDown, listener); >+ display.removeFilter(SWT.MouseMove, listener); > display.removeFilter(SWT.KeyUp, listener); > display.removeFilter(SWT.KeyDown, listener); >- >+ > IJobManager jobManager = Platform.getJobManager(); > jobManager.removeJobChangeListener(jobListener); > } > >- public void shutdown() >- { >+ public void shutdown() { > Display display = PlatformUI.getWorkbench().getDisplay(); > unhookListeners(display); > unhookPositionBasedListeners(display); >@@ -430,28 +402,27 @@ > currentMacro = null; > artificialWaitOn = false; > } >- >- >+ > /** >- * Prepares this macro manager for playback of test cases. This method should be >- * invoked to do the required one time initialization before a test suite's test >- * cases are played back. >+ * Prepares this macro manager for playback of test cases. This method >+ * should be invoked to do the required one time initialization before a >+ * test suite's test cases are played back. > * >- * @param objectMineXML The object mine XML >- * @throws CoreException In case of any unexpected error >+ * @param objectMineXML >+ * The object mine XML >+ * @throws CoreException >+ * In case of any unexpected error > */ >- public void prepareForPlayBack(String objectMineXML) throws CoreException >- { >- try >- { >- setObjectMine(ObjectMineManager.getInstance().loadObjectMine(objectMineXML)); >- } catch (Exception e) >- { >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >- } >+ public void prepareForPlayBack(String objectMineXML) throws CoreException { >+ try { >+ setObjectMine(MacroObjectDescriptorMineManager.getInstance() >+ .loadObjectMine(objectMineXML)); >+ } catch (Exception e) { >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >+ } > } >- >- >+ > /** > * Plays a provided macro stream. The method will close the input stream > * upon parsing. >@@ -459,105 +430,95 @@ > * @param is > * @throws CoreException > */ >- public boolean play(final Display display, final IRunnableContext context, String scriptName, XMLDefaultHandler handler, Boolean shouldBlock) throws CoreException >- { >+ public boolean play(final Display display, final IRunnableContext context, >+ String scriptName, XMLDefaultHandler handler, Boolean shouldBlock) >+ throws CoreException { > Node root = handler.getDocumentElement(); > NodeList children = root.getChildNodes(); > MacroCommandShell.initializeForNewPlay(); >- >+ > final Macro macro = new Macro(scriptName); >- for (int i = 0; i < children.getLength(); i++) >- { >+ for (int i = 0; i < children.getLength(); i++) { > Node child = children.item(i); >- if (child.getNodeName().equals(MacroConstants.SHELL_ELEMENT)) >- { >- macro.addShell(child, handler.getLineTable()); >+ if (child.getNodeName().equals(MacroConstants.SHELL_ELEMENT)) { >+ macro.load(child, handler.getLineTable()); > } > } > // discard the DOM > handler = null; > > final boolean[] result = new boolean[1]; >- >- class MacroOperationWrapper implements Runnable >- { >+ >+ class MacroOperationWrapper implements Runnable { >+ > private Exception exception; > private Object objectToNotify; > private boolean isDone; >- >- public MacroOperationWrapper (Object objectToNotify) >- { >+ >+ public MacroOperationWrapper(Object objectToNotify) { > this.objectToNotify = objectToNotify; > isDone = false; > } >- >- >- public void run() >- { >- try >- { >- /* Ali M.: Unfortunately position-based commands don't work when the macro is played in an IRunnableContext with >- * a progress bar. I had to sacrifice the progress bar for position-based commands to run correctly */ >- result[0] = runMacro(macro, display, new NullProgressMonitor()); >- >- if (objectToNotify != null) >- { >- synchronized(objectToNotify) >- { >+ >+ public void run() { >+ try { >+ /* >+ * Ali M.: Unfortunately position-based commands don't work >+ * when the macro is played in an IRunnableContext with a >+ * progress bar. I had to sacrifice the progress bar for >+ * position-based commands to run correctly >+ */ >+ result[0] = runMacro(macro, display, >+ new NullProgressMonitor()); >+ >+ if (objectToNotify != null) { >+ synchronized (objectToNotify) { > objectToNotify.notify(); > } > } > isDone = true; >- } >- catch (Exception e) >- { >+ } catch (Exception e) { > exception = e; > isDone = true; > } > } >- >- public void didErrorOccur() throws Exception >- { >+ >+ public void didErrorOccur() throws Exception { > if (exception != null) > throw exception; > } >- >- public boolean isDone() >- { >+ >+ public boolean isDone() { > return isDone; > } > } >- >- try >- { >- /* Run the macro synchronously or asynchronously depending on the argument passed in */ >- if (shouldBlock.booleanValue()) >- { >- MacroOperationWrapper macroRunOperation = new MacroOperationWrapper(shouldBlock); >+ >+ try { >+ /* >+ * Run the macro synchronously or asynchronously depending on the >+ * argument passed in >+ */ >+ if (shouldBlock.booleanValue()) { >+ MacroOperationWrapper macroRunOperation = new MacroOperationWrapper( >+ shouldBlock); > Thread macroRunThread = new Thread(macroRunOperation); > macroRunThread.start(); >- >- while (!macroRunOperation.isDone()) >- { >- synchronized (shouldBlock) >- { >+ >+ while (!macroRunOperation.isDone()) { >+ synchronized (shouldBlock) { > shouldBlock.wait(500); > } > } >- >+ > macroRunOperation.didErrorOccur(); >- } >- else >+ } else > new Thread(new MacroOperationWrapper(null)).start(); >- } >- catch (Exception e) >- { >+ } catch (Exception e) { > /* The cause of this exception would give away the error */ >- AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, -1, e); >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, -1, e); > result[0] = false; >- } >- finally >- { >+ } finally { > /* Indicate that we were done playing, if this is a blocking call */ > if (shouldBlock != null && shouldBlock.booleanValue()) > MacroCommandShell.macroStopped(); >@@ -565,336 +526,167 @@ > return result[0]; > } > >- private boolean runMacro(final Macro macro, final Display display, IProgressMonitor monitor) throws InvocationTargetException >- { >+ private boolean runMacro(final Macro macro, final Display display, >+ IProgressMonitor monitor) throws InvocationTargetException { > boolean success = false; >- try >- { >+ try { > // System.out.println("Start macro: "+macro.getName()); > success = macro.playback(display, null, monitor); >- } >- catch (CoreException e) >- { >+ } catch (CoreException e) { > throw new InvocationTargetException(e); >- } >- catch (ClassCastException e) >- { >+ } catch (ClassCastException e) { > throw new InvocationTargetException(e); >- } >- finally >- { >+ } finally { > monitor.done(); > // System.out.println("Stop macro: "+macro.getName()); > } > return success; > } > >- public XMLDefaultHandler createMacroDocument(InputStream is) throws CoreException >- { >+ public XMLDefaultHandler createMacroDocument(InputStream is) >+ throws CoreException { > XMLDefaultHandler handler = null; >- try >- { >+ try { > handler = MacroUtil.createXMLDocument(is); >+ } catch (SAXException e) { >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e >+ .getLocalizedMessage()), 0, e); >+ } catch (IOException e) { >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e >+ .getLocalizedMessage()), 0, e); > } >- catch (SAXException e) >- { >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e); >- } >- catch (IOException e) >- { >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e); >- } >- >+ > return handler; > } > >- >- private void onEvent(Event event) >- { >- try >- { >- /* If for any reason the current macro is null, then something has gone wrong. Shut the macro manager down */ >- if (currentMacro == null) >- { >+ private void onEvent(Event event) { >+ try { >+ /* >+ * If for any reason the current macro is null, then something has >+ * gone wrong. Shut the macro manager down >+ */ >+ if (currentMacro == null) { > shutdown(); > return; > } > >- >- synchronized (globalStateLock) >- { >- if (globalState == RECORDING_MODE && (event.type == SWT.Close || event.type == SWT.Activate) && !(event.widget instanceof Shell)) >+ synchronized (globalStateLock) { >+ if (globalState == ModeConstants.RECORDING_MODE >+ && (event.type == SWT.Close || event.type == SWT.Activate) >+ && !(event.widget instanceof Shell)) > return; > } > >- /* If there is an incomming event and there is already a job running in the background >- * then insert a pause command */ >- if (jobListener.getState() == RUNNING || jobListener.getState() == DONE) >- { >+ /* >+ * If there is an incomming event and there is already a job running >+ * in the background then insert a pause command >+ */ >+ if (jobListener.getState() == RUNNING >+ || jobListener.getState() == DONE) { > currentMacro.addPause(); > jobListener.reset(); > } > >- /* Check the global state here. If we're in the verification mode, then >- * redirect the events to the verification command. */ >- synchronized (globalStateLock) >- { >- if (globalState == RECORDING_MODE) >- { >+ /* >+ * Check the global state here. If we're in the verification mode, >+ * then redirect the events to the verification command. >+ */ >+ synchronized (globalStateLock) { >+ if (globalState == ModeConstants.RECORDING_MODE) { >+ currentMacro.addEvent(event); >+ } else if (globalState == ModeConstants.POSITION_BASED_REC_MODE) { >+ /* >+ * We'll tag the event with a detail constant that will >+ * identify the event as position based >+ */ >+ event.detail = EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT; >+ currentMacro.addEvent(event); >+ } else if (globalState == ModeConstants.VERIFICATION_MODE) { >+ /* >+ * We'll tag the event with a detail constant that will >+ * identify the event as verification hook insertion related >+ * command >+ */ >+ event.detail = EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT; > currentMacro.addEvent(event); >- } >- else if (globalState == POSITION_BASED_REC_MODE) >- { >- /* We'll tag the event with a detail constant that will identify the event as position based */ >- event.detail = POSITION_BASED_EVENT; >- currentMacro.addEvent (event); >- } >- else if (globalState == VERIFICATION_MODE) >- { >- verificationCommand = VerificationCommand.constructInstance(null, event); >- >- /* If we get events that can possibly change our shell stack, then fire off to the current macro >- * to handle it */ >- if (event.type == SWT.Activate && event.widget instanceof Shell) >- { >- currentMacro.addEvent(event); >- } >- >- /* Something went wrong. Inform the user with some feedback */ >- if (verificationCommand == null) >- { >- String error = VerificationCommand.getError(); >- if (error != null && !error.equals("")) >- notifyVerificationListener(error); >- } >- >- /* The normal flow */ >- else >- { >- MacroCommandShell topShell = currentMacro.getTopShell(); >- >- /* There is a chance that the macro does not have a top shell. We'll >- * attempt to resolve its top shell, if unsuccessful, then we'll prompt >- * the user with an error. */ >- >- if (topShell == null && event.widget instanceof Control) >- { >- Event artificialEvent = new Event(); >- artificialEvent.type = SWT.Activate; >- artificialEvent.display = event.widget.getDisplay(); >- artificialEvent.widget = ((Control) event.widget).getShell(); >- currentMacro.addEvent(artificialEvent); >- } >- >- /* If the resolve attempt failed, then notify the user */ >- topShell = currentMacro.getTopShell(); >- if (topShell == null) >- { >- setGlobalState(SUSPEND_MODE); >- showError(AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL_T, AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL); >- setGlobalState(RECORDING_MODE); >- return; >- } > >- verificationCommand.setParent (topShell); >- topShell.addVerificationCommand(verificationCommand); >- notifyVerificationListener(verificationCommand); >+ // see if the insertion was successful, notify the listener >+ // about the result >+ if (currentMacro.getTopShell() == null) { >+ setGlobalState(ModeConstants.SUSPEND_MODE); >+ showError( >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL); >+ setGlobalState(ModeConstants.RECORDING_MODE); > } > } > } > >- } >- catch (Exception e) >- { >+ } catch (Exception e) { >+ AutoGUIUtil.openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN, e.getMessage(), e); > e.printStackTrace(); > stopRecording(true); > } > } > > /** >- * Show an error message >- * @param title The title of the error message >- * @param errorMsg The actual error message >+ * Show an error message >+ * >+ * @param title >+ * The title of the error message >+ * @param errorMsg >+ * The actual error message > */ >- private void showError(final String title, final String errorMsg) >- { >+ public void showError(final String title, final String errorMsg) { > final IWorkbench workbench = PlatformUI.getWorkbench(); >- workbench.getDisplay().syncExec(new Runnable() >- { >- public void run() >- { >+ workbench.getDisplay().syncExec(new Runnable() { >+ >+ public void run() { > IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); >- if (window != null) >- { >+ if (window != null) { > MessageDialog.openError(window.getShell(), title, errorMsg); > } > } > }); > } > >- private void notifyVerificationListener(VerificationCommand verificationCommand) >- { >+ protected void notifyVerificationListener( >+ VerificationCommand verificationCommand) { > if (verificationHooksListener != null) > verificationHooksListener.instanceReady(verificationCommand); > > } > >- private void notifyVerificationListener(String error) >- { >+ protected void notifyVerificationListener(String error) { > if (verificationHooksListener != null) > verificationHooksListener.error(error); > } >- >- >- /** >- * Return the widget id resolved by the widget resolver whose id is passed in. >- * If in case the resolverId is null, then step through the widget resolvers starting >- * from index inx and return the results of the first resolver that is able to resolve >- * the widget that is passed in. >- * >- * @param widget The widget to be resolved >- * @param resolverId The resolver id. It can be null >- * @param inx The index of the resolvers that the search should begin from. This is >- * declared as an array because this method needs to preserve the change in value. The >- * array is of size 1 and its value must always be >= 0. >- * >- * @return The resolved widget id or null if none can be found >- */ >- public IWidgetId resolveWidget (Widget parent, Object object, String resolverId, int[] inx) >- { >- /* Load the widget if neccessary */ >- if (resolverIds == null) >- { >- loadWidgetResolvers(); >- } >- >- /* We have a valid resolver id */ >- if (resolverId != null) >- { >- WidgetResolverLoader widgetResolverLoader = (WidgetResolverLoader)widgetResolvers.get(resolverId); >- if (widgetResolverLoader == null) >- { >- return null; >- } >- return widgetResolverLoader.getWidgetResolver().getUniqueId(parent, object); >- } >- >- /* Otherwise, we'll need to step through the resolvers */ >- if (inx[0] < 0 || inx[0] >= resolverIds.length) >- return null; >- >- for (int i = inx[0]; i < resolverIds.length; i++) >- { >- WidgetResolverLoader widgetResolverLoader = (WidgetResolverLoader)widgetResolvers.get(resolverIds[i]); >- IWidgetId widgetId = widgetResolverLoader.getWidgetResolver().getUniqueId(parent, object); >- inx[0]++; >- if (widgetId != null) >- return widgetId; >- } >- >- return null; >- } >- >- >- public Hashtable getWidgetResolvers() >- { >- if (resolverIds == null) >- loadWidgetResolvers(); >- >- return widgetResolvers; >- } >- >- public IWidgetId resolveWidget (Widget widget, String resolverId, int[] inx) >- { >- return resolveWidget (widget instanceof Control ? ((Control)widget).getParent() : null, widget, resolverId, inx); >- } >- >- /** >- * Load the registered widget resolvers. The widget resolvers are ordered in the descending order of their priority >- */ >- private void loadWidgetResolvers() >- { >- IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.tptp.test.auto.gui.widgetResolver"); >- Vector tempContainer = new Vector(elements.length); >- >- for (int i = 0; i < elements.length; i++) >- { >- WidgetResolverLoader widgetResolverReg = WidgetResolverLoader.constructInstance(elements[i]); >- if (widgetResolverReg != null) >- { >- tempContainer.add(findIndex(widgetResolverReg.getPriority(), tempContainer), widgetResolverReg); >- widgetResolvers.put(widgetResolverReg.getId(), widgetResolverReg); >- } >- } >- >- resolverIds = new String[tempContainer.size()]; >- for (int i = 0; i < resolverIds.length; i++) >- { >- resolverIds[i] = ((WidgetResolverLoader)tempContainer.get(i)).getId(); >- } >- } >- >- private int findIndex(int desiredPriority, Vector container, int startIntervalInx, int endIntervalInx, int length) >- { >- if (startIntervalInx == endIntervalInx || startIntervalInx == endIntervalInx - 1) >- { >- if (length > 0) >- { >- WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader)container.get(startIntervalInx); >- int priority = widgetResolverReg.getPriority(); >- if (desiredPriority < priority) >- return startIntervalInx; >- } >- return endIntervalInx; >- } >- >- /* What's in the middle? */ >- int middleInx = startIntervalInx + (int) Math.ceil((endIntervalInx - startIntervalInx)/2); >- WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader)container.get(middleInx); >- int middleElementPriority = widgetResolverReg.getPriority(); >- >- if (middleElementPriority > desiredPriority) >- endIntervalInx = middleInx; >- else if (middleElementPriority < desiredPriority) >- startIntervalInx = middleInx; >- else >- return middleInx; >- return findIndex(desiredPriority, container, startIntervalInx, endIntervalInx, length); >- } >- >- private int findIndex(int priority, Vector container) >- { >- int length = container.size(); >- return findIndex (priority, container, 0, length, length); >- } > >- > /** > * Pre-condition: > * <ul> >- * <li> To guarantee that this field is not changed while it is being used, it must be locked </li> >+ * <li> To guarantee that this field is not changed while it is being used, >+ * it must be locked </li> > * </ul> >- * >- * @return The global state of the macro manager. >+ * >+ * @return The global state of the macro manager. > */ >- public byte getGlobalState() >- { >+ public byte getGlobalState() { > return globalState; > } >- > >- public void setGlobalState(byte globalState) >- { >- synchronized (globalStateLock) >- { >+ public void setGlobalState(byte globalState) { >+ synchronized (globalStateLock) { > byte oldState = this.globalState; > this.globalState = globalState; > >- if (globalStateListeners != null && oldState != this.globalState) >- { >- for (int i = 0; i < globalStateListeners.size(); i++) >- { >- GlobalStateListener gsl = (GlobalStateListener) globalStateListeners.get(i); >+ if (globalStateListeners != null && oldState != this.globalState) { >+ for (int i = 0; i < globalStateListeners.size(); i++) { >+ GlobalStateListener gsl = (GlobalStateListener) globalStateListeners >+ .get(i); > if (gsl.isListenerOn()) > gsl.globalStateChange(oldState, this.globalState); > } >@@ -902,196 +694,179 @@ > } > } > } >- >- public void setGlobalStateWithoutLock(byte globalState) >- { >+ >+ public void setGlobalStateWithoutLock(byte globalState) { > byte oldState = this.globalState; > this.globalState = globalState; >- >- if (globalStateListeners != null && oldState != this.globalState) >- { >- for (int i = 0; i < globalStateListeners.size(); i++) >- { >- GlobalStateListener gsl = (GlobalStateListener) globalStateListeners.get(i); >+ >+ if (globalStateListeners != null && oldState != this.globalState) { >+ for (int i = 0; i < globalStateListeners.size(); i++) { >+ GlobalStateListener gsl = (GlobalStateListener) globalStateListeners >+ .get(i); > if (gsl.isListenerOn()) > gsl.globalStateChange(oldState, this.globalState); > } >- >+ > } > } > >- public void setVerListener(VerificationHookListener verHookListener) >- { >+ public void setVerListener(VerificationHookListener verHookListener) { > verificationHooksListener = verHookListener; > } > >- public void removeVerListener() >- { >+ public void removeVerListener() { > verificationHooksListener = null; > } > >- public void registerGlobalStateListener(GlobalStateListener gsl) >- { >+ public void registerGlobalStateListener(GlobalStateListener gsl) { > if (this.globalStateListeners == null) > this.globalStateListeners = new Vector(2); > > this.globalStateListeners.add(gsl); > } > >- public void removeGlobalStateListener(GlobalStateListener gsl) >- { >- if (this.globalStateListeners != null) >- { >+ public void removeGlobalStateListener(GlobalStateListener gsl) { >+ if (this.globalStateListeners != null) { > this.globalStateListeners.remove(gsl); > if (this.globalStateListeners.size() == 0) > this.globalStateListeners = null; > } > } > >- public void setDependecies(Vector dependecies) >- { >+ public void setDependecies(Vector dependecies) { > this.dependecies = dependecies; > } > >- public Vector getDependecies() >- { >+ public Vector getDependecies() { > return this.dependecies; > } > >- public AutoGUIRunner getRunner() >- { >+ public AutoGUIRunner getRunner() { > return runner; > } > >- public void setRunner(AutoGUIRunner runner) >- { >+ public void setRunner(AutoGUIRunner runner) { > this.runner = runner; > } >- >- >+ > /** >- * This method is invoked to toggle the position based recording option on or off. >- * Turning on position based recording will only record position-based commands. >- * This is only recommended where object based recording cannot be used. (e.g. User >- * clicking at a specific location of a canvas) >- * >- * @param state True indicates that position based recording should be turned on and false indicates >- * that it should be turned off >+ * This method is invoked to toggle the position based recording option on >+ * or off. Turning on position based recording will only record >+ * position-based commands. This is only recommended where object based >+ * recording cannot be used. (e.g. User clicking at a specific location of a >+ * canvas) >+ * >+ * @param state >+ * True indicates that position based recording should be turned >+ * on and false indicates that it should be turned off > * > * @return true if operation is successful; false otherwise > */ >- public synchronized boolean togglePositionBasedRec(boolean state) >- { >- >- synchronized (globalStateLock) >- { >+ public synchronized boolean togglePositionBasedRec(boolean state) { >+ >+ synchronized (globalStateLock) { > Display currentDisplay = PlatformUI.getWorkbench().getDisplay(); >- >+ > /* We're required to turn on position based recoridng */ >- if (state) >- { >- if (currentDisplay != null) >- { >+ if (state) { >+ if (currentDisplay != null) { > unhookListeners(currentDisplay); > hookPositionBasedListeners(currentDisplay); >- >- globalState = POSITION_BASED_REC_MODE; >- } >- else >+ >+ globalState = ModeConstants.POSITION_BASED_REC_MODE; >+ } else > return false; > } > /* Otherwise turn the option off */ >- else if (!state) >- { >- if (currentDisplay != null) >- { >+ else if (!state) { >+ if (currentDisplay != null) { > unhookPositionBasedListeners(currentDisplay); > hookListeners(currentDisplay); >- >- globalState = RECORDING_MODE; >- } >- else >+ >+ globalState = ModeConstants.RECORDING_MODE; >+ } else > return false; > } >- >+ > } >- >+ > return true; >- >+ > } >- >- public boolean isArtificialWaitOn() >- { >+ >+ public boolean isArtificialWaitOn() { > return artificialWaitOn; > } > >- public void setArtificialWaitOn(boolean artificialWaitOn) >- { >+ public void setArtificialWaitOn(boolean artificialWaitOn) { > this.artificialWaitOn = artificialWaitOn; > } >- >- >+ > /** > * @return the objectMine > */ >- public IObjectMine getObjectMine() >- { >+ public MacroObjectDescriptorMine getObjectMine() { > return objectMine; > } > > /** >- * @param objectMine the objectMine to set >+ * @param objectMine >+ * the objectMine to set > */ >- public void setObjectMine(IObjectMine objectMine) >- { >+ public void setObjectMine(MacroObjectDescriptorMine objectMine) { > this.objectMine = objectMine; > } >- >- >+ > /** >- * Used to register classes as listeners that are awaiting the creation of a VerificationCommand >- * from a focus command of an editor or a viewer. >+ * Used to register classes as listeners that are awaiting the creation of a >+ * VerificationCommand from a focus command of an editor or a viewer. > * > * @author Ali Mehregani > */ >- public interface VerificationHookListener >- { >+ public interface VerificationHookListener { >+ > /** > * Reports any error while attempting to construct object > * >- * @param error A descriptive error message >+ * @param error >+ * A descriptive error message > */ > public void error(String error); > > /** > * Invoked when there is an instance ready > * >- * @param verificationCommand The instance of verification command created as a result of an event. >+ * @param verificationCommand >+ * The instance of verification command created as a result >+ * of an event. > */ > public void instanceReady(VerificationCommand verificationCommand); > } > > /** >- * A gateway for client to determine the global state changes of the macro recorder. >+ * A gateway for client to determine the global state changes of the macro >+ * recorder. > * > * @author amehregani > */ >- public interface GlobalStateListener >- { >+ public interface GlobalStateListener { >+ > /** >- * Indicates whether the listener is interested in listening >- * for a global state change. >+ * Indicates whether the listener is interested in listening for a >+ * global state change. > * > * @return True if the listener's globalStateChange method should be >- * invoke upon a global state change; false otherwise. >+ * invoke upon a global state change; false otherwise. > */ > public boolean isListenerOn(); > > /** > * Invoked when the global state of the macro manager has changed > * >- * @param oldState The old state >- * @param newState The new state >+ * @param oldState >+ * The old state >+ * @param newState >+ * The new state > */ > public void globalStateChange(byte oldState, byte newState); > } >@@ -1103,28 +878,33 @@ > public void setCommandTimeoutThreshold(int commandTimeoutThreshold) { > this.commandTimeoutThreshold = commandTimeoutThreshold; > } >- >- public int getOutstandShellCommands() >- { >+ >+ public int getOutstandShellCommands() { > return MacroCommandShell.getMacroCommandsBeingPlayed().size(); > } > > /** > * @return the objectMineOn > */ >- public boolean isObjectMineOn() >- { >+ public boolean isObjectMineOn() { > return objectMineOn; > } > > /** >- * @param objectMineOn the objectMineOn to set >+ * @param objectMineOn >+ * the objectMineOn to set > */ >- public void setObjectMineOn(boolean objectMineOn) >- { >+ public void setObjectMineOn(boolean objectMineOn) { > this.objectMineOn = objectMineOn; > } > >+ public IMacroCommandFactory getMacroCommandFactory() { >+ if (commandFactory == null) { >+ // see if we have a contribution via the macroCommandFactory >+ // extension point >+ return MacroCommandFactoryLoader.getHighestPriorityFactory(); >+ } >+ return commandFactory; >+ } > >- > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/Macro.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/macro/Macro.java,v >retrieving revision 1.1 >diff -u -r1.1 Macro.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/Macro.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/Macro.java 26 Jul 2008 19:22:11 -0000 >@@ -21,33 +21,28 @@ > import org.eclipse.jface.dialogs.Dialog; > import org.eclipse.jface.window.Window; > import org.eclipse.swt.SWT; >-import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Display; > import org.eclipse.swt.widgets.Event; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.commands.MacroCommandShell; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IPlayable; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.IWritable; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; > import org.eclipse.ui.PlatformUI; > import org.w3c.dom.Node; > > /** > * Models a macro > */ >-public class Macro implements IWritable, IPlayable >-{ >- private static final String SYNTAX_VERSION = "1.0"; >- >- /* Custom event types */ >- /* Indicates that a workbnech part has been closed */ >- public static final int WORKBENCH_PART_CLOSED = -1; >+public class Macro implements IPersistable, IPlayable { >+ >+ public static final String SYNTAX_VERSION = "1.1"; > > /* An array of shells */ > private ArrayList shells; >@@ -57,254 +52,292 @@ > > /* Keeps track of the stack of shells (This is used during recording) */ > private Stack shellStack; >- >- public Macro() >- { >+ >+ public Macro() { > shells = new ArrayList(); > } > >- public Macro(String name) >- { >+ public Macro(String name) { > this(); > this.name = name; > } > >- protected void addShell(Node node, Hashtable lineTable) throws CoreException >- { >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IReadable#load(org.w3c.dom.Node, >+ * java.util.Hashtable) >+ */ >+ public void load(Node node, Hashtable lineTable) throws CoreException { > MacroCommandShell shell = new MacroCommandShell(null, null, null); > shell.load(node, lineTable); > shells.add(shell); > } > >- public void initializeForRecording(Display display) >- { >+ public void initializeForRecording(Display display) { > shellStack = new Stack(); > shells.clear(); > Shell currentShell = display.getActiveShell(); > > if (currentShell == null) > return; >- >- /* In case we are suppose to ignore the shell, then don't add it to our stack */ >+ >+ /* >+ * In case we are suppose to ignore the shell, then don't add it to our >+ * stack >+ */ > Object data = currentShell.getData(MacroManager.IGNORE); >- >- if (data != null && data instanceof Boolean && ((Boolean)data).booleanValue()) >+ >+ if (data != null && data instanceof Boolean >+ && ((Boolean) data).booleanValue()) > return; >- >+ >+ // hook the workbench listener >+ MacroUtil.hookWorkbenchPartListener(currentShell); >+ > pushStack(createCommandShell(currentShell)); > } > >- private MacroCommandShell createCommandShell(Shell shell) >- { >- WidgetIdentifier wi = MacroUtil.getWidgetIdentifier(shell); >+ private MacroCommandShell createCommandShell(Shell shell) { >+ IMacroObjectIdentifier wi = null; >+ try { >+ wi = MacroObjectResolver.resolve(shell, new MacroObject( >+ new UIObject(shell))); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ } > if (wi == null) > return null; > return new MacroCommandShell(null, shell, wi); > } > >- private boolean isCurrent(Shell shell) >- { >+ private boolean isCurrent(Shell shell) { > if (shellStack.isEmpty()) > return false; > MacroCommandShell cshell = (MacroCommandShell) shellStack.peek(); > return cshell.tracks(shell); > } > >- public void stopRecording() >- { >+ public void stopRecording() { > reset(); > } > >- public boolean addEvent(Event event) throws Exception >- { >- if (MacroUtil.isIgnorableEvent(event)) >- return false; >- try >- { >- /* >- * A new shell is in the picture now (i.e. a new shell is closed or >- * activated). We need to modify the shell stack >- */ >- if (event.widget instanceof Shell) >- { >- switch (event.type) >- { >- case SWT.Activate: >- activateShell((Shell) event.widget); >- break; >- case SWT.Close: >- boolean stop = closeShell((Shell) event.widget); >- if (stop) >- return true; >- break; >- } >+ public void addEvent(Event event) throws Exception { >+ if (MacroUtil.isIgnorableEvent(event)) { >+ return; >+ } >+ >+ if (event.type != EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) { >+ // hook the workbench listener, if not already registered at the >+ // widget >+ MacroUtil.hookWorkbenchPartListener(event.widget); >+ } >+ >+ /* >+ * A new shell is in the picture now (i.e. a new shell is closed or >+ * activated). We need to modify the shell stack >+ */ >+ if (event.widget instanceof Shell) { >+ switch (event.type) { >+ case SWT.Activate: >+ activateShell((Shell) event.widget); >+ break; >+ case SWT.Close: >+ boolean stop = closeShell((Shell) event.widget); >+ if (stop) >+ return; >+ break; > } >+ } > >- /* Otherwise we have performed a command within the current shell */ >- else >- { >- /* Make sure that the command sent over belongs to the top shell */ >- MacroCommandShell topCommandShell = getTopShell(); >- if (topCommandShell != null) >- { >- Shell topShell = topCommandShell.getShell(); >- Shell widgetShell = (!(event.widget instanceof Control) ? null : ((Control)event.widget).getShell()); >- >- /* Add the event only if the widget shell could not be resolved or the widget shell is the same >- * as the top shell */ >- if (widgetShell == null || topShell == widgetShell) >- { >- topCommandShell.addEvent(event); >- } >+ // TODO: See if the following can be simplified >+ /* Otherwise we have performed a command within the current shell */ >+ if (!(event.widget instanceof Shell) >+ && event.detail != EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) { >+ /* Make sure that the command sent over belongs to the top shell */ >+ MacroCommandShell topCommandShell = getTopShell(); >+ if (topCommandShell != null) { >+ Shell topShell = topCommandShell.getShell(); >+ Shell widgetShell = (!(event.widget instanceof Control) ? null >+ : ((Control) event.widget).getShell()); >+ >+ /* >+ * Add the event only if the widget shell could not be resolved >+ * or the widget shell is the same as the top shell >+ */ >+ if (widgetShell == null || topShell == widgetShell) { >+ topCommandShell.addEvent(event); > } > } >- } catch (Exception e) >- { >- throw e; >+ } else if (event.detail == EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) { >+ MacroCommandShell topShell = getTopShell(); >+ /* >+ * There is a chance that the macro does not have a top shell. We'll >+ * attempt to resolve its top shell, if unsuccessful, then we'll >+ * prompt the user with an error. >+ */ >+ if (topShell == null && event.widget instanceof Control) { >+ Event artificialEvent = new Event(); >+ artificialEvent.type = SWT.Activate; >+ artificialEvent.display = event.widget.getDisplay(); >+ artificialEvent.widget = ((Control) event.widget).getShell(); >+ addEvent(artificialEvent); >+ topShell = getTopShell(); >+ } >+ if (topShell != null) { >+ topShell.addEvent(event); >+ } >+ > } >- return false; >+ return; > } > >- >- >- public void addPause() >- { >+ public void addPause() { > MacroCommandShell topShell = getTopShell(); > if (topShell != null) > topShell.addPause(); > } > >- >- public MacroCommandShell getTopShell() >- { >+ public MacroCommandShell getTopShell() { > if (shellStack.isEmpty()) > return null; > return (MacroCommandShell) shellStack.peek(); > } > >- private void activateShell(Shell shell) >- { >+ private void activateShell(Shell shell) { > if (shell.isDisposed()) > return; >- >+ > Object data = shell.getData(); >- if (data instanceof Dialog) >- { >- if (!isCurrent(shell)) >- { >- /* Before adding the shell to the stack, make sure that it is not a parent of the current shell */ >+ if (data instanceof Dialog) { >+ if (!isCurrent(shell)) { >+ /* >+ * Before adding the shell to the stack, make sure that it is >+ * not a parent of the current shell >+ */ > MacroCommandShell parentOfCurrentShell = null; >- if (shellStack.size() - 2 >= 0) >- { >- parentOfCurrentShell = (MacroCommandShell)shellStack.get(shellStack.size() - 2); >+ if (shellStack.size() - 2 >= 0) { >+ parentOfCurrentShell = (MacroCommandShell) shellStack >+ .get(shellStack.size() - 2); > } >- >- /* If the new shell happens to be the parent of the current shell, then we just need to pop the stack */ >- if (parentOfCurrentShell != null && parentOfCurrentShell.tracks(shell)) >- { >+ >+ /* >+ * If the new shell happens to be the parent of the current >+ * shell, then we just need to pop the stack >+ */ >+ if (parentOfCurrentShell != null >+ && parentOfCurrentShell.tracks(shell)) { > popStack(); >- } >- else >- { >- >+ } else { >+ > MacroCommandShell commandShell = createCommandShell(shell); >- >+ > /* Initialize for recording failed to find the top shell */ >- if (getTopShell() == null) >- { >- pushStack(commandShell); >- } >- else >- { >+ if (getTopShell() == null) { >+ pushStack(commandShell); >+ } else { > getTopShell().addCommandShell(commandShell); > shellStack.push(commandShell); >- updateObjectMine(commandShell); >+ updateObjectMine(commandShell); > } > } > } >- } >- else if (data instanceof Window) >- { >+ } else if (data instanceof Window) { > updateStack(); >- if (!isCurrent(shell)) >- { >+ if (!isCurrent(shell)) { > popStack(); >- >+ > MacroCommandShell newCommandShell = createCommandShell(shell); > MacroCommandShell topCommandShell = getTopShell(); >- if (topCommandShell == null || !topCommandShell.getWidgetId().getObjectId().equals(newCommandShell.getWidgetId().getObjectId())) >- { >+ if (topCommandShell == null >+ || !topCommandShell.getMacroObjectIdentifier() >+ .getObjectIdentifier().getWidgetId().equals( >+ newCommandShell >+ .getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getWidgetId())) { > pushStack(createCommandShell(shell)); >- } >+ } > } > > } > } > >- private void popStack() >- { >+ private void popStack() { > if (shellStack.isEmpty()) > return; > MacroCommandShell top = (MacroCommandShell) shellStack.pop(); > top.extractExpectedReturnCode(); > updateObjectMine(getTopShell()); > } >- >- >- private void pushStack(MacroCommandShell commandShell) >- { >+ >+ private void pushStack(MacroCommandShell commandShell) { > shellStack.push(commandShell); > shells.add(commandShell); > updateObjectMine(commandShell); > } > >- private void updateObjectMine(MacroCommandShell commandShell) >- { >- IObjectMine objectMine = MacroManager.getInstance().getObjectMine(); >+ private void updateObjectMine(MacroCommandShell commandShell) { >+ MacroObjectDescriptorMine objectMine = MacroManager.getInstance() >+ .getObjectMine(); > MacroCommandShell macroCommandShell = getTopShell(); > final String SHELL = "Shell"; >- IUIObject shellObject = null; >- if (objectMine != null && macroCommandShell != null) >- { >- try >- { >- String macroShellObjectId = macroCommandShell.getWidgetId().getObjectId().toString(); >- shellObject = objectMine.lookupUIObject(null, null, macroShellObjectId); >- if (shellObject == null) >- { >- shellObject = new UIObject(null); >- shellObject.setDescriptive(SHELL + (macroCommandShell.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING : ": " + macroCommandShell.getDescriptiveField())); >- shellObject.setObjectId(macroShellObjectId); >- shellObject.setReferenceId(objectMine.getUniqueReferenceId()); >- shellObject.setResolver(macroCommandShell.getWidgetId().getResolverId()); >- shellObject = objectMine.registerObject(shellObject); >+ MacroObjectDescriptor shellObject = null; >+ if (objectMine != null && macroCommandShell != null) { >+ try { >+ IMacroObjectIdentifier macroShellObjectId = macroCommandShell >+ .getMacroObjectIdentifier(); >+ shellObject = objectMine.lookupMacroObjectDescriptor(null, >+ null, macroShellObjectId.getObjectIdentifier() >+ .getWidgetId(), null); >+ if (shellObject == null) { >+ shellObject = new MacroObjectDescriptor(null); >+ ((MacroObjectDescriptor) shellObject) >+ .setDescriptive(SHELL >+ + (macroCommandShell.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING >+ : ": " >+ + macroCommandShell >+ .getDescriptiveField())); >+ ((MacroObjectDescriptor) shellObject) >+ .setWidgetId(macroShellObjectId >+ .getObjectIdentifier().getWidgetId()); >+ ((MacroObjectDescriptor) shellObject) >+ .setObjectId(macroShellObjectId >+ .getObjectIdentifier().getObjectId()); >+ ((MacroObjectDescriptor) shellObject) >+ .setResolver(macroCommandShell >+ .getMacroObjectIdentifier() >+ .getObjectIdentifier().getResolverId()); >+ shellObject = objectMine >+ .registerObject((MacroObjectDescriptor) shellObject); > } > objectMine.setActiveObject(shellObject); >- } >- catch (UIObjectNotFound e) >- { >+ } catch (UIObjectNotFound e) { > /* Shouldn't happen */ > e.printStackTrace(); >- } catch (IDCollisionException e) >- { >+ } catch (IDCollisionException e) { > /* Shouldn't happen */ > e.printStackTrace(); >- } catch (CoreException e) >- { >+ } catch (CoreException e) { > /* Shouldn't happen */ > e.printStackTrace(); > } > } >- >- /* Update the reference id of the widget identifier for the macro command shell */ >- if (shellObject != null) >- { >- commandShell.getWidgetId().setReferenceId(shellObject.getReferenceId()); >+ >+ /* >+ * Update the reference id of the widget identifier for the macro >+ * command shell >+ */ >+ if (shellObject != null) { >+ // seems to be more appropriate to set the corrsponding object for >+ // the shell >+ commandShell.setCorrespondingMacroObjectDescriptor(shellObject); >+ // CHANGED BY ANY: >+ // commandShell.getWidgetId().setReferenceId(shellObject.getReferenceId()); > } > } > >- private boolean closeShell(Shell shell) >- { >+ private boolean closeShell(Shell shell) { > if (shellStack.isEmpty()) > return false; > MacroCommandShell top = (MacroCommandShell) shellStack.peek(); >@@ -313,10 +346,8 @@ > return shellStack.isEmpty(); > } > >- private void updateStack() >- { >- while (shellStack.size() > 0) >- { >+ private void updateStack() { >+ while (shellStack.size() > 0) { > MacroCommandShell top = getTopShell(); > if (top.isDisposed()) > popStack(); >@@ -325,81 +356,74 @@ > } > } > >- public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException >- { >+ public boolean playback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { > reset(); > String mname = name != null ? name : "macro"; >- monitor.beginTask(AutoGUIMessages.AUTO_GUI_MACRO_EXECUTING + mname + " ...", shells.size()); >- for (int i = 0; i < shells.size(); i++) >- { >+ monitor.beginTask(AutoGUIMessages.AUTO_GUI_MACRO_EXECUTING + mname >+ + " ...", shells.size()); >+ for (int i = 0; i < shells.size(); i++) { > MacroCommandShell shell = (MacroCommandShell) shells.get(i); > final Shell[] sh = new Shell[1]; >- display.syncExec(new Runnable() >- { >- public void run() >- { >- sh[0] = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); >+ display.syncExec(new Runnable() { >+ >+ public void run() { >+ sh[0] = PlatformUI.getWorkbench() >+ .getActiveWorkbenchWindow().getShell(); > } > }); >- try >- { >- boolean result = shell.playback(display, sh[0], new SubProgressMonitor(monitor, 1)); >+ try { >+ boolean result = shell.playback(display, sh[0], >+ new SubProgressMonitor(monitor, 1)); > if (!result) > return false; >- } catch (CoreException e) >- { >+ } catch (CoreException e) { > throw e; > } > } > return true; > } > >- private void reset() >- { >+ private void reset() { > shellStack = null; > } > >- public void write(int indent, PrintWriter writer) >- { >+ public void write(int indent, PrintWriter writer) { > StringBuffer sb = new StringBuffer(); >- write (indent, sb); >+ write(indent, sb); > writer.write(sb.toString()); > } > >- public void write(int indent, StringBuffer sb) >- { >+ public void write(int indent, StringBuffer sb) { > /* Add <macro version="..." */ >- MacroUtil.addElement(sb, indent, MacroConstants.MACRO_ELEMENT, false, false); >- MacroUtil.addAttribute(sb, new String[] {MacroConstants.VERSION_ATTRIBUTE}, new String[] {SYNTAX_VERSION}, false, true); >+ MacroUtil.addElement(sb, indent, MacroConstants.MACRO_ELEMENT, false, >+ false); >+ MacroUtil.addAttribute(sb, >+ new String[] { MacroConstants.VERSION_ATTRIBUTE }, >+ new String[] { SYNTAX_VERSION }, false, true); > > int cindent = 1; > /* For every macro command shell */ >- for (int i = 0; i < shells.size(); i++) >- { >+ for (int i = 0; i < shells.size(); i++) { > MacroCommandShell cshell = (MacroCommandShell) shells.get(i); > cshell.write(cindent, sb); > } >- MacroUtil.addElement(sb, 0, MacroConstants.MACRO_ELEMENT, true, true); >+ MacroUtil.addElement(sb, 0, MacroConstants.MACRO_ELEMENT, true, true); > } >- >- >- public String getName() >- { >+ >+ public String getName() { > return name; > } > >- public void writeStart(int indent, StringBuffer writer) >- { >- /* Doesn't need to be implemented */ >+ public void writeStart(int indent, StringBuffer writer) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ public void writeFinish(int indent, StringBuffer writer) { >+ /* Doesn't need to be implemented */ > } > >- public void writeFinish(int indent, StringBuffer writer) >- { >- /* Doesn't need to be implemented */ >- } >- >- public int getShellStackSize() >- { >+ public int getShellStackSize() { > return shellStack.size(); > } > >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroObjectLocator.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroObjectLocator.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroObjectLocator.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroObjectLocator.java 27 Feb 2007 21:43:28 -0000 1.3 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,916 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2007 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.macro; >- >-import java.util.ArrayList; >-import java.util.Enumeration; >-import java.util.Hashtable; >-import java.util.Iterator; >-import java.util.Vector; >- >-import org.eclipse.core.runtime.CoreException; >-import org.eclipse.core.runtime.IPath; >-import org.eclipse.core.runtime.Path; >-import org.eclipse.jface.action.CoolBarManager; >-import org.eclipse.jface.action.IContributionItem; >-import org.eclipse.jface.action.ICoolBarManager; >-import org.eclipse.jface.action.IMenuManager; >-import org.eclipse.jface.action.IToolBarManager; >-import org.eclipse.jface.action.MenuManager; >-import org.eclipse.jface.action.ToolBarContributionItem; >-import org.eclipse.jface.action.ToolBarManager; >-import org.eclipse.jface.window.ApplicationWindow; >-import org.eclipse.jface.window.Window; >-import org.eclipse.jface.wizard.IWizardPage; >-import org.eclipse.jface.wizard.WizardDialog; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.widgets.Composite; >-import org.eclipse.swt.widgets.Control; >-import org.eclipse.swt.widgets.Decorations; >-import org.eclipse.swt.widgets.Event; >-import org.eclipse.swt.widgets.Item; >-import org.eclipse.swt.widgets.Menu; >-import org.eclipse.swt.widgets.MenuItem; >-import org.eclipse.swt.widgets.Shell; >-import org.eclipse.swt.widgets.ToolBar; >-import org.eclipse.swt.widgets.ToolItem; >-import org.eclipse.swt.widgets.Widget; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.commands.CommandTarget; >-import org.eclipse.tptp.test.auto.gui.internal.commands.EditorCommandTarget; >-import org.eclipse.tptp.test.auto.gui.internal.commands.ViewCommandTarget; >-import org.eclipse.tptp.test.auto.gui.internal.commands.WindowCommandTarget; >-import org.eclipse.tptp.test.auto.gui.internal.commands.WizardCommandTarget; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader; >-import org.eclipse.ui.IActionBars; >-import org.eclipse.ui.IEditorPart; >-import org.eclipse.ui.IEditorReference; >-import org.eclipse.ui.IViewPart; >-import org.eclipse.ui.IViewSite; >-import org.eclipse.ui.IWorkbenchPage; >-import org.eclipse.ui.IWorkbenchPart; >-import org.eclipse.ui.IWorkbenchWindow; >-import org.eclipse.ui.PartInitException; >-import org.eclipse.ui.testing.IWorkbenchPartTestable; >-import org.w3c.dom.Node; >- >-/** >- * A utility class used to locate different objects needed when playing back >- * commands. >- * >- * @author Ali Mehregani >- */ >-public class MacroObjectLocator >-{ >- >- public static CommandTarget[] locateCommandTarget(Composite parent, WidgetIdentifier wid, ArrayList parents, int line) throws CoreException >- { >- Shell shell = (Shell) parent; >- >- IPath contextId = wid.getContextId(); >- >- String firstToken = contextId.segment(0); >- Iterator iter = parents != null ? parents.iterator() : null; >- String id = contextId.segment(1); >- >- if (MacroConstants.MENUS_VALUE.equals(firstToken)) >- { >- return new CommandTarget[]{locateMenuBarItem(shell, wid, iter, line)}; >- } >- else if (MacroConstants.POPUP_VALUE.equals(firstToken)) >- { >- return new CommandTarget[]{ locatePopupMenuItem(shell, wid, iter, line)}; >- } >- else if (MacroConstants.TOOLBAR_VALUE.equals(firstToken)) >- { >- return new CommandTarget[]{ locateToolItem(shell, wid, line)}; >- } >- else if (MacroConstants.LOCAL_TOOLBAR_VALUE.equals(firstToken)) >- { >- return new CommandTarget[]{ locateLocalToolItem(shell, wid, line)}; >- } >- else if (MacroConstants.LOCAL_TOOLBAR_MENU_VALUE.equals(firstToken)) >- { >- return new CommandTarget[] {locateToolBarMenuItem(shell, wid, line)}; >- } >- else if (MacroConstants.WIZARD_VALUE.equals(firstToken)) >- { >- return locateWizardControl(shell, wid, line); >- } >- else if (MacroConstants.SHELL_VALUE.equals(firstToken)) >- { >- return locateShellControl(shell, wid, line); >- } >- else if (MacroConstants.WIZARD_PAGE_VALUE.equals(firstToken)) >- { >- return locateWizardPageControl(shell, id, wid, line); >- } >- else if (MacroConstants.VIEW_VALUE.equals(firstToken)) >- { >- return locateViewControl(shell, id, wid, line); >- } >- else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) >- { >- String inputName = contextId.segment(2); >- return locateEditorControl(shell, id, inputName, wid, line); >- } >- >- >- return null; >- } >- >- public static CommandTarget[] locateCommandTarget(Composite parent, WidgetIdentifier wid, int line) throws CoreException >- { >- return locateCommandTarget(parent, wid, null, line); >- } >- >- /** >- * Used to located the editor part with the passed id. >- * >- * @param shell >- * The current shell >- * @param id >- * The id of the editor part >- * @param line >- * The line number of the script (used to indicate the line >- * number if we throw a core exception. Mark as -1 if a script is >- * not being used) >- * @param input >- * If not null, then it attempts to match the input of the >- * identified editor with the input that is passed it. >- * >- * @return The editor part with the passed 'id' >- * >- * @throws CoreException >- * If the editor part cannot be located. >- */ >- public static IEditorPart locateEditor(Shell shell, String id, int line, String input) throws CoreException >- { >- Object data = shell.getData(); >- IEditorPart editor = null; >- >- try >- { >- if (data instanceof IWorkbenchWindow) >- { >- IWorkbenchWindow window = (IWorkbenchWindow) data; >- IWorkbenchPage page = window.getActivePage(); >- >- if (page != null) >- { >- IEditorReference[] erefs = page.getEditorReferences(); >- >- for (int i = 0; i < erefs.length; i++) >- { >- IEditorReference eref = erefs[i]; >- if (eref.getId().equals(id)) >- { >- // check the input >- IEditorPart part = eref.getEditor(true); >- if (input == null) >- { >- editor = part; >- break; >- } >- else if (part.getEditorInput().getName().equals(input)) >- { >- editor = part; >- break; >- } >- } >- } >- } >- } >- } >- catch (Throwable t) >- { >- >- } >- if (editor != null) >- { >- editor.getSite().getPage().activate(editor); >- return editor; >- } >- >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR, id), line); >- return null; >- } >- >- private static EditorCommandTarget[] locateEditorControl(Shell shell, String id, String inputName, WidgetIdentifier wid, int line) throws CoreException >- { >- Control[] controls = null; >- >- try >- { >- IEditorPart editor = locateEditor(shell, id, line, inputName); >- >- if (editor != null) >- { >- Composite c = getWorkbenchPartControl(editor); >- controls = locateVisibleChild(c, null, wid); >- if (controls != null) >- { >- EditorCommandTarget[] editorCommandTargets = new EditorCommandTarget[controls.length]; >- for (int i = 0; i < controls.length; i++) >- { >- editorCommandTargets[i] = new EditorCommandTarget(controls[i], editor); >- } >- >- return editorCommandTargets; >- } >- } >- } >- catch (Throwable t) >- { >- t.printStackTrace(); >- } >- if (controls == null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR_CON, wid.getObjectId().toString()), line); >- >- return null; >- } >- >- private static CommandTarget locateLocalToolItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException >- { >- try >- { >- IPath wpath = wid.getContextId().removeFirstSegments(1); >- String firstToken = wpath.segment(0); >- IWorkbenchPart workbenchPart = null; >- Composite parent = null; >- CommandTarget target = null; >- >- if (MacroConstants.VIEW_VALUE.equals(firstToken)) >- { >- String id = wpath.segment(1); >- workbenchPart = locateView(shell, id, line); >- } >- else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) >- { >- String id = wpath.segment(1); >- workbenchPart = locateEditor(shell, id, line, null); >- } >- else if (MacroConstants.SHELL_VALUE.equals(firstToken)) >- { >- parent = shell; >- } >- >- if (workbenchPart != null) >- { >- Composite comp = getWorkbenchPartControl(workbenchPart); >- MacroUtil.processDisplayEvents(shell.getDisplay()); >- parent = comp.getParent(); >- } >- >- if (parent != null) >- { >- WidgetIdentifier widgetIdentifier = new WidgetIdentifier(wid.getContextId(), new Path(wid.getContextId().lastSegment()), wid.getResolverId()); >- Control[] controls = locateVisibleChild(parent, null, widgetIdentifier); >- if (controls != null && controls.length > 0 && controls[0] instanceof ToolBar) >- { >- target = locateToolItem((ToolBar)controls[0], wid, line); >- } >- } >- >- if (target != null) >- return target; >- >- } >- catch (Throwable t) >- { >- /* The next line will throw an exception */ >- t.printStackTrace(); >- } >- >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR, wid.getFullyQualifiedId().toString()), line); >- return null; >- } >- >- private static CommandTarget locateMenuBarItem(Shell shell, WidgetIdentifier wid, Iterator parents, int line) throws CoreException >- { >- try >- { >- MenuItem item = null; >- Object data = shell.getData(); >- Menu menuBar = shell.getMenuBar(); >- >- if (data instanceof ApplicationWindow && parents != null) >- { >- ApplicationWindow window = (ApplicationWindow) data; >- MenuManager manager = window.getMenuBarManager(); >- item = locateMenuItem(manager, wid.getResolverId(), wid.getObjectId().toString(), parents, line); >- } >- else >- { >- item = locateMenuItem(menuBar, wid.getResolverId(), wid.getObjectId().toString(), line); >- } >- if (item != null) >- return new CommandTarget(item, menuBar); >- >- } >- catch (Throwable t) >- { >- /* The next line will throw exception */ >- } >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line); >- return null; >- } >- >- private static MenuItem locateMenuItem(Menu menu, String resolverId, String id, int line) >- { >- MenuItem[] items = menu.getItems(); >- >- for (int i = 0; i < items.length; i++) >- { >- MenuItem item = items[i]; >- >- Menu submenu = item.getMenu(); >- if (submenu != null) >- { >- /* Ali M.: We have to force the menu to open, since its items may not have already been created */ >- forceMenuOpen(null, submenu); >- MenuItem hit = locateMenuItem(submenu, resolverId, id, line); >- if (hit != null) >- return hit; >- } >- else >- { >- if (foundItem(item, resolverId, id)) >- return item; >- } >- } >- return null; >- } >- >- >- private static MenuItem locateMenuItem(MenuManager mng, String resolverId, String id, Iterator parents, int line) >- { >- IContributionItem[] items = mng.getItems(); >- >- String parentId = null; >- if (parents.hasNext()) >- parentId = (String) parents.next(); >- >- for (int i = 0; i < items.length; i++) >- { >- IContributionItem citem = items[i]; >- >- if (citem instanceof MenuManager) >- { >- MenuManager submenu = (MenuManager) citem; >- String subId = submenu.getId(); >- >- if (subId.equals(parentId)) >- { >- // show this menu to force dynamic items >- // to show >- Menu menu = submenu.getMenu(); >- forceMenuOpen(null, menu); >- >- MenuItem hit = locateMenuItem(submenu, resolverId, id, parents, line); >- forceMenuClosed(menu); >- if (hit != null) >- return hit; >- } >- } >- else >- { >- /* Ali M.: I believe that the first line and the following block were for optimization purposes only */ >- //String itemId = getActionId(citem); >- //if (itemId != null && id.equals(itemId)) >- //{ >- MenuItem hit = locateMenuItem(mng.getMenu(), resolverId, id, line); >- if (hit != null) >- return hit; >- //} >- } >- } >- return null; >- } >- >- private static CommandTarget locatePopupMenuItem(Shell shell, WidgetIdentifier wid, Iterator parents, int line) throws CoreException >- { >- try >- { >- IPath contextPath = wid.getContextId().removeFirstSegments(1); >- IPath wpath = new Path(getLastSegment(contextPath)); >- >- int widgetPathInx = contextPath.toString().indexOf(wpath.toString()); >- if (widgetPathInx > 0) >- contextPath = new Path(contextPath.toString().substring(0, widgetPathInx - 1)); >- CommandTarget[] targets = locateCommandTarget(shell, new WidgetIdentifier(contextPath, wpath, null), line); >- if (targets != null) >- { >- for (int i = 0; i < targets.length; i++) >- { >- Control control = (Control) targets[i].getWidget(); >- Menu popupMenu = control.getMenu(); >- if (popupMenu != null) >- { >- forceMenuOpen(control, popupMenu); >- MenuItem menuItem = locateMenuItem(popupMenu, wid.getResolverId(), wid.getObjectId().toString(), line); >- forceMenuClosed(popupMenu); >- if (menuItem != null) >- { >- return new CommandTarget(menuItem, control); >- } >- } >- } >- } >- } >- catch (Throwable t) >- { >- /* The next line will throw an exception */ >- } >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line); >- return null; >- } >- >- private static CommandTarget locateToolBarMenuItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException >- { >- try >- { >- IPath contextPath = wid.getContextId().removeFirstSegments(1); >- >- /* The context is a menu */ >- IViewPart viewPart = null; >- if (MacroConstants.VIEW_VALUE.equals(contextPath.segment(0))) >- { >- viewPart = locateView(shell, contextPath.segment(1), line); >- } >- >- >- IViewSite viewSite = viewPart == null ? null : viewPart.getViewSite(); >- IMenuManager menuManager = null; >- if (viewSite != null) >- { >- IActionBars actionBar = viewSite.getActionBars(); >- actionBar.updateActionBars(); >- menuManager = actionBar.getMenuManager(); >- } >- >- if (menuManager instanceof MenuManager) >- { >- >- Menu menu = ((MenuManager)menuManager).getMenu(); >- if (menu == null) >- { >- menu = ((MenuManager)menuManager).createMenuBar((Decorations)shell); >- } >- if (menu != null) >- { >- forceMenuOpen(null, menu); >- MenuItem menuItem = locateMenuItem(menu, wid.getResolverId(), wid.getObjectId().toString(), line); >- forceMenuClosed(menu); >- if (menuItem != null) >- { >- return new CommandTarget(menuItem, null); >- } >- } >- } >- } >- catch (Throwable t) >- { >- /* The next line will throw an exception */ >- } >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line); >- return null; >- } >- private static String getLastSegment(IPath contextPath) >- { >- String[] segments = contextPath.segments(); >- String candidate = ""; >- for (int i = segments.length - 1; i >= 0; i--) >- { >- if (candidate.length() > 0) >- candidate = "/" + candidate; >- candidate = segments[i] + candidate; >- int openingBracesInx = candidate.indexOf('{'); >- int closingBracesInx = candidate.indexOf('}'); >- if ((openingBracesInx == -1 && closingBracesInx == -1) || (openingBracesInx >= 0 && openingBracesInx < closingBracesInx)) >- return candidate; >- } >- >- return ""; >- } >- >- private static WindowCommandTarget[] locateShellControl(Shell shell, WidgetIdentifier wid, int line) throws CoreException >- { >- Control[] controls = null; >- Window window = null; >- try >- { >- window = (Window) shell.getData(); >- controls = locateVisibleChild(shell, null, wid); >- } >- catch (Throwable t) >- { >- >- } >- if (controls == null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL, wid.getObjectId().toString()), line); >- >- WindowCommandTarget[] windowCommandTarget = new WindowCommandTarget[controls.length]; >- for (int i = 0; i < controls.length; i++) >- { >- if (controls[i].isDisposed()) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid.getObjectId().toString()), line); >- windowCommandTarget[i] = new WindowCommandTarget(controls[i], window); >- } >- >- return windowCommandTarget; >- } >- >- private static CommandTarget locateToolItem(ICoolBarManager coolMng, WidgetIdentifier wid, int line) >- { >- IContributionItem[] items = coolMng.getItems(); >- for (int i = 0; i < items.length; i++) >- { >- if (items[i] instanceof ToolBarContributionItem) >- { >- ToolBarContributionItem item = (ToolBarContributionItem) items[i]; >- IToolBarManager toolMng = item.getToolBarManager(); >- CommandTarget target = locateToolItem((ToolBarManager) toolMng, wid, line); >- if (target != null) >- return target; >- } >- } >- return null; >- } >- >- private static CommandTarget locateToolItem(ToolBarManager toolMng, WidgetIdentifier wid, int line) >- { >- return locateToolItem(toolMng.getControl(), wid, line); >- } >- >- >- private static CommandTarget locateToolItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException >- { >- CommandTarget target = null; >- try >- { >- Object data = shell.getData(); >- if (data instanceof ApplicationWindow) >- { >- ApplicationWindow window = (ApplicationWindow) data; >- CoolBarManager coolMng = window.getCoolBarManager(); >- if (coolMng != null) >- { >- target = locateToolItem(coolMng, wid, line); >- } >- ToolBarManager toolMng = window.getToolBarManager(); >- if (toolMng != null) >- { >- target = locateToolItem(toolMng, wid, line); >- } >- } >- } >- catch (Throwable t) >- { >- /* The next line will throw an exception */ >- target = null; >- } >- if (target == null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL, wid.getObjectId().toString()), line); >- return target; >- } >- >- private static CommandTarget locateToolItem(ToolBar toolBar, WidgetIdentifier wid, int line) >- { >- if (toolBar == null) >- return null; >- ToolItem[] items = toolBar.getItems(); >- for (int i = 0; i < items.length; i++) >- { >- ToolItem item = items[i]; >- if (foundItem(item, wid.getResolverId(), wid.getObjectId().toString())) >- return new CommandTarget(item, toolBar); >- } >- return null; >- } >- >- >- /** >- * Used to located the view part with the passed id. >- * >- * @param shell >- * The current shell >- * @param id >- * The id of the view part >- * @param line >- * The line number of the script (used to indicate the line >- * number if we throw a core exception. Mark as -1 if a script is >- * not being used) >- * >- * @return The view part with the passed 'id' >- * >- * @throws CoreException >- * If the view part cannot be located. >- */ >- public static IViewPart locateView(Shell shell, String id, int line) throws CoreException >- { >- try >- { >- Object data = shell.getData(); >- >- if (data instanceof IWorkbenchWindow) >- { >- IWorkbenchWindow window = (IWorkbenchWindow) data; >- IWorkbenchPage page = window.getActivePage(); >- if (page != null) >- { >- IViewPart view = page.findView(id); >- >- if (view == null) >- { >- try >- { >- view = page.showView(id); >- >- } >- catch (PartInitException pie) >- { >- /* Do a thorough search */ >- IWorkbenchWindow[] windows = GuiPlugin.getDefault().getWorkbench().getWorkbenchWindows(); >- >- /* For every workbench window */ >- for (int i = 0; i < windows.length && view == null; i++) >- { >- /* For every page of a workbench window */ >- IWorkbenchPage[] pages = windows[i].getPages(); >- for (int j = 0; j < pages.length && view == null; j++) >- { >- view = pages[j].findView(id); >- >- } >- } >- //need to mke sure that even if it is found in another page, we show it. >- >- } >- } >- // added for defcet 175320 in order to ensure the page is >- //given focus no matter where it is found >- page.showView(id); >- return view; >- } >- } >- } >- catch (Throwable t) >- { >- /* The next line will throw an exception */ >- } >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW, id), line); >- return null; >- } >- >- private static ViewCommandTarget[] locateViewControl(Shell shell, String id, WidgetIdentifier wid, int line) throws CoreException >- { >- Control[] controls = null; >- try >- { >- IViewPart view = locateView(shell, id, line); >- if (view != null) >- { >- Composite c = getWorkbenchPartControl(view); >- controls = locateVisibleChild((Composite) c, null, wid); >- // controls will never be null but might be empty >- // This way the error is caught here and will reflect the view not found >- if (controls.length >0) >- { >- ViewCommandTarget[] viewCommandTarget = new ViewCommandTarget[controls.length]; >- for (int i = 0; i < controls.length; i++) >- { >- viewCommandTarget[i] = new ViewCommandTarget(controls[i], view); >- } >- return viewCommandTarget; >- } >- } >- } >- catch (Throwable t) >- { >- >- } >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW_CON, wid.getObjectId().toString()), line); >- return null; >- } >- >- private static Control[] locateVisibleChild(Composite parent, Composite skip, WidgetIdentifier widgetId) >- { >- int[] counter = new int[1]; >- counter[0] = 0; >- String wid = widgetId.getObjectId().toString(); >- int sloc = wid.indexOf('#'); >- String wclassName = null; >- if (sloc != -1) >- wclassName = wid.substring(0, sloc); >- >- /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: We need to return all possible matches */ >- Vector matches = new Vector(); >- Vector indices = new Vector(); >- locateVisibleChild(parent, skip, widgetId, wclassName, counter, matches, indices); >- Control[] matchedControls = new Control[matches.size()]; >- matches.toArray(matchedControls); >- return matchedControls; >- } >- >- private static Control locateVisibleChild(Composite parent, Composite skip, WidgetIdentifier id, String wclassName, int[] index, Vector matches, Vector indices) >- { >- return MacroUtil.recursiveSearch(parent, skip, null, id, wclassName, index, matches, indices); >- } >- >- private static WizardCommandTarget[] locateWizardControl(Shell shell, WidgetIdentifier wid, int line) throws CoreException >- { >- WizardDialog wdialog = null; >- Control[] controls = null; >- try >- { >- wdialog = (WizardDialog) shell.getData(); >- IWizardPage page = wdialog.getCurrentPage(); >- Composite pparent = (Composite) page.getControl(); >- controls = locateVisibleChild(shell, pparent, wid); >- } >- catch (Throwable t) >- { >- >- } >- if (controls == null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD, wid.getObjectId().toString()), line); >- >- WizardCommandTarget[] wizardCommandTarget = new WizardCommandTarget[controls.length]; >- for (int i = 0; i < controls.length; i++) >- { >- if (controls[i].isDisposed()) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid.getObjectId().toString()), line); >- wizardCommandTarget[i] = new WizardCommandTarget(controls[i], wdialog); >- } >- >- return wizardCommandTarget; >- } >- >- private static WizardCommandTarget[] locateWizardPageControl(Shell shell, String id, WidgetIdentifier wid, int line) throws CoreException >- { >- Control[] controls = null; >- try >- { >- Object data = shell.getData(); >- if (data instanceof WizardDialog) >- { >- WizardDialog wdialog = (WizardDialog) data; >- IWizardPage page = wdialog.getCurrentPage(); >- // assert page >- // if (pname.equals(id)==false) >- // throwCoreException("Unexpected wizard page: "+pname+", expected >- // "+id, line); >- Composite pparent = (Composite) page.getControl(); >- controls = locateVisibleChild(pparent, null, wid); >- if (controls != null) >- { >- WizardCommandTarget[] wizardCommandTarget = new WizardCommandTarget[controls.length]; >- for (int i = 0; i < controls.length; i++) >- { >- wizardCommandTarget[i] = new WizardCommandTarget(controls[i], wdialog); >- } >- return wizardCommandTarget; >- } >- } >- } >- catch (Throwable t) >- { >- >- } >- if (controls == null) >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD_CON, wid.getObjectId().toString()), line); >- return null; >- } >- >- private static void forceMenuOpen(Control c, Menu menu) >- { >- Event e = new Event(); >- e.type = SWT.Show; >- e.widget = menu; >- >- menu.notifyListeners(e.type, e); >- MacroUtil.processDisplayEvents(menu.getDisplay()); >- } >- >- private static void forceMenuClosed(Menu menu) >- { >- Event e = new Event(); >- e.type = SWT.Hide; >- e.widget = menu; >- >- menu.notifyListeners(e.type, e); >- MacroUtil.processDisplayEvents(menu.getDisplay()); >- } >- >- >- /** >- * If the node passed in has a reference id, then this method looks up the id in >- * the object mine and attempts to find the object that is referenced. >- * >- * @param node Represents the XML node >- * @param lineTable Contains line level information >- * >- * @return A String[] of length 2, where String[0] = context id and String[1] = object >- * id. If the node does not have a reference id, then null is returned. >- * >- * @throws CoreException If the node contains a reference id attribute but the >- * corresponding object mine does not have any such object. >- */ >- public static IUIObject lookupReferenceId(IUIObject parent, Node node, Hashtable lineTable) throws CoreException >- { >- String referenceId = MacroUtil.getAttribute(node, MacroConstants.REFERENCE_ID_ATTRIBUTE); >- if (referenceId == null) >- return null; >- >- IUIObject correspondingObject = MacroManager.getInstance().getObjectMine().lookupUIObject(parent, referenceId); >- if (correspondingObject == null) >- { >- Integer[] lineLevelDetail = (Integer[]) lineTable.get(node); >- AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, referenceId), lineLevelDetail == null ? 0 : lineLevelDetail[0].intValue()); >- } >- else >- { >- return correspondingObject; >- } >- >- /* Code not reached beyond this point */ >- return null; >- } >- >- >- /** >- * We have to use internal APIs here to get the controls of a part >- */ >- public static Composite getWorkbenchPartControl (IWorkbenchPart part) >- { >- IWorkbenchPartTestable testable = (IWorkbenchPartTestable)part.getSite().getAdapter(IWorkbenchPartTestable.class); >- return testable.getControl().getParent(); >- } >- >- /** >- * Returns true if the id computed for 'item' matches 'id' >- * >- * @param item The tool item >- * @param resolverId The resolver id -- can be null >- * @param id The id that should be matched against >- * @return true if there is a match, and false otherwise >- */ >- public static boolean foundItem(Item item, String resolverId, Object id) >- { >- /* Try the widget resolvers first */ >- if (foundWidget(item, resolverId, id)) >- return true; >- >- /* Give the old policy a try */ >- String toolItemIdStr = MacroUtil.getActionId(item).toString(); >- if (toolItemIdStr != null && toolItemIdStr.equals(id)) >- return true; >- >- return false; >- } >- >- /** >- * Returns true iff the widget matches the id passed in. >- * >- * @param widget The widget >- * @param resolverId The resolver id -- can be null >- * @param id The id >- * @return true iff the widget matches the id passed in. >- */ >- public static boolean foundWidget(Widget widget, String resolverId, Object id) >- { >- MacroManager macroManager = MacroManager.getInstance(); >- Hashtable widgetResolvers = macroManager.getWidgetResolvers(); >- >- if (resolverId != null) >- { >- WidgetResolverLoader loader = (WidgetResolverLoader)widgetResolvers.get(resolverId); >- if (loader != null) >- return loader.getWidgetResolver().foundWidget(widget, id); >- return false; >- } >- >- Enumeration keys = widgetResolvers.keys(); >- while (keys.hasMoreElements()) >- { >- if (((WidgetResolverLoader)widgetResolvers.get(keys.nextElement())).getWidgetResolver().foundWidget(widget, id)) >- return true; >- } >- return false; >- } >- >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/AbstractMacroInstruction.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/macro/AbstractMacroInstruction.java,v >retrieving revision 1.2 >diff -u -r1.2 AbstractMacroInstruction.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/AbstractMacroInstruction.java 27 Oct 2006 14:39:23 -0000 1.2 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/AbstractMacroInstruction.java 26 Jul 2008 19:22:10 -0000 >@@ -14,110 +14,61 @@ > import java.util.Map; > > import org.eclipse.core.runtime.CoreException; >-import org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier; > import org.w3c.dom.Node; > > /** >- * Provides an abstract implementation of {@link IMacroInstruction}. Contributors >- * can subclass {@link AbstractMacroInstruction} or provide a direct implementaion >- * of {@link IMacroInstruction}. >+ * Provides an abstract implementation of {@link IMacroInstruction}. Contributors can subclass {@link AbstractMacroInstruction} or provide a direct >+ * implementaion of {@link IMacroInstruction}. > * > * @author Ali Mehregani > */ >-public abstract class AbstractMacroInstruction implements IMacroInstruction >-{ >- /** The widget id associated with this command */ >- private WidgetIdentifier widgetId; >- >- /** The corresponding UI object for this macro instruction*/ >- private IUIObject uiObject; >- >- /** The line range of this macro instruction relative to the macro script */ >- private int [] range; >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable) >- */ >- public void load(Node node, Hashtable lineTable) throws CoreException >- { >- bindSourceLocation(node, lineTable); >+public abstract class AbstractMacroInstruction implements IMacroInstruction { >+ >+ /** The line range of this macro instruction relative to the macro script */ >+ private int[] range; >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable) >+ */ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ bindSourceLocation(node, >+ lineTable); > } > >- > /** > * Binds the line details with this macro instruction > * >- * @param node The node of this instruction >- * @param lineTable The line level information >+ * @param node >+ * The node of this instruction >+ * @param lineTable >+ * The line level information > */ >- protected void bindSourceLocation(Node node, Map lineTable) >- { >- Integer[] lines = (Integer[]) lineTable.get(node); >- if (lines != null) { >- range = new int[2]; >- range[0] = lines[0].intValue(); >- range[1] = lines[1].intValue(); >- } >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getStartLine() >- */ >- public int getStartLine() >- { >- if (range == null) >- return -1; >- return range[0]; >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getStopLine() >- */ >- public int getStopLine() >- { >- if (range == null) >- return -1; >- return range[1]; >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getCorrespondingObject() >- */ >- public IUIObject getCorrespondingObject() >- { >- return uiObject; >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#setCorrespondingObject(org.eclipse.tptp.test.auto.gui.internal.core.IUIObject) >- */ >- public void setCorrespondingObject(IUIObject uiObject) >- { >- this.uiObject = uiObject; >- } >- >- >- /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getWidgetId() >- */ >- public WidgetIdentifier getWidgetId() >- { >- return widgetId; >+ protected void bindSourceLocation(Node node, Map lineTable) { >+ Integer[] lines = (Integer[]) lineTable.get(node); >+ if (lines != null) { >+ range = new int[2]; >+ range[0] = lines[0].intValue(); >+ range[1] = lines[1].intValue(); >+ } > } >- >- >+ > /** >- * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#setWidgetId(org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier) >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getStartLine() > */ >- public void setWidgetId(WidgetIdentifier widgetIdentifier) >- { >- this.widgetId = widgetIdentifier; >+ public int getStartLine() { >+ if (range == null) >+ return -1; >+ return range[0]; > } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getStopLine() >+ */ >+ public int getStopLine() { >+ if (range == null) >+ return -1; >+ return range[1]; >+ } >+ >+ > } >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/XMLDefaultHandler.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/XMLDefaultHandler.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/XMLDefaultHandler.java >--- src/org/eclipse/tptp/test/auto/gui/internal/macro/XMLDefaultHandler.java 10 Jul 2006 14:49:06 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,166 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2003, 2006 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.macro; >- >-import java.util.Hashtable; >-import java.util.Stack; >- >-import javax.xml.parsers.DocumentBuilderFactory; >-import javax.xml.parsers.ParserConfigurationException; >- >-import org.w3c.dom.Element; >-import org.w3c.dom.Node; >-import org.w3c.dom.Text; >-import org.xml.sax.Attributes; >-import org.xml.sax.Locator; >-import org.xml.sax.helpers.DefaultHandler; >- >-public class XMLDefaultHandler extends DefaultHandler >-{ >- >- private org.w3c.dom.Document fDocument; >- >- private Locator fLocator; >- >- private Hashtable fLineTable; >- >- private Element fRootElement; >- >- private Stack fElementStack = new Stack(); >- >- /* Indicates whether a CDATA section is reached */ >- private boolean cdataStarted; >- >- public XMLDefaultHandler() >- { >- fLineTable = new Hashtable(); >- } >- >- public void startElement(String uri, String localName, String qName, Attributes attributes) >- { >- Element element = fDocument.createElement(qName); >- for (int i = 0; i < attributes.getLength(); i++) >- { >- element.setAttribute(attributes.getQName(i), attributes.getValue(i)); >- } >- >- Integer lineNumber = new Integer(fLocator.getLineNumber()); >- Integer[] range = new Integer[] { lineNumber, new Integer(-1) }; >- fLineTable.put(element, range); >- if (fRootElement == null) >- fRootElement = element; >- else >- ((Element) fElementStack.peek()).appendChild(element); >- fElementStack.push(element); >- } >- >- public void endElement(String uri, String localName, String qName) >- { >- Integer[] range = (Integer[]) fLineTable.get(fElementStack.pop()); >- range[1] = new Integer(fLocator.getLineNumber()); >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator) >- */ >- public void setDocumentLocator(Locator locator) >- { >- fLocator = locator; >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.xml.sax.helpers.DefaultHandler#startDocument() >- */ >- public void startDocument() >- { >- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); >- try >- { >- fDocument = factory.newDocumentBuilder().newDocument(); >- } >- catch (ParserConfigurationException e) >- { >- } >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.xml.sax.helpers.DefaultHandler#endDocument() >- */ >- public void endDocument() >- { >- fDocument.appendChild(fRootElement); >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, >- * java.lang.String) >- */ >- public void processingInstruction(String target, String data) >- { >- fDocument.appendChild(fDocument.createProcessingInstruction(target, data)); >- } >- >- /* >- * (non-Javadoc) >- * >- * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) >- */ >- public void characters(char[] characters, int start, int length) >- { >- StringBuffer buff = new StringBuffer(); >- for (int i = 0; i < length; i++) >- { >- buff.append(characters[start + i]); >- } >- >- String buffValue = buff.toString(); >- boolean isBufferJustWhiteSpace = buffValue.trim().equals(""); >- boolean isBufferEmpty = buffValue.length() <= 0; >- >- if ((cdataStarted && isBufferEmpty) || (!cdataStarted && isBufferJustWhiteSpace)) >- { >- cdataStarted = false; >- return; >- } >- >- Text text = fDocument.createTextNode(buffValue); >- cdataStarted = true; >- if (fRootElement == null) >- fDocument.appendChild(text); >- else >- ((Element) fElementStack.peek()).appendChild(text); >- } >- >- public Node getDocumentElement() >- { >- fDocument.getDocumentElement().normalize(); >- return fDocument.getDocumentElement(); >- } >- >- public org.w3c.dom.Document getDocument() >- { >- fDocument.getDocumentElement().normalize(); >- return fDocument; >- } >- >- public Hashtable getLineTable() >- { >- return fLineTable; >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/messages.properties >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/messages.properties,v >retrieving revision 1.31 >diff -u -r1.31 messages.properties >--- src/org/eclipse/tptp/test/auto/gui/internal/messages.properties 22 Jul 2008 19:10:13 -0000 1.31 >+++ src/org/eclipse/tptp/test/auto/gui/internal/messages.properties 26 Jul 2008 19:21:51 -0000 >@@ -143,6 +143,7 @@ > AUTO_GUI_ERROR_MACRO_MENU = Cannot locate menu item: {0} > AUTO_GUI_ERROR_MACRO_TOOL = Cannot locate tool item: {0} > AUTO_GUI_ERROR_MACRO_TOOL_BAR = Cannot locate local tool bar item: {0} >+AUTO_GUI_ERROR_MACRO_TAB = Cannot locate tab item: {0} > AUTO_GUI_ERROR_MACRO_WIZARD = Cannot locate wizard control: {0} > AUTO_GUI_ERROR_MACRO_WIZARD_CON = Cannot locate wizard page control: {0} > AUTO_GUI_ERROR_MACRO_SHELL = Cannot locate shell control: {0} >@@ -199,7 +200,7 @@ > AUTO_GUI_ERROR_TST_WRONG_SRC = The second last segment of the verification hook class path must be a source folder > AUTO_GUI_ERROR_TST_OBJ_MINE_T = Error loading object mine... > AUTO_GUI_ERROR_TST_OBJ_MINE = Error parsing the object mine of the test suite >-AUTO_GUI_ERROR_TST_OBJ_MINE_REF = The reference id of the object {0} is missing or invalid >+AUTO_GUI_ERROR_TST_OBJ_MINE_REF = The reference id of the UI object with widget id {0} and object id {1} is missing or invalid > AUTO_GUI_ERROR_TST_OBJ_MINE_ID = The object id reference, {0}, collides with another object that already exists > AUTO_GUI_ERROR_TST_OBJ_MINE_REG = Error registering an object with the object mine of the test suite > >@@ -208,6 +209,7 @@ > AUTO_GUI_CONTROL_DIALOG_TITLE = Test Case Control Center > AUTO_GUI_CONTROL_VER_HOOK = Verification Hooks > AUTO_GUI_CONTROL_VER_INSERT = &Insert >+AUTO_GUI_CONTROL_VER_INCLUDE_UI_OBJECT = Check this if you do not only want to have the context (Editor, View, Shell) but also the selected UI Object (Button, MenuItem, ...) passed as parameter to the verfication hook method. > AUTO_GUI_CONTROL_TERMINATE = Terminate > AUTO_GUI_CONTROL_RESTART = Restart > AUTO_GUI_CONTROL_POSITION_BASED = Toggle On/Off Position Based Recording >@@ -226,3 +228,9 @@ > AUTO_GUI_DETAILS_STARTPT = Starting Point: > > AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL = Undoable Text Operation >+ >+AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE = The macro object {0} could not be resolved. >+ >+AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS = The UI object with widget id {0} and object id {1} could not be unambigously identified. >+AUTO_GUI_RESOLVER_IDENTIFIER_MISSING = The resolver {0} did not set its id on the resolved UI object identifier. >+ >Index: src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIImages.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIImages.java,v >retrieving revision 1.14 >diff -u -r1.14 AutoGUIImages.java >--- src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIImages.java 5 Mar 2008 18:27:25 -0000 1.14 >+++ src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIImages.java 26 Jul 2008 19:21:48 -0000 >@@ -20,6 +20,7 @@ > * > * > * @author Paul E. Slauenwhite >+ * @author Alexander Nyssen > * @version March 5, 2008 > * @since August 19, 2005 > */ >@@ -56,6 +57,7 @@ > public static final String IMG_NEW_AUTO_GUI = "new_atestsuite.gif"; > public static final String OBJECT_MINE = "object_mine.gif"; > public static final String POSITION_BASED = "position_based.gif"; >+ public static final String VERIFICATION_HOOK = "verification_hook.gif"; > public static final String VARS = "variables.gif"; > public static final String VAR_ITEM = "variable.gif"; > public static final String TERMINATE = "terminate.gif"; >@@ -100,6 +102,9 @@ > > add("d", T_TOOL, POSITION_BASED); > add("e", T_TOOL, POSITION_BASED); >+ >+ add("d", T_TOOL, VERIFICATION_HOOK); >+ add("e", T_TOOL, VERIFICATION_HOOK); > > add("d", T_TOOL, TERMINATE); > add("e", T_TOOL, TERMINATE); >@@ -166,4 +171,4 @@ > /* wizban */ > add(T_WIZBAN, IMG_NEW_AUTO_GUI_WIZBAN); > } >-} >+} >\ No newline at end of file >Index: src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIMessages.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIMessages.java,v >retrieving revision 1.24 >diff -u -r1.24 AutoGUIMessages.java >--- src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIMessages.java 14 Jul 2008 19:18:57 -0000 1.24 >+++ src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIMessages.java 26 Jul 2008 19:21:49 -0000 >@@ -19,6 +19,7 @@ > * > * > * @author Paul E. Slauenwhite >+ * @author Alexander Nyssen > * @version July 14, 2008 > * @since August 19, 2005 > */ >@@ -154,6 +155,7 @@ > public static String AUTO_GUI_ERROR_MACRO_MENU; > public static String AUTO_GUI_ERROR_MACRO_TOOL; > public static String AUTO_GUI_ERROR_MACRO_TOOL_BAR; >+ public static String AUTO_GUI_ERROR_MACRO_TAB; > public static String AUTO_GUI_ERROR_MACRO_WIZARD; > public static String AUTO_GUI_ERROR_MACRO_WIZARD_CON; > public static String AUTO_GUI_ERROR_MACRO_SHELL; >@@ -218,7 +220,8 @@ > > public static String AUTO_GUI_CONTROL_DIALOG_TITLE; > public static String AUTO_GUI_CONTROL_VER_HOOK; >- public static String AUTO_GUI_CONTROL_VER_INSERT; >+ public static String AUTO_GUI_CONTROL_VER_INSERT; >+ public static String AUTO_GUI_CONTROL_VER_INCLUDE_UI_OBJECT; > public static String AUTO_GUI_CONTROL_TERMINATE; > public static String AUTO_GUI_CONTROL_RESTART; > public static String AUTO_GUI_CONTROL_POSITION_BASED; >@@ -238,6 +241,11 @@ > > public static String AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL; > >+ public static String AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE; >+ >+ public static String AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS; >+ public static String AUTO_GUI_RESOLVER_IDENTIFIER_MISSING; >+ > static { > NLS.initializeMessages(BUNDLE_NAME, AutoGUIMessages.class); > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIUtil.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIUtil.java,v >retrieving revision 1.10 >diff -u -r1.10 AutoGUIUtil.java >--- src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIUtil.java 8 Aug 2006 17:56:06 -0000 1.10 >+++ src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIUtil.java 26 Jul 2008 19:21:50 -0000 >@@ -72,6 +72,7 @@ > * A primitive utility class that is commonly shared between the auto gui classes > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ > public class AutoGUIUtil > { >@@ -178,8 +179,13 @@ > IProject[] workspaceProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); > for (int i = 0; i < workspaceProjects.length; i++) > { >- if (workspaceProjects[i].getNature(JavaCore.NATURE_ID) == null) >+ // fix for bug #206768 >+ if (!workspaceProjects[i].isOpen()) > continue; >+ >+ if( workspaceProjects[i].getNature(JavaCore.NATURE_ID) == null) >+ continue; >+ > IJavaProject javaProject = JavaCore.create(workspaceProjects[i]); > > if (javaProject == null || !javaProject.exists()) >@@ -602,6 +608,10 @@ > throwCoreException(message, 0, null); > } > >+ public static void throwCoreException(String message, Throwable t) throws CoreException >+ { >+ throwCoreException(message, 0, t); >+ } > > public static void throwCoreException(String message, int line) throws CoreException > { >Index: src/org/eclipse/tptp/test/auto/gui/internal/dialogs/AutoGUITestControllerDialog.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/dialogs/AutoGUITestControllerDialog.java,v >retrieving revision 1.7 >diff -u -r1.7 AutoGUITestControllerDialog.java >--- src/org/eclipse/tptp/test/auto/gui/internal/dialogs/AutoGUITestControllerDialog.java 18 Apr 2008 14:51:21 -0000 1.7 >+++ src/org/eclipse/tptp/test/auto/gui/internal/dialogs/AutoGUITestControllerDialog.java 26 Jul 2008 19:22:06 -0000 >@@ -46,112 +46,149 @@ > import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; > >- > /** >- * This dialog is displayed while the user is recording their macro. >- * It is used to control the test case that is being recorded. >+ * This dialog is displayed while the user is recording their macro. It is used >+ * to control the test case that is being recorded. > * > * @author Ali Mehregani > * @author Paul E. Slauenwhite >+ * @author Alexander Nyssen > * @version March 5, 2008 > * @since July 10, 2006 > */ >-public class AutoGUITestControllerDialog extends Dialog >-implements SelectionListener, MouseListener, MouseMoveListener, KeyListener, DisposeListener >-{ >+public class AutoGUITestControllerDialog extends Dialog implements >+ SelectionListener, MouseListener, MouseMoveListener, KeyListener, >+ DisposeListener { > >- private Shell sShell; // @jve:decl-index=0:visual-constraint="10,10" >+ private Shell sShell; // @jve:decl-index=0:visual-constraint="10,10" > private Composite toolbarComposite; > private Group verificationGrp; > private Group controlGrp; > private ToolBar toolBar; >- private Text verificationName; >- private Button insertButton; >- private Label nameLbl; >+ >+ /* verification group */ >+ private Label verficationHookNameLabel; >+ private Text verificationHookNameText; >+ private ToolBar verificationScopExtensionToolBar; >+ private ToolItem verificationScopeExtensionToolItem; >+ private Button verificationHookInsertionButton; >+ > private ToolItem terminate; > private ToolItem restart; > private ToolItem positionBasedRecording; > private ToolItem recordWaitTime; >- >+ > private Composite statusComposite; > private Label statuslbl; >- >+ > /* Listener container */ > private Vector listenerBucket; >- >- /* Global coordinates of the shell - everything else is defined relative to this */ >+ >+ /* >+ * Global coordinates of the shell - everything else is defined relative to >+ * this >+ */ > private Point shellBounds; >- >- /* Indicates that the mouse button is pushed on the shell */ >+ >+ /* Indicates that the mouse button is pushed on the shell */ > private boolean isMouseDown; >- >+ > /* The dialog is moved relative to this position */ > private Point originalPosition; >- >- /* Indicates whether the control center shell is disposed or not */ >+ >+ /* Indicates whether the control center shell is disposed or not */ > private boolean isShellDisposed; >- >- /* The real parent that the dialog is suppose to have. This may not necessarily be the actual parent >- * of the shell if it is forced to go to the background */ >+ >+ /* >+ * The real parent that the dialog is suppose to have. This may not >+ * necessarily be the actual parent of the shell if it is forced to go to >+ * the background >+ */ > private Shell realParent; >- >- /* The actual parent of the dialog. This should always return the same result as getParent() */ >+ >+ /* >+ * The actual parent of the dialog. This should always return the same >+ * result as getParent() >+ */ > private Shell actualParent; > >- /* The first control center dialog will have this set and the successive ones will not */ >+ /* >+ * The first control center dialog will have this set and the successive >+ * ones will not >+ */ > private boolean isRoot; >- >+ > /* The control root (set only if isRoot is false) */ > private AutoGUITestControllerDialog rootControl; >- >+ > /* The control delegator (maybe set only if isRoot is true) */ > private AutoGUITestControllerDialog delegator; >- >- /* The display listener that will be listening in for new active shells (set only if isRoot is true) */ >- private DisplayListener displayListener; >- >+ >+ /* >+ * The display listener that will be listening in for new active shells (set >+ * only if isRoot is true) >+ */ >+ private DisplayListener displayListener; >+ > /* The last status of the control center dialog */ > private String lastStatus; >- >+ > /* The last location of the control dialog box */ > private Point lastLocation; >- >- /* Indicates whether position based should be on (should be set before shell is created)*/ >+ >+ /* >+ * Indicates whether position based should be on (should be set before shell >+ * is created) >+ */ > private boolean positionBasedOn; >- >+ > /* Indicates whether wait times should be recorded */ > private boolean waitTimeOn; >- >- /* Stores the root's parent. At any time this dialog will either have its parent set to >- * the root's parent or the active shell */ >+ >+ /* >+ * Indicates wether the generated verification hook method should contain a >+ * second parameter for the UI object that was selected inside the context >+ */ >+ private boolean verificationScopeExtended; >+ >+ /* >+ * Stores the root's parent. At any time this dialog will either have its >+ * parent set to the root's parent or the active shell >+ */ > private static Shell rootParent; >- >+ > /* Indicates whether this dialog has purposely been sent to back */ > private boolean forceToBack; >- >+ > /* Indicates whether the dialog is activated or not */ > private static boolean activated; >- >+ > /* Event types */ >- public final static byte TERMINATE = 0x01; >- public final static byte VERIFICATION_HOOK_INSERT = 0x02; >- public final static byte RESTART = 0x03; >- public final static byte POSITION_BASED = 0x04; >- public final static byte WAIT_TIME = 0x05; >- >+ public final static byte TERMINATE = 0x01; >+ public final static byte RESTART = 0x02; >+ public final static byte POSITION_BASED = 0x03; >+ public final static byte WAIT_TIME = 0x04; >+ public final static byte VERIFICATION_HOOK_INSERT = 0x05; >+ > private final static int DO_NOT_DISPOSE = 1020; >- >- /* At all times, there should only be one active dialog displayed to the user */ >+ >+ /* >+ * At all times, there should only be one active dialog displayed to the >+ * user >+ */ > private static AutoGUITestControllerDialog activeControlDialog; >- >+ > /** >- * This constructor is used to create dialogs that are opened when the active shell changes. >+ * This constructor is used to create dialogs that are opened when the >+ * active shell changes. > * >- * @param parentShell The parent shell >- * @param rootControl The control center that all the tasks will be delegated to. >+ * @param parentShell >+ * The parent shell >+ * @param rootControl >+ * The control center that all the tasks will be delegated to. > */ >- public AutoGUITestControllerDialog(Shell parentShell, AutoGUITestControllerDialog rootControl) >- { >+ public AutoGUITestControllerDialog(Shell parentShell, >+ AutoGUITestControllerDialog rootControl) { > super(parentShell); > isShellDisposed = false; > realParent = parentShell; >@@ -159,12 +196,10 @@ > isRoot = false; > this.rootControl = rootControl; > this.positionBasedOn = false; >- >+ > } >- >- >- public AutoGUITestControllerDialog(Shell parent) >- { >+ >+ public AutoGUITestControllerDialog(Shell parent) { > super(parent); > isShellDisposed = false; > realParent = parent; >@@ -172,21 +207,18 @@ > isRoot = true; > activated = true; > } >- >- >- public void openDialog() >- { >+ >+ public void openDialog() { > openDialog(null); > } >- >+ > /** > * Equivalent to openDialog (true) > */ >- public void openDialog(final Shell activeShell) >- { >- shellBounds = new Point (317, 105); >+ public void openDialog(final Shell activeShell) { >+ shellBounds = new Point(317, 105); > originalPosition = new Point(0, 0); >- sShell = new Shell(getParent(), SWT.MODELESS); >+ sShell = new Shell(getParent(), SWT.MODELESS); > sShell.setText(AutoGUIMessages.AUTO_GUI_CONTROL_DIALOG_TITLE); > sShell.setLayout(new GridLayout()); > sShell.setSize(shellBounds); >@@ -195,689 +227,700 @@ > sShell.addMouseListener(this); > sShell.addMouseMoveListener(this); > sShell.addDisposeListener(this); >- >+ > /* We would like the macro recorder to ignore this shell */ > sShell.setData(MacroManager.IGNORE, Boolean.TRUE); >- >- sShell.setFocus(); >+ >+ sShell.setFocus(); > createToolbarComposite(); > createStatusComposite(); >- >+ > ActivationListener activationListener = null; > /* We need to always stay on top of every shell */ >- if (isRoot) >- { >+ if (isRoot) { > rootParent = getParent(); > displayListener = new DisplayListener(); > Display.getCurrent().addFilter(SWT.Activate, displayListener); > } >- >- else >- { >- /* Defect #113543: Under the RedHat linux environment, if a modeless dialog is opened with an application modal dialog as its >- * parent, the modality of the opened dialog will be restricted to application modal (blocking the parent dialog). We'll >- * need to dispose and open the control center dialog based on activation and deactivation events. This is very expensive and >- * it is only performed on non-windows environments. >- */ >+ >+ else { >+ /* >+ * Defect #113543: Under the RedHat linux environment, if a modeless >+ * dialog is opened with an application modal dialog as its parent, >+ * the modality of the opened dialog will be restricted to >+ * application modal (blocking the parent dialog). We'll need to >+ * dispose and open the control center dialog based on activation >+ * and deactivation events. This is very expensive and it is only >+ * performed on non-windows environments. >+ */ > final String WINDOWS_OS = "windows"; > String platformOS = System.getProperty("os.name"); >- >- if (platformOS == null || platformOS.toLowerCase().indexOf(WINDOWS_OS) == -1) >- { >+ >+ if (platformOS == null >+ || platformOS.toLowerCase().indexOf(WINDOWS_OS) == -1) { > activationListener = new ActivationListener(false); > } > } >- >+ > /* Open the dialog */ > activeControlDialog = this; >- sShell.open(); >- >- if (activationListener != null) >- { >- sShell.addListener(SWT.Activate, activationListener); >- sShell.addListener(SWT.Deactivate, activationListener); >- >- final ActivationListener finalActivationListener = activationListener; >- GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(100, new Runnable(){ >+ sShell.open(); > >- public void run() { >- if (activeShell != null && !activeShell.isDisposed()) >- activeShell.setActive(); >- >- finalActivationListener.setEnable(true); >- >- }}); >- } >- >- >- >- } >- >- >- /** >- * This method initializes toolbarComposite >- * >- */ >+ if (activationListener != null) { >+ sShell.addListener(SWT.Activate, activationListener); >+ sShell.addListener(SWT.Deactivate, activationListener); >+ >+ final ActivationListener finalActivationListener = activationListener; >+ GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(100, >+ new Runnable() { >+ >+ public void run() { >+ if (activeShell != null >+ && !activeShell.isDisposed()) >+ activeShell.setActive(); >+ >+ finalActivationListener.setEnable(true); >+ >+ } >+ }); >+ } >+ >+ } >+ >+ /** >+ * This method initializes toolbarComposite >+ * >+ */ > private void createToolbarComposite() { > GridLayout gridLayout = new GridLayout(); > gridLayout.numColumns = 2; >- toolbarComposite = new Composite(sShell, SWT.NONE); >+ toolbarComposite = new Composite(sShell, SWT.NONE); > createControlGrp(); > createVerificationGrp(); > toolbarComposite.setLayoutData(GridDataUtil.createHorizontalFill()); > toolbarComposite.addMouseListener(this); > toolbarComposite.addMouseMoveListener(this); >- toolbarComposite.setLayout(gridLayout); >+ toolbarComposite.setLayout(gridLayout); > } >- >- private void createStatusComposite() >- { >+ >+ private void createStatusComposite() { > GridData gd = new GridData(); > gd.horizontalAlignment = SWT.CENTER; >- >+ > GridLayout gridLayout = new GridLayout(); >- statusComposite = new Composite (sShell, SWT.NONE); >+ statusComposite = new Composite(sShell, SWT.NONE); > statusComposite.setLayout(gridLayout); > statusComposite.setLayoutData(gd); > statusComposite.addMouseListener(this); > statusComposite.addMouseMoveListener(this); >- >+ > GridData gd2 = new GridData(); > gd2.horizontalAlignment = SWT.CENTER; > gd2.grabExcessHorizontalSpace = true; >- gd2.widthHint = (int)(shellBounds.x * 0.8); >- statuslbl = new Label (statusComposite, SWT.NONE); >+ gd2.widthHint = (int) (shellBounds.x * 0.8); >+ statuslbl = new Label(statusComposite, SWT.NONE); > statuslbl.setAlignment(SWT.CENTER); > statuslbl.setLayoutData(gd2); > statuslbl.addMouseListener(this); > statuslbl.addMouseMoveListener(this); > } >- >- >+ > /** >- * This method initializes verificationGrp >- * >- */ >+ * This method initializes verificationGrp >+ * >+ */ > private void createVerificationGrp() { > GridLayout gridLayout1 = new GridLayout(); >- gridLayout1.numColumns = 3; >- verificationGrp = new Group(toolbarComposite, SWT.NONE); >+ gridLayout1.numColumns = 4; >+ verificationGrp = new Group(toolbarComposite, SWT.NONE); > verificationGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_HOOK); > verificationGrp.setLayout(gridLayout1); >- verificationGrp.setLayoutData (GridDataUtil.createHorizontalFill()); >+ verificationGrp.setLayoutData(GridDataUtil.createHorizontalFill()); > verificationGrp.addMouseListener(this); > verificationGrp.addMouseMoveListener(this); >- nameLbl = new Label(verificationGrp, SWT.NONE); >- nameLbl.setText(AutoGUIMessages.AUTO_GUI_NEW_DIALOG_NAME); >- nameLbl.addMouseListener(this); >- nameLbl.addMouseMoveListener(this); >- verificationName = new Text(verificationGrp, SWT.BORDER); >- verificationName.setLayoutData (GridDataUtil.createHorizontalFill()); >- verificationName.addKeyListener(this); >- insertButton = new Button(verificationGrp, SWT.NONE); >- insertButton.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INSERT); >- insertButton.addSelectionListener(this); >- insertButton.setEnabled(false); >- sShell.setDefaultButton(insertButton); >- } >- /** >- * This method initializes controlGrp >- * >- */ >+ >+ verficationHookNameLabel = new Label(verificationGrp, SWT.NONE); >+ verficationHookNameLabel >+ .setText(AutoGUIMessages.AUTO_GUI_NEW_DIALOG_NAME); >+ verficationHookNameLabel.addMouseListener(this); >+ verficationHookNameLabel.addMouseMoveListener(this); >+ >+ verificationHookNameText = new Text(verificationGrp, SWT.BORDER); >+ verificationHookNameText.setLayoutData(GridDataUtil >+ .createHorizontalFill()); >+ verificationHookNameText.addKeyListener(this); >+ >+ verificationScopExtensionToolBar = new ToolBar(verificationGrp, >+ SWT.NONE); >+ verificationScopeExtensionToolItem = new ToolItem( >+ verificationScopExtensionToolBar, SWT.CHECK); >+ verificationScopeExtensionToolItem.setImage(AutoGUIImages.getInstance() >+ .getImage("e", AutoGUIImages.VERIFICATION_HOOK)); >+ verificationScopeExtensionToolItem >+ .setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INCLUDE_UI_OBJECT); >+ verificationScopeExtensionToolItem >+ .setSelection(verificationScopeExtended); >+ verificationScopeExtensionToolItem.addSelectionListener(this); >+ verificationScopeExtensionToolItem.setEnabled(false); >+ >+ verificationHookInsertionButton = new Button(verificationGrp, SWT.NONE); >+ verificationHookInsertionButton >+ .setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INSERT); >+ verificationHookInsertionButton.addSelectionListener(this); >+ verificationHookInsertionButton.setEnabled(false); >+ sShell.setDefaultButton(verificationHookInsertionButton); >+ } >+ >+ /** >+ * This method initializes controlGrp >+ * >+ */ > private void createControlGrp() { >- controlGrp = new Group(toolbarComposite, SWT.NONE); >+ controlGrp = new Group(toolbarComposite, SWT.NONE); > controlGrp.setLayout(new GridLayout()); > controlGrp.addMouseListener(this); > controlGrp.addMouseMoveListener(this); > createToolBar(); > controlGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_CONT); > } >+ > /** >- * This method initializes toolBar >- * >- */ >+ * This method initializes toolBar >+ * >+ */ > private void createToolBar() { > GridData gridData = new GridData(); > gridData.horizontalAlignment = SWT.CENTER; > gridData.grabExcessHorizontalSpace = true; >- toolBar = new ToolBar(controlGrp, SWT.NONE); >- >+ toolBar = new ToolBar(controlGrp, SWT.NONE); >+ > /* The terminate button */ > terminate = new ToolItem(toolBar, SWT.PUSH); >- terminate.setImage(AutoGUIImages.getInstance().getImage("e", AutoGUIImages.TERMINATE)); >+ terminate.setImage(AutoGUIImages.getInstance().getImage("e", >+ AutoGUIImages.TERMINATE)); > terminate.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_TERMINATE); > terminate.addSelectionListener(this); >- >+ > /* The restart button */ > restart = new ToolItem(toolBar, SWT.PUSH); >- restart.setImage(AutoGUIImages.getInstance().getImage(AutoGUIImages.RESTART)); >+ restart >+ .setImage(AutoGUIImages.getInstance() >+ .getImage(AutoGUIImages.RESTART)); > restart.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART); > restart.addSelectionListener(this); >- >+ > /* A separator */ > ToolItem sep = new ToolItem(toolBar, SWT.SEPARATOR); > sep.setText(""); >- >+ > /* The position-based recording button */ >- positionBasedRecording = new ToolItem (toolBar, SWT.CHECK); >- positionBasedRecording.setImage(AutoGUIImages.getInstance().getImage("e", AutoGUIImages.POSITION_BASED)); >- positionBasedRecording.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_POSITION_BASED); >+ positionBasedRecording = new ToolItem(toolBar, SWT.CHECK); >+ positionBasedRecording.setImage(AutoGUIImages.getInstance().getImage("e", >+ AutoGUIImages.POSITION_BASED)); >+ positionBasedRecording >+ .setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_POSITION_BASED); > positionBasedRecording.setSelection(positionBasedOn); > positionBasedRecording.addSelectionListener(this); >- >- /* The wait time toggle buttong */ >- recordWaitTime = new ToolItem (toolBar, SWT.CHECK); >- recordWaitTime .setImage(AutoGUIImages.getInstance().getImage(AutoGUIImages.WAIT_TIME)); >- recordWaitTime.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_WAIT_TIME); >+ >+ /* The wait time toggle buttong */ >+ recordWaitTime = new ToolItem(toolBar, SWT.CHECK); >+ recordWaitTime.setImage(AutoGUIImages.getInstance() >+ .getImage(AutoGUIImages.WAIT_TIME)); >+ recordWaitTime >+ .setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_WAIT_TIME); > recordWaitTime.setSelection(waitTimeOn); > recordWaitTime.addSelectionListener(this); >- >- >+ > toolBar.setLayoutData(gridData); > } >- >- >+ > /** >- * Used to register listeners with the control dialog box >- * See event types for the type of events that the listener >- * will be invoked with. >+ * Used to register listeners with the control dialog box See event types >+ * for the type of events that the listener will be invoked with. > */ >- public void registerListener (AutoGUIControllerListener listener) >- { >+ public void registerListener(AutoGUIControllerListener listener) { > if (listenerBucket == null) > listenerBucket = new Vector(); > if (listener != null && !listenerBucket.contains(listener)) > listenerBucket.add(listener); > } >- >- public void terminate() >- { >- if (rootControl != null) >- { >+ >+ public void terminate() { >+ if (rootControl != null) { > rootControl.terminate(); >- } >- else if (isRoot) >- { >+ } else if (isRoot) { > Display.getCurrent().removeFilter(SWT.Activate, displayListener); > activeControlDialog.dispose(); >- notifyListeners (TERMINATE, null); >+ notifyListeners(TERMINATE, null); > } > > } > >- public void widgetSelected(SelectionEvent e) >- { >+ public void widgetSelected(SelectionEvent e) { > byte eventType = 0; >- >+ > /* Determine the type of event */ >- if (e.widget == terminate) >- { >+ if (e.widget == terminate) { > eventType = TERMINATE; >- notifyListeners (eventType, null); >- >+ notifyListeners(eventType, null); >+ > if (e.detail != DO_NOT_DISPOSE) > dispose(); >- >+ > return; > } > /* This is the verification insertion event */ >- else if (e.widget == insertButton) >+ else if (e.widget == verificationHookInsertionButton) > eventType = VERIFICATION_HOOK_INSERT; >- else if (e.widget == restart) >+ else if (e.widget == verificationScopeExtensionToolItem) { >+ verificationScopeExtended = ((ToolItem) e.widget).getSelection(); >+ } else if (e.widget == restart) > eventType = RESTART; >- else if (e.widget == positionBasedRecording) >- { >- positionBasedOn = ((ToolItem)e.widget).getSelection(); >+ else if (e.widget == positionBasedRecording) { >+ positionBasedOn = ((ToolItem) e.widget).getSelection(); > eventType = POSITION_BASED; >- } >- else if (e.widget == recordWaitTime) >- { >- waitTimeOn = ((ToolItem)e.widget).getSelection(); >+ } else if (e.widget == recordWaitTime) { >+ waitTimeOn = ((ToolItem) e.widget).getSelection(); > eventType = WAIT_TIME; > } >- >+ > if (eventType != 0) >- notifyListeners (eventType, verificationName.getText()); >+ notifyListeners(eventType, verificationHookNameText.getText()); > } >- >- >- public void widgetDisposed(DisposeEvent e) >- { >- if (!isShellDisposed && isRoot) >- { >+ >+ public void widgetDisposed(DisposeEvent e) { >+ if (!isShellDisposed && isRoot) { > isShellDisposed = true; >- >- /* The shell is been disposed. Simulate a termination */ >+ >+ /* The shell is been disposed. Simulate a termination */ > Event event = new Event(); > event.widget = terminate; > event.detail = DO_NOT_DISPOSE; >- widgetSelected(new SelectionEvent(event)); >+ widgetSelected(new SelectionEvent(event)); > } >- >- } >- >+ >+ } >+ > /** > * A helper method used to notify the registered listeners > * >- * @param eventType The type of event that caused this invokation >+ * @param eventType >+ * The type of event that caused this invokation > */ >- protected void notifyListeners (byte eventType, Object value) >- { >- >- /* If we're not the root control center, then we're expected to delegate the tasks */ >- if (!isRoot) >- { >- rootControl.notifyListeners(eventType, value); >- } >- else >- { >+ protected void notifyListeners(byte eventType, Object value) { >+ >+ /* >+ * If we're not the root control center, then we're expected to delegate >+ * the tasks >+ */ >+ if (!isRoot) { >+ rootControl.notifyListeners(eventType, value); >+ } else { > /* Remove the listener if we were terminated */ > if (eventType == TERMINATE) >- Display.getCurrent().removeFilter(SWT.Activate, displayListener); >- >- /* Update appropriate fields if delegator updated the position-based or wait-time-recording options */ >- if (delegator != null) >- { >+ Display.getCurrent() >+ .removeFilter(SWT.Activate, displayListener); >+ >+ /* >+ * Update appropriate fields if delegator updated the position-based >+ * or wait-time-recording options >+ */ >+ if (delegator != null) { > if (eventType == POSITION_BASED) > positionBasedOn = delegator.isPositionBasedOn(); > else if (eventType == WAIT_TIME) > waitTimeOn = delegator.isWaitTimeOn(); > } >- >+ > /* Start notifying the listeners */ > int size = listenerBucket.size(); >- for (int i = 0; i < size; i++) >- { >- ((AutoGUIControllerListener)listenerBucket.get(i)).handleEvent(eventType, value); >+ for (int i = 0; i < size; i++) { >+ ((AutoGUIControllerListener) listenerBucket.get(i)) >+ .handleEvent(eventType, value); > } > } > } > >+ public void widgetDefaultSelected(SelectionEvent e) { >+ /* Doesn't need to be implemented */ >+ } > >- public void widgetDefaultSelected(SelectionEvent e) >- { >- /* Doesn't need to be implemented */ >- } >- >- >- /** >- * A chance to clean up after our self >- */ >- public void dispose() >- { >- isShellDisposed = true; >- if (sShell != null && !sShell.isDisposed()) >- { >+ /** >+ * A chance to clean up after our self >+ */ >+ public void dispose() { >+ isShellDisposed = true; >+ if (sShell != null && !sShell.isDisposed()) { > sShell.close(); > toolBar.dispose(); >- verificationName.dispose(); >- insertButton.dispose(); >- nameLbl.dispose(); >+ verificationHookNameText.dispose(); >+ verificationScopeExtensionToolItem.dispose(); >+ verificationHookInsertionButton.dispose(); >+ verficationHookNameLabel.dispose(); > terminate.dispose(); > restart.dispose(); > positionBasedRecording.dispose(); > verificationGrp.dispose(); > controlGrp.dispose(); > toolbarComposite.dispose(); >- sShell.dispose(); // @jve:decl-index=0:visual-constraint="10,10" >+ sShell.dispose(); // @jve:decl-index=0:visual-constraint="10,10" > } >- >+ > toolBar = null; >- verificationName = null; >- insertButton = null; >- nameLbl = null; >- terminate = null; >+ verificationHookNameText = null; >+ verificationScopeExtensionToolItem = null; >+ verificationHookInsertionButton = null; >+ verficationHookNameLabel = null; >+ terminate = null; > verificationGrp = null; > controlGrp = null; > toolbarComposite = null; >- sShell = null; // @jve:decl-index=0:visual-constraint="10,10" >- >+ sShell = null; // @jve:decl-index=0:visual-constraint="10,10" >+ > shellBounds = null; > originalPosition = null; > } >- >- public void mouseDoubleClick(MouseEvent e) >- { >+ >+ public void mouseDoubleClick(MouseEvent e) { > /* Doesn't need to be implemented */ > } >- >- public void mouseDown(MouseEvent e) >- { >+ >+ public void mouseDown(MouseEvent e) { > isMouseDown = true; > originalPosition.x = e.x; > originalPosition.y = e.y; > } > >- >- public void mouseUp(MouseEvent e) >- { >+ public void mouseUp(MouseEvent e) { > isMouseDown = false; > } > >- > /** >- * Move the dialog box when the user clicks on the shell and moves the cursor >+ * Move the dialog box when the user clicks on the shell and moves the >+ * cursor > */ >- public void mouseMove(MouseEvent e) >- { >- if (isMouseDown) >- { >+ public void mouseMove(MouseEvent e) { >+ if (isMouseDown) { > int xMove = e.x - originalPosition.x; > int yMove = e.y - originalPosition.y; >- >+ > Point currentLocation = sShell.getLocation(); >- sShell.setLocation(currentLocation.x + xMove, currentLocation.y + yMove); >+ sShell.setLocation(currentLocation.x + xMove, currentLocation.y >+ + yMove); > lastLocation = sShell.getLocation(); >- } >+ } > } > > /** > * Updates the status of the control dialog center > * >- * @param status The status to be printed >+ * @param status >+ * The status to be printed > */ >- public void setStatus (String status) >- { >- >+ public void setStatus(String status) { >+ > /* The delegator has to handle this (if one exists) */ >- if (isRoot && delegator != null && !delegator.isShellDisposed) >- { >+ if (isRoot && delegator != null && !delegator.isShellDisposed) { > delegator.setStatus(status); > return; > } >- //added for defect 173451 to ensure that in case where the widget is disposed >+ // added for defect 173451 to ensure that in case where the widget is >+ // disposed > // we switch to the correct reference (for Linux platform) > // Liz Dancy >- else if (statuslbl.isDisposed() && delegator.isShellDisposed){ >- >+ else if (statuslbl.isDisposed() && delegator.isShellDisposed) { >+ > this.updateDelegator(this.realParent, this.realParent); > statuslbl = this.delegator.statuslbl; >- } >+ } > if (status == null) > return; >- >+ > lastStatus = status; >- String finalStatus = AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BASE + status; >+ String finalStatus = AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BASE >+ + status; > boolean toolong = false; > if (finalStatus.length() > 30) > toolong = true; >- >- >+ > statuslbl.setToolTipText(finalStatus); > if (toolong) >- finalStatus = finalStatus.substring (0, 30) + "..."; >- >- statuslbl.setText (finalStatus); >- } >- >- public String getLastStatus() >- { >+ finalStatus = finalStatus.substring(0, 30) + "..."; >+ >+ statuslbl.setText(finalStatus); >+ } >+ >+ public String getLastStatus() { > if (isRoot && delegator != null) > return delegator.getLastStatus(); > return lastStatus; > } >- >- >+ > /** > * A primitive listener class > */ >- public interface AutoGUIControllerListener >- { >+ public interface AutoGUIControllerListener { > /** >- * Invoked when there is an event caused by the user interacting with the control center. >+ * Invoked when there is an event caused by the user interacting with >+ * the control center. > * >- * @param event The event type >- * @param value The value associated with the event. It can be null if no value is associated with >- * the event type. >+ * @param event >+ * The event type >+ * @param value >+ * The value associated with the event. It can be null if no >+ * value is associated with the event type. > */ >- public void handleEvent (byte event, Object value); >+ public void handleEvent(byte event, Object value); > } > >- >- public void keyPressed(KeyEvent e) >- { >- keyReleased (null); >+ public void keyPressed(KeyEvent e) { >+ keyReleased(null); > } > >- >- public void keyReleased(KeyEvent e) >- { >- if (verificationName.getText().trim().equals("")) >- { >- insertButton.setEnabled(false); >+ public void keyReleased(KeyEvent e) { >+ if (verificationHookNameText.getText().trim().equals("")) { >+ verificationHookInsertionButton.setEnabled(false); >+ verificationScopeExtensionToolItem.setEnabled(false); > return; > } >- insertButton.setEnabled(true); >+ verificationHookInsertionButton.setEnabled(true); >+ verificationScopeExtensionToolItem.setEnabled(true); > } >- >- public Point getLastLocation () >- { >+ >+ public Point getLastLocation() { > if (isRoot && delegator != null) > return delegator.getLastLocation(); > if (sShell != null && !sShell.isDisposed()) > return sShell.getLocation(); >- >+ > return lastLocation; > } >- >- public void setLocation (Point location) >- { >+ >+ public void setLocation(Point location) { > lastLocation = location; > } >- >- >+ > public void setPositionBasedOn(boolean isPositionBasedOn) { > this.positionBasedOn = isPositionBasedOn; > } > >- > public boolean isPositionBasedOn() { > return positionBasedOn; > } > >+ public boolean isVerficationScopeExtended() { >+ return verificationScopeExtended; >+ } > > public boolean isWaitTimeOn() { > return waitTimeOn; > } > >- > public void setWaitTimeOn(boolean waitTimeOn) { > this.waitTimeOn = waitTimeOn; > } >- >- >- public synchronized void updateDelegator (Shell guardian, Shell realParent) >- { >- updateDelegator (guardian, realParent, null); >- } >- >- public void updateDelegator (Shell guardian, Shell realParent, Shell activeShell) >- { >+ >+ public synchronized void updateDelegator(Shell guardian, Shell realParent) { >+ updateDelegator(guardian, realParent, null); >+ } >+ >+ public void updateDelegator(Shell guardian, Shell realParent, >+ Shell activeShell) { > if (guardian.isDisposed()) > return; >- >- Point location = getLastLocation(); >+ >+ Point location = getLastLocation(); > String lastStatus = getLastStatus(); >- >+ > AutoGUITestControllerDialog rootControl = null; > if (isRoot) > rootControl = this; >- >+ > else > rootControl = this.rootControl; >- >+ > AutoGUITestControllerDialog delegator = rootControl.getDelegator(); >- /* Get rid of the last delegator */ >- if (activeControlDialog != null ){ >+ /* Get rid of the last delegator */ >+ if (activeControlDialog != null) { > activeControlDialog.dispose(); >- >+ > } >- >- delegator = new AutoGUITestControllerDialog(guardian, AutoGUITestControllerDialog.this); >+ >+ delegator = new AutoGUITestControllerDialog(guardian, >+ AutoGUITestControllerDialog.this); > delegator.setLocation(location); > delegator.setPositionBasedOn(isPositionBasedOn()); > delegator.setWaitTimeOn(isWaitTimeOn()); > delegator.openDialog(activeShell); >- delegator.setStatus(lastStatus); >+ delegator.setStatus(lastStatus); > delegator.actualParent = guardian; > delegator.realParent = realParent; >- >+ > rootControl.setDelegator(delegator); > } >- >- public AutoGUITestControllerDialog getDelegator() >- { >+ >+ public AutoGUITestControllerDialog getDelegator() { > return delegator; > } >- >- public void setDelegator(AutoGUITestControllerDialog delegator) >- { >+ >+ public void setDelegator(AutoGUITestControllerDialog delegator) { > this.delegator = delegator; > } >- >- >- private class DisplayListener implements Listener >- { >- public void handleEvent(final Event event) >- { >- >- class ChangeDialogParentOp implements Runnable >- { >+ >+ private class DisplayListener implements Listener { >+ public void handleEvent(final Event event) { >+ >+ class ChangeDialogParentOp implements Runnable { > private DisplayListener listener; >- public ChangeDialogParentOp(DisplayListener listener) >- { >+ >+ public ChangeDialogParentOp(DisplayListener listener) { > this.listener = listener; > } >- >- public void run() >- { >- try >- { >+ >+ public void run() { >+ try { > if (forceToBack) > return; >- >- boolean isNewShellPresent = event.widget instanceof Shell && /* The widget is a shell */ >- !event.widget.isDisposed() && /* It hasn't been disposed */ >- event.widget.getData(MacroManager.IGNORE) == null && /* It shouldn't be ignored */ >- (realParent.isDisposed() || !event.widget.equals(realParent)) && /* It's not the current shell that we have as our parent */ >- !isComboBox(actualParent = (Shell)event.widget); /* It's not a combo box */ >+ >+ boolean isNewShellPresent = event.widget instanceof Shell >+ && /* The widget is a shell */ >+ !event.widget.isDisposed() >+ && /* It hasn't been disposed */ >+ event.widget.getData(MacroManager.IGNORE) == null >+ && /* It shouldn't be ignored */ >+ (realParent.isDisposed() || !event.widget >+ .equals(realParent)) >+ && /* >+ * It's not the current shell that we have >+ * as our parent >+ */ >+ !isComboBox(actualParent = (Shell) event.widget); /* >+ * It's >+ * not >+ * a >+ * combo >+ * box >+ */ > if (!isNewShellPresent) > return; >+ // need to check for activated >+ // bugzilla_184767 >+ // Liz Dancy >+ if (activated) >+ updateDelegator(actualParent, actualParent, >+ actualParent); > >- updateDelegator (actualParent, actualParent, actualParent); >- > if (actualParent != rootParent) > activated = true; > AutoGUITestControllerDialog.this.realParent = actualParent; > } > >- catch (Throwable t) >- { >- /* If at any point an error occurs, then de-register this listener */ >- Display.getCurrent().removeFilter(SWT.Activate, listener); >+ catch (Throwable t) { >+ /* >+ * If at any point an error occurs, then de-register >+ * this listener >+ */ >+ Display.getCurrent().removeFilter(SWT.Activate, >+ listener); > } >- >+ > } > >- private boolean isComboBox(Shell shell) >- { >+ private boolean isComboBox(Shell shell) { > Control[] children = shell.getChildren(); > return children.length == 1 && children[0] instanceof List; > } >- }; >- >- /* We need to run this as a timer operation because it may otherwise cause a widget disposed exeception. The exception >- * is caused in cases where we get an activation event on shells that are activated only for short periods of time. Running >- * this operation as a timer operation will guarantee that an activated shell is present and not disposed after 50 milliseconds. >- * This ultimately avoids processing activated shells that have a very short life span. */ >- GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(50, new ChangeDialogParentOp(this)); >- } >- } >+ } >+ ; > >+ /* >+ * We need to run this as a timer operation because it may otherwise >+ * cause a widget disposed exeception. The exception is caused in >+ * cases where we get an activation event on shells that are >+ * activated only for short periods of time. Running this operation >+ * as a timer operation will guarantee that an activated shell is >+ * present and not disposed after 50 milliseconds. This ultimately >+ * avoids processing activated shells that have a very short life >+ * span. >+ */ >+ GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(50, >+ new ChangeDialogParentOp(this)); >+ } >+ } > >- public class ActivationListener implements Listener >- { >+ public class ActivationListener implements Listener { > private boolean enable; >- >- public ActivationListener(boolean enable) >- { >+ >+ public ActivationListener(boolean enable) { > this.enable = enable; > } >- >- >- public void handleEvent(Event event) >- { >+ >+ public void handleEvent(Event event) { > if (!enable) > return; >- >- >- switch (event.type) >- { >- case SWT.Activate: >- controlCenterDialogActivated(); >- break; >- case SWT.Deactivate: >- controlCenterDialogDeactivated(); >- break; >+ >+ switch (event.type) { >+ case SWT.Activate: >+ controlCenterDialogActivated(); >+ break; >+ case SWT.Deactivate: >+ controlCenterDialogDeactivated(); >+ break; > } >- >+ > } > >- private void controlCenterDialogActivated() >- { >- /* If the parent of the control center dialog is a modal dialog but it was sent back, then we'll need to >- * bring the control center dialog to the front */ >- if (isModalParent() && actualParent == rootParent && !activated) >- { >- activated = true; >+ private void controlCenterDialogActivated() { >+ /* >+ * If the parent of the control center dialog is a modal dialog but >+ * it was sent back, then we'll need to bring the control center >+ * dialog to the front >+ */ >+ if (isModalParent() && actualParent == rootParent && !activated) { >+ activated = false; > forceToBack = false; > enable = false; >- updateDelegator (realParent, realParent); >+ updateDelegator(realParent, realParent); > enable = true; >- >+ > } >- >+ > } >- >- private void controlCenterDialogDeactivated() >- { >- /* If the parent of the control center dialog is modal, then we need to send it back */ >- if (isModalParent() && actualParent == realParent && activated) >- { >+ >+ private void controlCenterDialogDeactivated() { >+ /* >+ * If the parent of the control center dialog is modal, then we need >+ * to send it back >+ */ >+ if (isModalParent() && actualParent == realParent && activated) { > activated = false; > forceToBack = true; >- enable = false; >- >+ enable = false; >+ > Shell realParent = null; >- if (delegator != null){ >+ if (delegator != null) { > realParent = delegator.realParent; >- } >- else >+ } else > realParent = AutoGUITestControllerDialog.this.realParent; >- > updateDelegator(rootParent, realParent, realParent); >- >- >+ > enable = true; > } > } > >- >- private boolean isModalParent() >- { >+ private boolean isModalParent() { > if (realParent == null || realParent.isDisposed()) > return false; >- >+ > int parentStyle = realParent.getStyle(); >- return (parentStyle & SWT.SYSTEM_MODAL) != 0 || >- (parentStyle & SWT.PRIMARY_MODAL) != 0 || >- (parentStyle & SWT.APPLICATION_MODAL) != 0; >- } >- >- private void setEnable (boolean enable) >- { >+ return (parentStyle & SWT.SYSTEM_MODAL) != 0 >+ || (parentStyle & SWT.PRIMARY_MODAL) != 0 >+ || (parentStyle & SWT.APPLICATION_MODAL) != 0; >+ } >+ >+ private void setEnable(boolean enable) { > this.enable = enable; > } >- >+ > } > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUIGenerator.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUIGenerator.java,v >retrieving revision 1.9 >diff -u -r1.9 AutoGUIGenerator.java >--- src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUIGenerator.java 19 Apr 2007 12:28:03 -0000 1.9 >+++ src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUIGenerator.java 26 Jul 2008 19:21:54 -0000 >@@ -38,6 +38,7 @@ > * The code generator for auto gui test suites > * > * @author Ali Mehregani >+ * @author Alexander Nyssen > */ > public class AutoGUIGenerator extends JavaGenerator > { >@@ -101,7 +102,7 @@ > * @param argument The argument of the method (see restriction above) > * @throws Exception > */ >- public void createMethod (String methodName, String argument) throws Exception >+ public void createMethod (String methodName, String[] arguments) throws Exception > { > IFile javaFile = getFileHandle(getTestSuite()); > ICompilationUnit cu = JavaCore.createCompilationUnitFrom(javaFile); >@@ -117,8 +118,7 @@ > > > cu.becomeWorkingCopy(null, new NullProgressMonitor()); >- String[] args = {argument}; >- IMethod method = mainClass.getMethod(methodName, args); >+ IMethod method = mainClass.getMethod(methodName, arguments); > > try > { >@@ -128,7 +128,7 @@ > Helper helper = new Helper(); > String packageName = helper.getPackageName(getTestSuite()); > helper.setImportManager(new ImportManager(packageName)); >- method = createTestMethod(mainClass, testCaseName, testCaseDescription, helper, methodName, args); >+ method = createTestMethod(mainClass, testCaseName, testCaseDescription, helper, methodName, arguments); > > helper.emitSortedImports(cu); > >Index: src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUILaunchGenerator.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUILaunchGenerator.java,v >retrieving revision 1.11 >diff -u -r1.11 AutoGUILaunchGenerator.java >--- src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUILaunchGenerator.java 2 May 2007 19:35:57 -0000 1.11 >+++ src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUILaunchGenerator.java 26 Jul 2008 19:21:55 -0000 >@@ -35,10 +35,10 @@ > import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper; > import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; > import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; > > > /** >@@ -108,13 +108,13 @@ > * @param objectMine The object mine > * @param buffer The buffer that will be used to write the object mine to > */ >- private static void serializeObjectMine(IObjectMine objectMine, StringBuffer buffer) >+ private static void serializeObjectMine(MacroObjectDescriptorMine objectMine, StringBuffer buffer) > { > /* Walk through each of the included object mines of the test suite */ > List includes = objectMine.getIncludes(); > for (int i = 0, includeCount = includes.size(); i < includeCount; i++) > { >- serializeObjectMine((IObjectMine)includes.get(i), buffer); >+ serializeObjectMine((MacroObjectDescriptorMine)includes.get(i), buffer); > } > > /* Add the object that have been directly registered with the object mine passed in */ >@@ -124,10 +124,10 @@ > > private static String resolveObjectMine(ITestSuite testSuite) > { >- IObjectMine objectMine = null; >+ MacroObjectDescriptorMine objectMine = null; > try > { >- objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite); >+ objectMine = MacroObjectDescriptorMineManager.getInstance().loadObjectMine(testSuite); > } > catch (Exception e) > { >Index: src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookMethodGenerator.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookMethodGenerator.java,v >retrieving revision 1.18 >diff -u -r1.18 VerificationHookMethodGenerator.java >--- src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookMethodGenerator.java 18 Apr 2008 20:32:50 -0000 1.18 >+++ src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookMethodGenerator.java 26 Jul 2008 19:21:56 -0000 >@@ -1,14 +1,3 @@ >-/********************************************************************** >- * Copyright (c) 2007, 2008 IBM Corporation and others. >- * 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 >- * $Id: VerificationHookMethodGenerator.java,v 1.18 2008/04/18 20:32:50 paules Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- **********************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.codegen; > > import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper; >Index: src/org/eclipse/tptp/test/auto/gui/internal/codegen/TestSuiteToXMLConvertor.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/codegen/TestSuiteToXMLConvertor.java,v >retrieving revision 1.19 >diff -u -r1.19 TestSuiteToXMLConvertor.java >--- src/org/eclipse/tptp/test/auto/gui/internal/codegen/TestSuiteToXMLConvertor.java 18 Apr 2008 20:32:50 -0000 1.19 >+++ src/org/eclipse/tptp/test/auto/gui/internal/codegen/TestSuiteToXMLConvertor.java 26 Jul 2008 19:21:55 -0000 >@@ -1,14 +1,3 @@ >-/********************************************************************** >- * Copyright (c) 2007, 2008 IBM Corporation and others. >- * 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 >- * $Id: TestSuiteToXMLConvertor.java,v 1.19 2008/04/18 20:32:50 paules Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- **********************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.codegen; > > import java.util.HashSet; >Index: src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookClassGenerator.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookClassGenerator.java,v >retrieving revision 1.17 >diff -u -r1.17 VerificationHookClassGenerator.java >--- src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookClassGenerator.java 18 Apr 2008 20:32:50 -0000 1.17 >+++ src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookClassGenerator.java 26 Jul 2008 19:21:56 -0000 >@@ -1,14 +1,3 @@ >-/********************************************************************** >- * Copyright (c) 2007, 2008 IBM Corporation and others. >- * 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 >- * $Id: VerificationHookClassGenerator.java,v 1.17 2008/04/18 20:32:50 paules Exp $ >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- **********************************************************************/ > package org.eclipse.tptp.test.auto.gui.internal.codegen; > > import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >Index: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIObjectMineTreeStructure.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIObjectMineTreeStructure.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIObjectMineTreeStructure.java >--- src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIObjectMineTreeStructure.java 20 Mar 2008 15:48:06 -0000 1.5 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,537 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006, 2008 IBM Corporation and others. >- * 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: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.tptp.test.auto.gui.internal.editor; >- >-import java.util.ArrayList; >-import java.util.Collection; >-import java.util.Iterator; >-import java.util.List; >- >-import org.eclipse.core.runtime.IStatus; >-import org.eclipse.emf.ecore.EStructuralFeature; >-import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >-import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil; >-import org.eclipse.hyades.test.common.util.XMLUtil; >-import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter; >-import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider; >-import org.eclipse.hyades.ui.editor.IEditorExtension; >-import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider; >-import org.eclipse.jface.action.Action; >-import org.eclipse.jface.action.IMenuManager; >-import org.eclipse.jface.dialogs.IDialogConstants; >-import org.eclipse.jface.resource.ImageDescriptor; >-import org.eclipse.jface.viewers.IContentProvider; >-import org.eclipse.jface.viewers.ILabelProvider; >-import org.eclipse.jface.viewers.IStructuredSelection; >-import org.eclipse.jface.viewers.Viewer; >-import org.eclipse.osgi.util.NLS; >-import org.eclipse.swt.SWT; >-import org.eclipse.swt.graphics.Image; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >-import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >-import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >-import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >-import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; >-import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestSuiteDialog; >-import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MessageUIElement; >-import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager; >- >-/** >- * Represents the object mine tree that is displayed in the test >- * case page of the editor. >- * >- * @author Ali Mehregani >- * @author Paul E. Slauenwhite >- * @version March 7, 2008 >- * @since July 10, 2006 >- */ >-public class AutoGUIObjectMineTreeStructure extends AutoGUIAbstractTreeStructure >-{ >- /** Represents the root element in the object mine tree */ >- private static final RootUIObjectMineTreeNode ROOT_ELEMENT = new RootUIObjectMineTreeNode(); >- >- /** The test case form */ >- private AutoGUITestCasesForm testCaseForm; >- >- /** The content provider */ >- private ObjectMineTreeContentProvider contentProvider; >- >- /** The label provider */ >- private ObjectMineLabelProvider labelProvider; >- >- /** The line number and offset relation. The index of the list represents the line >- * number and the value is an object of type Integer[0] indicating the start >- * and end offset */ >- private List lineOffsetRelation; >- >- /** The include object mine menu item */ >- private IncludeObjectMineAction includeObjectMineAction; >- >- /** Change output menu item */ >- private ChangeOutputAction changeOutputAction; >- >- /** Keeps track of the test suite used as input */ >- private ITestSuite testSuiteInput; >- >- /** Stores any error that occurred while loading the object mine */ >- private Object[] error; >- >- public AutoGUIObjectMineTreeStructure(AutoGUITestCasesForm testCaseForm, IEditorExtension editorPart) >- { >- super(editorPart, null); >- this.testCaseForm = testCaseForm; >- lineOffsetRelation = new ArrayList(); >- includeObjectMineAction = new IncludeObjectMineAction(); >- changeOutputAction = new ChangeOutputAction(); >- } >- >- /** >- * Overwrite this method so that a custom content provider can be >- * registered with the tree >- */ >- protected IContentProvider createContentProvider() >- { >- if (contentProvider == null) >- contentProvider = new ObjectMineTreeContentProvider(editorPart, getEStructuralFeature()); >- return contentProvider; >- } >- >- >- /** >- * Overwrite this method so that a custom label provider can be >- * registered with the tree >- * >- * @return The label provider for the object mine tree >- */ >- protected ILabelProvider createLabelProvider() >- { >- if (labelProvider == null) >- labelProvider = new ObjectMineLabelProvider(TestWorkbenchAdapter.class); >- return labelProvider; >- } >- >- >- >- /** >- * Overwrite this method so that custom buttons can be added beside the >- * object mine tree. >- */ >- protected void adjustButtonLabels(String addLabel) >- { >- setButtonLabels (new String[0]); >- } >- >- >- /** >- * Need to overwrite this method since there are no buttons whose status need >- * to be updated. >- */ >- protected void updateActionsAndButtons(IStructuredSelection structuredSelection) >- { >- /* purposely left blank */ >- } >- >- >- /** >- * Refreshes the content of this tree by forcing the test suite to reload its >- * object mine. >- */ >- public void refresh() >- { >- ObjectMineManager.getInstance().clearCache(); >- loadObjectMine(testSuiteInput, false); >- getTreeViewer().refresh(); >- } >- >- >- public List getLineOffsetRelation() >- { >- return lineOffsetRelation; >- } >- >- >- /** >- * Needs to be overwritten to modify the default tree style >- */ >- public int getTreeStryle() >- { >- return super.getTreeStryle() | SWT.BORDER; >- } >- >- >- private Object[] createErrorItem(String prefix, Exception e) >- { >- Throwable cause = AutoGUIUtil.findCause(e); >- prefix += prefix == null ? "": ": "; >- prefix += (cause.getMessage() == cause.getClass().getName() ? "" : " " + cause.getMessage()); >- prefix += ": " + e.getStackTrace()[0].getClassName() + ":" + e.getStackTrace()[0].getLineNumber(); >- return new Object[]{new MessageUIElement(IStatus.ERROR, prefix)}; >- } >- >- >- /** >- * Overwrite this method so that custom menu items can be added to the entries that are >- * displayed in the object mine tree. >- * >- * @param menuManager The menu manager >- */ >- protected void fillContextMenu(IMenuManager menuManager) >- { >- IStructuredSelection selection = getStructuredSelection(); >- if (!selection.isEmpty() && selection.size() == 1 && selection.getFirstElement() instanceof RootUIObjectMineTreeNode) >- { >- menuManager.add(includeObjectMineAction); >- menuManager.add(changeOutputAction); >- } >- } >- >- >- private IObjectMine loadObjectMine(ITestSuite testSuite, boolean showError) >- { >- IObjectMine input = null; >- if (testSuite == null) >- { >- testSuiteInput = null; >- return null; >- } >- >- try >- { >- testSuiteInput =(ITestSuite)testSuite; >- input = ObjectMineManager.getInstance().loadObjectMine(testSuiteInput); >- String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteInput, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE); >- lineOffsetRelation = AutoGUIObjectMineTreeStructure.this.findLineOffsetIndicator(objectMineXML); >- error = null; >- } >- catch (Exception e) >- { >- if (showError) >- { >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE + ": " + testSuite.getName(), >- e); >- } >- else >- { >- error = createErrorItem(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, e); >- } >- >- input = null; >- } >- >- return input; >- } >- >- >- /** >- * The content provider for the object mine tree. >- * >- * @author Ali Mehregani >- */ >- private class ObjectMineTreeContentProvider extends EObjectTreeContentProvider >- { >- public ObjectMineTreeContentProvider(IEditorExtension editorPart, EStructuralFeature eStructuralFeature) >- { >- super(editorPart, eStructuralFeature); >- } >- >- public Object[] getElements(Object inputElement) >- { >- return new Object[]{ROOT_ELEMENT}; >- } >- >- >- /** >- * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) >- */ >- public Object[] getChildren(Object parentElement) >- { >- IObjectMine input = loadObjectMine(testSuiteInput, false); >- if (input == null) >- { >- if (parentElement == ROOT_ELEMENT && error != null) >- return error; >- } >- >- /* If the test suite doesn't have an object mine then return an empty list */ >- String objectMineXML = null; >- if (testSuiteInput == null || (objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteInput, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE)) == null || objectMineXML.length() <= 0) >- return null; >- >- >- if (parentElement == ROOT_ELEMENT) >- { >- return input.getChildren(); >- } >- else if (parentElement instanceof IUIObject) >- { >- return ((IUIObject)parentElement).getChildren(); >- } >- >- return null; >- } >- >- >- public boolean hasChildren(Object parentElement) >- { >- IObjectMine input = loadObjectMine(testSuiteInput, false); >- if (parentElement == ROOT_ELEMENT) >- { >- return input == null ? error != null : input.getChildren().length > 0; >- } >- else if (parentElement instanceof IUIObject) >- { >- return ((IUIObject)parentElement).childCount() > 0; >- } >- >- return false; >- } >- >- /** >- * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) >- */ >- public Object getParent(Object element) >- { >- if (element instanceof IUIObject) >- { >- IUIObject parent = ((IUIObject)element).getParent(); >- return parent == null ? (Object)ROOT_ELEMENT : parent; >- } >- return null; >- } >- >- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) >- { >- if (!(newInput instanceof ITestSuite)) >- return; >- >- loadObjectMine((ITestSuite)newInput, false); >- >- } >- } >- >- >- private class ObjectMineLabelProvider extends WorkbenchAdapterLabelProvider >- { >- >- public ObjectMineLabelProvider(Class cl) throws IllegalArgumentException >- { >- super(cl); >- } >- >- public String getText(Object element) >- { >- if (element == ROOT_ELEMENT) >- { >- return AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_MINE; >- } >- else if (element instanceof IUIObject) >- { >- String descriptiveField = ((IUIObject)element).getDescriptive(); >- return descriptiveField == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_OBJECT : XMLUtil.removeXMLSymbols(descriptiveField); >- } >- else if (element instanceof MessageUIElement) >- { >- String message = ((MessageUIElement)element).getText(); >- return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE : message; >- } >- >- return MacroConstants.EMPTY_STRING; >- } >- >- public Image getImage(Object element) >- { >- if (element == ROOT_ELEMENT) >- { >- return AutoGUIImages.getInstance().getImage(AutoGUIImages.OBJECT_MINE); >- } >- else if (element instanceof IUIObject) >- { >- IUIObject parent = ((IUIObject)element).getParent(); >- return parent == null ? AutoGUIImages.getInstance().getImage(AutoGUIImages.SHELL) : AutoGUIImages.getInstance().getImage(AutoGUIImages.WIDGET); >- } >- else if (element instanceof MessageUIElement) >- { >- return ((MessageUIElement)element).getIcon(); >- } >- >- return null; >- } >- } >- >- >- /** >- * A dummy class that represents the root element in the object mine >- * tree. >- */ >- private static class RootUIObjectMineTreeNode >- { >- } >- >- >- /** >- * The include object mine action. The purpose of this action is to allow >- * the user to include object mines under the test suite's object mine >- * >- * @author Ali Mehregani >- */ >- private class IncludeObjectMineAction extends Action >- { >- /** >- * Perform the action. >- * >- */ >- public void run() >- { >- /* Display the test suite list dialog */ >- AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- testSuiteInput, >- AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, >- false); >- >- if(autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID) >- return; >- >- >- /* Get the selected test suites and include them as part of this test suite's object mine */ >- Collection tests = autoGUITestSuiteDialog.getTests(); >- IObjectMine input = loadObjectMine(testSuiteInput, true); >- boolean markdirty = false; >- for (Iterator testIterator = tests.iterator(); testIterator.hasNext();) >- { >- Object currentTestSuite = testIterator.next(); >- if (!(currentTestSuite instanceof ITestSuite)) >- continue; >- >- ITestSuite testSuite = (ITestSuite)currentTestSuite; >- try >- { >- IObjectMine objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite); >- if (objectMine != null && !input.getIncludes().contains(objectMine)) >- { >- markdirty = true; >- input.addInclude(objectMine); >- } >- } >- catch (Exception e) >- { >- /* Display an error */ >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_DIALOG_TST_INCL, testSuite.getName()), >- e); >- } >- } >- >- if (markdirty) >- { >- testCaseForm.updateTestProperty(null, input.serializeToString(), true); >- getTreeViewer().setSelection(getTreeViewer().getSelection()); >- } >- } >- >- >- public boolean isEnabled() >- { >- return testSuiteInput != null; >- } >- >- public String getText() >- { >- return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_INCL; >- } >- >- public ImageDescriptor getImageDescriptor() >- { >- return AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.INCLUDE); >- } >- } >- >- >- /** >- * This action changes the output of the object mine to another test suite. >- * >- * @author Ali Mehregani >- */ >- private class ChangeOutputAction extends Action >- { >- /** >- * Perform the action. >- */ >- public void run() >- { >- /* Display the test suite list dialog */ >- AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog( >- GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), >- testSuiteInput, >- AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, >- true); >- >- if(autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID) >- return; >- >- >- /* Get the selected test suites and include them as part of this test suite's object mine */ >- Collection tests = autoGUITestSuiteDialog.getTests(); >- if (tests == null) >- return; >- >- Object[] selectedTestContainer = tests.toArray(); >- if (selectedTestContainer.length != 1 || !(selectedTestContainer[0] instanceof ITestSuite)) >- return; >- >- IObjectMine input = loadObjectMine(testSuiteInput, true); >- IObjectMine oldOutputObjectMine = input.getOutputSource(); >- ITestSuite oldOutput = oldOutputObjectMine == null ? null : oldOutputObjectMine.getOwner(); >- ITestSuite newOutput = (ITestSuite)selectedTestContainer[0]; >- if (oldOutput == null || (!oldOutput.getId().equals(newOutput.getId()))) >- { >- IObjectMine objectMine = null; >- try >- { >- objectMine = ObjectMineManager.getInstance().loadObjectMine(newOutput); >- input.setOutputSource(objectMine); >- testCaseForm.updateTestProperty(null, input.serializeToString(), true); >- getTreeViewer().setSelection(getTreeViewer().getSelection()); >- } >- catch (Exception e) >- { >- input.setOutputSource(null); >- AutoGUIUtil.openErrorWithDetail( >- AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >- NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, newOutput.getName()), >- e); >- } >- } >- } >- >- >- public boolean isEnabled() >- { >- return testSuiteInput != null; >- } >- >- public String getText() >- { >- return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_OUPUT; >- } >- >- public ImageDescriptor getImageDescriptor() >- { >- return AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.OUTPUT); >- } >- } >-} >Index: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCasesForm.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCasesForm.java,v >retrieving revision 1.23 >diff -u -r1.23 AutoGUITestCasesForm.java >--- src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCasesForm.java 10 Apr 2008 01:28:58 -0000 1.23 >+++ src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCasesForm.java 26 Jul 2008 19:22:10 -0000 >@@ -95,9 +95,9 @@ > import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIRefreshAction; > import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUITestCaseAction; > import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIUpdateTestCaseAction; >-import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject; > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MacroUIInstruction; >-import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; > import org.eclipse.ui.IActionBars; > import org.eclipse.ui.actions.ActionFactory; > import org.eclipse.ui.forms.IManagedForm; >@@ -177,7 +177,7 @@ > private Text startingPttxt; > > /* The object mine tree */ >- private AutoGUIObjectMineTreeStructure objectMineTree; >+ private AutoGUIMacroObjectDescriptorMineTreeStructure objectMineTree; > > /* The object mine listener */ > private ObjectMineTreeListener objectMineListener; >@@ -213,7 +213,7 @@ > lastTreeHierarchySelected = new LinkedList(); > logicalTreeRepresentaion = new AutoGUITestCaseTreeStructure (editor, Common_TestprofilePackage.eINSTANCE.getTPFTestSuite_TestCases()); > logicalRepresentationListener = new LogicalRepresentationListener(); >- objectMineTree = new AutoGUIObjectMineTreeStructure(this, editor); >+ objectMineTree = new AutoGUIMacroObjectDescriptorMineTreeStructure(this, editor); > linearOperationHistory = new DefaultOperationHistory(); > context = new Hashtable(); > isOperationHistory = true; >@@ -1013,8 +1013,8 @@ > { > Object[] selectedItems = ((StructuredSelection)selectedEntity).toArray(); > Integer[] lineLevelDetail = null; >- if (selectedItems.length == 1 && selectedItems[0] instanceof IUIObject) >- lineLevelDetail = (Integer[])((IUIObject)selectedItems[0]).getData(); >+ if (selectedItems.length == 1 && selectedItems[0] instanceof MacroObjectDescriptor) >+ lineLevelDetail = (Integer[])((MacroObjectDescriptor)selectedItems[0]).getData(); > > /* Select the XML fragment if the line level information is available */ > if (lineLevelDetail != null) >@@ -1036,7 +1036,7 @@ > return; > > /* Update the offest that each tree item keeps track */ >- ObjectMineManager.getInstance().markObjectMineDirty (getTestSuite()); >+ MacroObjectDescriptorMineManager.getInstance().markObjectMineDirty (getTestSuite()); > if (isOperationHistory) > { > objectMineTree.updateOffsetRelation(AutoGUITestCasesForm.this, objectMineTree.getLineOffsetRelation(), event.length, event.replacedText.length()); >@@ -1076,7 +1076,7 @@ > } > } > >- public AutoGUIObjectMineTreeStructure getObjectMineTreeStruct() >+ public AutoGUIMacroObjectDescriptorMineTreeStructure getObjectMineTreeStruct() > { > return objectMineTree; > } >Index: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCaseTreeStructure.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCaseTreeStructure.java,v >retrieving revision 1.3 >diff -u -r1.3 AutoGUITestCaseTreeStructure.java >--- src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCaseTreeStructure.java 5 Mar 2008 18:27:01 -0000 1.3 >+++ src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCaseTreeStructure.java 26 Jul 2008 19:22:07 -0000 >@@ -36,7 +36,7 @@ > import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >-import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; > import org.w3c.dom.Node; > import org.w3c.dom.NodeList; > >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/META-INF/MANIFEST.MF,v >retrieving revision 1.10 >diff -u -r1.10 MANIFEST.MF >--- META-INF/MANIFEST.MF 18 Apr 2008 14:37:27 -0000 1.10 >+++ META-INF/MANIFEST.MF 26 Jul 2008 19:21:48 -0000 >@@ -1,8 +1,8 @@ > Manifest-Version: 1.0 > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName >-Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui; singleton:=true >-Bundle-Version: 4.3.100.qualifier >+Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui;singleton:=true >+Bundle-Version: 4.5.000.qualifier > Bundle-ClassPath: autogui.jar > Bundle-Activator: org.eclipse.tptp.test.auto.gui.internal.GuiPlugin > Bundle-Vendor: %providerName >@@ -11,12 +11,20 @@ > org.eclipse.tptp.test.auto.gui.internal.actions, > org.eclipse.tptp.test.auto.gui.internal.codegen, > org.eclipse.tptp.test.auto.gui.internal.commands, >+ org.eclipse.tptp.test.auto.gui.internal.commands.factory, > org.eclipse.tptp.test.auto.gui.internal.core, > org.eclipse.tptp.test.auto.gui.internal.dialogs, > org.eclipse.tptp.test.auto.gui.internal.editor, > org.eclipse.tptp.test.auto.gui.internal.macro, >- org.eclipse.tptp.test.auto.gui.internal.resolvers, >+ org.eclipse.tptp.test.auto.gui.internal.macroobject, >+ org.eclipse.tptp.test.auto.gui.internal.macroobject.mine, >+ org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver, > org.eclipse.tptp.test.auto.gui.internal.runner, >+ org.eclipse.tptp.test.auto.gui.internal.uiobject, >+ org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver, >+ org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate, >+ org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport, >+ org.eclipse.tptp.test.auto.gui.internal.util, > org.eclipse.tptp.test.auto.gui.internal.wizard > Require-Bundle: org.eclipse.ui;bundle-version="[3.2.0,4.0.0)", > org.junit;bundle-version="[3.2.0,4.0.0)", >@@ -32,7 +40,8 @@ > org.eclipse.hyades.test.tools.core;bundle-version="[4.1.0,5.0.0)", > org.eclipse.ui.forms;bundle-version="[3.2.0,4.0.0)", > org.eclipse.debug.ui;bundle-version="[3.2.0,4.0.0)", >+ org.eclipse.ui.testing;bundle-version="[3.2.0,4.0.0)", > org.eclipse.hyades.trace.ui;bundle-version="[4.1.0,5.0.0)", > org.eclipse.jdt.ui >-Eclipse-LazyStart: true > Bundle-RequiredExecutionEnvironment: J2SE-1.4 >+Bundle-ActivationPolicy: lazy >Index: schema/widgetResolver.exsd >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/schema/widgetResolver.exsd,v >retrieving revision 1.5 >diff -u -r1.5 widgetResolver.exsd >--- schema/widgetResolver.exsd 10 Jul 2006 14:49:07 -0000 1.5 >+++ schema/widgetResolver.exsd 26 Jul 2008 19:21:48 -0000 >@@ -12,6 +12,9 @@ > > <element name="extension"> > <annotation> >+ <appInfo> >+ <meta.element deprecated="true" replacement="uiObjectResolverDelegate" /> >+ </appInfo> > <documentation> > The following internal extension provides the mean for defining custom widget resolvers. > </documentation> >Index: src/org/eclipse/tptp/test/auto/gui/internal/runner/AutoGUIRunner.java >=================================================================== >RCS file: /cvsroot/tptp/test/org.eclipse.tptp.test.auto.gui/src/org/eclipse/tptp/test/auto/gui/internal/runner/AutoGUIRunner.java,v >retrieving revision 1.25 >diff -u -r1.25 AutoGUIRunner.java >--- src/org/eclipse/tptp/test/auto/gui/internal/runner/AutoGUIRunner.java 14 Jul 2008 19:18:57 -0000 1.25 >+++ src/org/eclipse/tptp/test/auto/gui/internal/runner/AutoGUIRunner.java 26 Jul 2008 19:22:17 -0000 >@@ -65,12 +65,12 @@ > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; > import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >-import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler; > import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestCase; > import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestInvocation; > import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestSuite; > import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.GeneralPropertyRetriever; > import org.eclipse.tptp.test.auto.gui.internal.runner.VariableSubstitution.Variable; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; > import org.eclipse.ui.IStartup; > import org.eclipse.ui.IWorkbench; > import org.eclipse.ui.IWorkbenchWindow; >@@ -1232,11 +1232,11 @@ > } > > /** >- * Runs a verificaiton hook >+ * Runs a verification hook > * > * @param verfHook The verification hook > */ >- public void runVerificaitonHook(IHyadesTest verificationHook) >+ public void runVerificationHook(IHyadesTest verificationHook) > { > /* Set the root, if it hasn't already been set */ > if (super.getRoot() == null) >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/UIObjectResolver.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/UIObjectResolver.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/UIObjectResolver.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/UIObjectResolver.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,81 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateRegistry; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader; >+ >+/** >+ * This is a facade that encapsulates resolving/deresolving of UI objects. It >+ * delegates to the respective UIObjectDelegateResolvers that can be plugged in >+ * via the respective extension point >+ * <code>org.eclipse.tptp.auto.gui.uiObjectResolverDelegate</code>. >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public class UIObjectResolver { >+ >+ public static IUIObjectIdentifier resolve(Object context, IUIObject uiObject) >+ throws CoreException { >+ >+ IUIObjectResolverDelegate[] delegateResolvers = UIObjectResolverDelegateRegistry >+ .getDelegateResolvers(); >+ IUIObjectIdentifier identifier = null; >+ for (int i = 0; i < delegateResolvers.length && identifier == null; i++) { >+ identifier = delegateResolvers[i].resolve(context, uiObject); >+ >+ if (identifier != null) { >+ // check if the resolver delegate has set its id into the >+ // returned >+ // identifier >+ if (identifier.getResolverId() == null) { >+ AutoGUIUtil >+ .throwCoreException(NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_RESOLVER_IDENTIFIER_MISSING, >+ delegateResolvers[i])); >+ return null; >+ } >+ } >+ } >+ >+ return identifier; >+ } >+ >+ public static IUIObject deresolve(Object context, >+ IUIObjectIdentifier uiObjectIdentifier) throws CoreException { >+ // we need to obtain the resolver id to be able to delegate to the >+ // respective UIObjectResolverDelegate >+ String resolverId = uiObjectIdentifier.getResolverId(); >+ if (resolverId == null) { >+ // if we do not have a resolver id, use one of the old registered >+ // ones, as they all >+ // have the same deprecated deresolving mechanism >+ return UIObjectResolverDelegateRegistry.getDelegateResolver( >+ NonTrivialUIObjectResolverDelegate.ID).deresolve(context, >+ uiObjectIdentifier); >+ } >+ return UIObjectResolverDelegateRegistry.getDelegateResolver(resolverId) >+ .deresolve(context, uiObjectIdentifier); >+ >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/IPlayable.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/IPlayable.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/IPlayable.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/IPlayable.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,21 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Shell; >+ >+public interface IPlayable { >+ >+ boolean playback(Display display, Shell parent, IProgressMonitor monitor) throws CoreException; >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/ModeConstants.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/ModeConstants.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/ModeConstants.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/ModeConstants.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,28 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+ >+/** >+ * @author Alexander Nyssen >+ */ >+public interface ModeConstants { >+ >+ /* Global states */ >+ public static final byte RECORDING_MODE = 0x00; /* Recording mode */ >+ public static final byte VERIFICATION_MODE = 0x01; /* Verification mode */ >+ public static final byte SUSPEND_MODE = 0x02; /* Suspend mode */ >+ public static final byte QUICK_RUN_MODE = 0x03; /* Quick run mode (when current workbench is used as the context) */ >+ public static final byte EXECUTION_RUN_MODE = 0x04; /* Execution run mode (when proper launch configuration is used) */ >+ public static final byte IDLE_MODE = 0x05; /* Idle mode */ >+ public static final byte POSITION_BASED_REC_MODE = 0x06; /* Position based recording */ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObjectIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObjectIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObjectIdentifier.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObjectIdentifier.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,27 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject; >+ >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+ >+/** >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public interface IMacroObjectIdentifier { >+ >+ public String getContextIdentifier(); >+ >+ public IUIObjectIdentifier getObjectIdentifier(); >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMine.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMine.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMine.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMine.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,616 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine; >+ >+import java.util.ArrayList; >+import java.util.Hashtable; >+import java.util.LinkedList; >+import java.util.List; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; >+import org.w3c.dom.NamedNodeMap; >+import org.w3c.dom.Node; >+ >+/** >+ * >+ * @author Ali Mehregani >+ */ >+public class MacroObjectDescriptorMine { >+ /** The root node of the tree structure that contains the objects */ >+ private MacroObjectDescriptor root; >+ >+ /** Included object mines */ >+ private ArrayList includes; >+ >+ /** The test suite that owns this object mine */ >+ private ITestSuite owner; >+ >+ /** The output object mine */ >+ private MacroObjectDescriptorMine outputObjectMine; >+ >+ /** The active object */ >+ private MacroObjectDescriptor activeObject; >+ >+ /** >+ * Keeps track of the maximum reference id in use. This is used to generate >+ * a unique reference id when requested >+ */ >+ private int maximumRefId; >+ >+ /** The xml handler used to parse the object mine */ >+ private XMLDefaultHandler defaultXMLHandler; >+ >+ public MacroObjectDescriptorMine(ITestSuite testSuite, >+ XMLDefaultHandler defaultXMLHandler) { >+ owner = testSuite; >+ root = new MacroObjectDescriptor(null); >+ includes = new ArrayList(); >+ this.defaultXMLHandler = defaultXMLHandler; >+ } >+ >+ public void addInclude(MacroObjectDescriptorMine objectMine) { >+ includes.add(objectMine); >+ if (outputObjectMine != null) { >+ MacroObjectDescriptorMine foundObjectMine = findIncludedObjectMine(outputObjectMine); >+ outputObjectMine = foundObjectMine == null ? outputObjectMine >+ : foundObjectMine; >+ } >+ } >+ >+ public MacroObjectDescriptor lookupMacroObjectDescriptor( >+ MacroObjectDescriptor parent, String referenceId) { >+ MacroObjectDescriptor uiObject = lookupIncludes(parent, referenceId); >+ if (uiObject != null) >+ return uiObject; >+ >+ uiObject = lookupMacroObjectDescriptor(parent); >+ if (uiObject == null) >+ return null; >+ >+ uiObject = uiObject.findChild(referenceId); >+ return uiObject; >+ } >+ >+ private MacroObjectDescriptor lookupMacroObjectDescriptor( >+ MacroObjectDescriptor object, boolean requiresPresence) >+ throws UIObjectNotFound { >+ if (object == null) { >+ return root; >+ } >+ >+ LinkedList relationship = object.getHierarchicalRelation(); >+ MacroObjectDescriptor currentNode = root; >+ for (int i = 0, height = relationship.size(); currentNode != null >+ && i < height; i++) { >+ currentNode = currentNode >+ .findChild(((MacroObjectDescriptor) relationship.get(i)) >+ .getReferenceId()); >+ } >+ >+ if (currentNode == null && requiresPresence) >+ throw new UIObjectNotFound(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, object >+ .getReferenceId())); >+ >+ return currentNode; >+ } >+ >+ public MacroObjectDescriptor lookupMacroObjectDescriptor( >+ MacroObjectDescriptor parent, String contextId, String widgetId, >+ String objectId) { >+ MacroObjectDescriptor uiObject = lookupIncludes(parent, contextId, >+ widgetId, objectId); >+ if (uiObject != null) >+ return uiObject; >+ >+ MacroObjectDescriptor parentNode = lookupMacroObjectDescriptor(parent); >+ if (parentNode == null) >+ return null; >+ >+ MacroObjectDescriptor[] children = parentNode.getChildren(); >+ for (int i = 0; i < children.length; i++) { >+ if (((contextId == null && children[i].getContextId() == null) || (contextId != null && contextId >+ .equals(children[i].getContextId()))) >+ && widgetId.equals(children[i].getWidgetId()) >+ && ((objectId == null && children[i].getObjectId() == null) || (objectId != null && objectId >+ .equals(children[i].getObjectId())))) { >+ return children[i]; >+ } >+ >+ } >+ return null; >+ } >+ >+ public MacroObjectDescriptor[] getChildren() { >+ return root.getChildren(); >+ } >+ >+ private MacroObjectDescriptor lookupMacroObjectDescriptor( >+ MacroObjectDescriptor parent) { >+ try { >+ return lookupMacroObjectDescriptor(parent, false); >+ } catch (UIObjectNotFound e) { >+ return null; >+ } >+ } >+ >+ /** >+ * Looks up the included object mine to determine if they have a >+ * corresponding object with the reference id passed in. >+ * >+ * @param parent >+ * The parent of the object >+ * @param referenceId >+ * The reference id of the object >+ * >+ * @return The object with the reference id passed in; null if none is >+ * found. >+ * @throws UIObjectNotFound >+ * In case the parent can't be found. >+ */ >+ private MacroObjectDescriptor lookupIncludes(MacroObjectDescriptor parent, >+ String referenceId) { >+ MacroObjectDescriptor[] uiObject = lookupIncludes(parent, referenceId, >+ null, null, null); >+ return uiObject != null && uiObject.length > 0 ? uiObject[0] : null; >+ } >+ >+ /** >+ * Looks up the included object mine to determine if they have a >+ * corresponding object with the contextId id and object id passed in. >+ * >+ * @param parent >+ * The parent of the object >+ * @param contextId >+ * The context id of the object >+ * @param widgetId >+ * The id of the object >+ * >+ * @return The object with the matching context and object id passed in; >+ * null if none is found. >+ * @throws UIObjectNotFound >+ * In case the parent can't be found. >+ */ >+ private MacroObjectDescriptor lookupIncludes(MacroObjectDescriptor parent, >+ String contextId, String widgetId, String objectId) { >+ MacroObjectDescriptor[] uiObject = lookupIncludes(parent, null, >+ contextId, widgetId, objectId); >+ return uiObject != null && uiObject.length > 0 ? uiObject[0] : null; >+ } >+ >+ /** >+ * Looks up the included object mines to find an object that has been >+ * requested. If reference id happens to be null, then context/object id are >+ * used. >+ * >+ * @param parent >+ * The parent of the object >+ * @param referenceId >+ * The reference id of the object. >+ * @param contextId >+ * The context id of the object >+ * @param widgetId >+ * The id of the object >+ * >+ * @return The objects to look for >+ */ >+ private MacroObjectDescriptor[] lookupIncludes( >+ MacroObjectDescriptor parent, String referenceId, String contextId, >+ String widgetId, String objectId) { >+ boolean useReferenceId = referenceId != null; >+ boolean useObjectId = widgetId != null; >+ >+ MacroObjectDescriptor objectRequested = null; >+ MacroObjectDescriptor[] children = null; >+ for (int i = 0, includeCount = includes.size(); i < includeCount; i++) { >+ MacroObjectDescriptorMine objectMine = (MacroObjectDescriptorMine) includes >+ .get(i); >+ if (useReferenceId) { >+ objectRequested = objectMine.lookupMacroObjectDescriptor( >+ parent, referenceId); >+ } else if (useObjectId) { >+ objectRequested = objectMine.lookupMacroObjectDescriptor( >+ parent, contextId, widgetId, objectId); >+ } >+ >+ children = objectRequested == null ? children >+ : new MacroObjectDescriptor[] { objectRequested }; >+ if (children != null) { >+ return children; >+ } >+ } >+ >+ return null; >+ } >+ >+ public MacroObjectDescriptor getRoot() { >+ return root; >+ } >+ >+ public MacroObjectDescriptor registerObject(MacroObjectDescriptor parent, >+ Node objectNode) throws IDCollisionException, UIObjectNotFound, >+ CoreException { >+ NamedNodeMap attributes = objectNode.getAttributes(); >+ MacroObjectDescriptor macroObjectDescriptor = new MacroObjectDescriptor( >+ parent); >+ >+ MacroObjectDescriptor node = lookupMacroObjectDescriptor(parent, true); >+ >+ /* Set the attributes of the object */ >+ String referenceIdStr = getAttribute(attributes, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ updateMaxReferenceId(referenceIdStr); >+ >+ Hashtable lineLevelDetail = null; >+ if (defaultXMLHandler != null) >+ lineLevelDetail = defaultXMLHandler.getLineTable(); >+ macroObjectDescriptor.setReferenceId(referenceIdStr); >+ macroObjectDescriptor.setContextId(getAttribute(attributes, >+ MacroConstants.CONTEXT_ID_ATTRIBUTE)); >+ // for backwards compatibility, also search for an ID attribute (old >+ // format). Otherwise read the widget and object id >+ if (getAttribute(attributes, MacroConstants.ID_ATTRIBUTE) != null) { >+ macroObjectDescriptor.setWidgetId(getAttribute(attributes, >+ MacroConstants.ID_ATTRIBUTE)); >+ } else { >+ macroObjectDescriptor.setWidgetId(getAttribute(attributes, >+ MacroConstants.WIDGET_ID_ATTRIBUTE)); >+ macroObjectDescriptor.setObjectId(getAttribute(attributes, >+ MacroConstants.OBJECT_ID_ATTRIBUTE)); >+ } >+ macroObjectDescriptor.setDescriptive(getAttribute(attributes, >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE)); >+ macroObjectDescriptor.setResolver(getAttribute(attributes, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE)); >+ if (lineLevelDetail != null) >+ macroObjectDescriptor.setData(((Integer[]) lineLevelDetail >+ .get(objectNode))); >+ node.addChild(macroObjectDescriptor); >+ >+ return macroObjectDescriptor; >+ } >+ >+ public MacroObjectDescriptor registerObject(MacroObjectDescriptor uiObject) >+ throws IDCollisionException, UIObjectNotFound, CoreException { >+ // assign a new unique id to the MacroObjectDescriptor >+ String uniqueId = getUniqueReferenceId(); >+ updateMaxReferenceId(uniqueId); >+ uiObject.setReferenceId(uniqueId); >+ >+ MacroObjectDescriptor parentObject = uiObject.getParent(); >+ >+ /* >+ * If the object that is about to be registered happens to be at the >+ * first level (i.e. it is an infant), then it needs to be registered >+ * with the output destination of this object mine >+ */ >+ if (parentObject == null && outputObjectMine != null) { >+ outputObjectMine.registerObject(uiObject); >+ includes.contains(outputObjectMine); >+ return uiObject; >+ } >+ >+ if (parentObject == null) { >+ root.addChild(uiObject); >+ } else { >+ parentObject.addChild(uiObject); >+ } >+ >+ return uiObject; >+ } >+ >+ private void updateMaxReferenceId(String referenceIdStr) { >+ try { >+ int referenceId = Integer.parseInt(referenceIdStr); >+ int maximumIncludedRefId = findMaximumIncludedRefId(); >+ maximumRefId = Math.max( >+ Math.max(referenceId, maximumIncludedRefId), maximumRefId); >+ >+ if (referenceId == maximumRefId) >+ maximumRefId++; >+ } catch (NumberFormatException nfe) { >+ /* Doesn't need to be handled */ >+ } >+ } >+ >+ /** >+ * Walks through the included object mines of this object mine to determine >+ * the unique reference id. >+ * >+ * @return A unique reference id that is global to all included object >+ * mines. >+ */ >+ private int findMaximumIncludedRefId() { >+ int uniqueRefId = 0; >+ >+ for (int i = 0, includeCount = includes.size(); i < includeCount; i++) { >+ MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes >+ .get(i); >+ try { >+ uniqueRefId = Math.max(Integer.parseInt(currentObjectMine >+ .getUniqueReferenceId()), uniqueRefId); >+ } catch (NumberFormatException nfe) { >+ /* Ignore the exception */ >+ } >+ } >+ return uniqueRefId; >+ } >+ >+ private String getAttribute(NamedNodeMap attributes, String attributeName) { >+ Node attr = attributes.getNamedItem(attributeName); >+ return attr == null ? null : attr.getNodeValue(); >+ } >+ >+ public void setOutputSource(MacroObjectDescriptorMine objectMine) { >+ outputObjectMine = objectMine == null ? null >+ : findIncludedObjectMine(objectMine); >+ if (outputObjectMine == null) >+ outputObjectMine = objectMine; >+ } >+ >+ public MacroObjectDescriptorMine getOutputSource() { >+ return outputObjectMine; >+ } >+ >+ private MacroObjectDescriptorMine findIncludedObjectMine( >+ MacroObjectDescriptorMine objectMine) { >+ for (int i = 0, includeCount = includes.size(); i < includeCount; i++) { >+ MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes >+ .get(i); >+ if (currentObjectMine.equals(objectMine)) >+ return currentObjectMine; >+ } >+ >+ return null; >+ } >+ >+ public ITestSuite getOwner() { >+ return owner; >+ } >+ >+ public static class UIObjectNotFound extends Exception { >+ static final long serialVersionUID = 4699726279267599112L; >+ >+ public UIObjectNotFound(String message) { >+ super(message); >+ } >+ } >+ >+ public static class IDCollisionException extends Exception { >+ static final long serialVersionUID = -6526030843455792891L; >+ >+ public IDCollisionException(String message) { >+ super(message); >+ } >+ } >+ >+ public String serializeToString() { >+ StringBuffer objectMineSerialized = new StringBuffer(); >+ int indent = 0; >+ >+ /* <object-mine> */ >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.OBJECT_MINE_ELEMENT, false, true); >+ >+ serializeHeader(objectMineSerialized, indent + 1, true); >+ serializeObjects(objectMineSerialized, indent + 1, true); >+ >+ /* </object-mine> */ >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.OBJECT_MINE_ELEMENT, true, true); >+ >+ return objectMineSerialized.toString(); >+ } >+ >+ private void serializeHeader(StringBuffer objectMineSerialized, int indent, >+ boolean includeHeader) { >+ /* Don't write anything if the header is empty */ >+ if (outputObjectMine == null >+ && (includes == null || includes.size() <= 0)) >+ return; >+ >+ boolean outputElement = outputObjectMine != null; >+ >+ /* <header output="..."/> */ >+ if (includeHeader) { >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.HEADER_ELEMENT, false, !outputElement); >+ if (outputElement) >+ MacroUtil.addAttribute(objectMineSerialized, >+ new String[] { MacroConstants.OUTPUT_ATTRIBUTE }, >+ new String[] { AutoGUIUtil >+ .resolveTestSuitePath(outputObjectMine >+ .getOwner()) }, false, true); >+ } >+ >+ /* Add the <include .../> elements */ >+ for (int i = 0, includeCount = includes.size(); i < includeCount; i++) { >+ MacroObjectDescriptorMine currentInclude = (MacroObjectDescriptorMine) includes >+ .get(i); >+ ITestSuite testSuite = currentInclude.getOwner(); >+ String path = AutoGUIUtil.resolveTestSuitePath(testSuite); >+ >+ if (path != null) { >+ MacroUtil.addElement(objectMineSerialized, indent + 1, >+ MacroConstants.INCLUDE_ELEMENT, false, false); >+ MacroUtil.addAttribute(objectMineSerialized, >+ new String[] { MacroConstants.PATH_ATTRIBUTE }, >+ new String[] { path }, true, true); >+ } >+ } >+ >+ if (includeHeader) { >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.HEADER_ELEMENT, true, true); >+ } >+ } >+ >+ private void serializeObjects(StringBuffer objectMineSerialized, >+ int indent, boolean includeHeader) { >+ MacroObjectDescriptor[] rootChildren = root.getChildren(); >+ if (rootChildren == null || rootChildren.length <= 0) >+ return; >+ >+ /* Add the objects */ >+ if (includeHeader) { >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.OBJECTS_ELEMENT, false, true); >+ addObject(objectMineSerialized, indent + 1, rootChildren); >+ MacroUtil.addElement(objectMineSerialized, indent, >+ MacroConstants.OBJECTS_ELEMENT, true, true); >+ return; >+ } >+ >+ addObject(objectMineSerialized, indent + 1, rootChildren); >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptorMine#serializeHeaderToString() >+ */ >+ public String serializeHeaderToString() { >+ StringBuffer sb = new StringBuffer(); >+ serializeHeader(sb, 0, false); >+ return sb.toString(); >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptorMine#serializeObjetsToString() >+ */ >+ public String serializeObjetsToString() { >+ StringBuffer sb = new StringBuffer(); >+ serializeObjects(sb, 0, false); >+ return sb.toString(); >+ } >+ >+ private void addObject(StringBuffer objectMapSerialized, int indent, >+ MacroObjectDescriptor[] rootChildren) { >+ if (rootChildren == null) >+ return; >+ >+ for (int i = 0; i < rootChildren.length; i++) { >+ MacroObjectDescriptor currentMacroObjectDescriptor = rootChildren[i]; >+ MacroObjectDescriptor[] children = rootChildren[i].getChildren(); >+ >+ /* If the object is a shell without any children, then skip it */ >+ if (currentMacroObjectDescriptor.getParent() == null >+ && (children == null || children.length <= 0)) >+ continue; >+ >+ boolean hasChildren = children != null && children.length > 0; >+ MacroUtil.addElement(objectMapSerialized, indent, >+ MacroConstants.OBJECT_ELEMENT, false, false); >+ MacroUtil.addAttribute(objectMapSerialized, new String[] { >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE, >+ MacroConstants.CONTEXT_ID_ATTRIBUTE, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE, >+ MacroConstants.WIDGET_ID_ATTRIBUTE, >+ MacroConstants.OBJECT_ID_ATTRIBUTE }, new String[] { >+ currentMacroObjectDescriptor.getDescriptive(), >+ currentMacroObjectDescriptor.getReferenceId(), >+ currentMacroObjectDescriptor.getContextId(), >+ currentMacroObjectDescriptor.getResolverId(), >+ currentMacroObjectDescriptor.getWidgetId(), >+ currentMacroObjectDescriptor.getObjectId() }, !hasChildren, >+ true); >+ if (hasChildren) { >+ addObject(objectMapSerialized, indent + 1, rootChildren[i] >+ .getChildren()); >+ MacroUtil.addElement(objectMapSerialized, indent, >+ MacroConstants.OBJECT_ELEMENT, true, true); >+ } >+ } >+ >+ } >+ >+ public MacroObjectDescriptor getActiveObject() { >+ return activeObject; >+ } >+ >+ public void setActiveObject(MacroObjectDescriptor activeObject) { >+ this.activeObject = activeObject; >+ } >+ >+ private String getUniqueReferenceId() { >+ int maximumIncludedRefId = findMaximumIncludedRefId(); >+ maximumRefId = Math.max(maximumIncludedRefId, maximumRefId); >+ >+ /* Restart the reference id */ >+ if (maximumRefId >= Integer.MAX_VALUE - 10) { >+ maximumRefId = 0; >+ } >+ return String.valueOf(maximumRefId); >+ } >+ >+ public List getIncludes() { >+ return includes; >+ } >+ >+ public boolean equals(Object o) { >+ return o instanceof MacroObjectDescriptorMine ? getOwner().getId() >+ .equals(((MacroObjectDescriptorMine) o).getOwner().getId()) >+ : false; >+ } >+ >+ public void setOwner(ITestSuite testSuite) { >+ this.owner = testSuite; >+ } >+ >+ /** >+ * If the node passed in has a reference id, then this method looks up the >+ * id in the object mine and attempts to find the object that is referenced. >+ * >+ * @param node >+ * Represents the XML node >+ * @param lineTable >+ * Contains line level information >+ * >+ * @return A String[] of length 2, where String[0] = context id and >+ * String[1] = object id. If the node does not have a reference id, >+ * then null is returned. >+ * >+ * @throws CoreException >+ * If the node contains a reference id attribute but the >+ * corresponding object mine does not have any such object. >+ */ >+ public MacroObjectDescriptor lookupReferenceId( >+ MacroObjectDescriptor parent, Node node, Hashtable lineTable) >+ throws CoreException { >+ String referenceId = MacroUtil.getAttribute(node, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ if (referenceId == null) >+ return null; >+ >+ MacroObjectDescriptor correspondingObject = lookupMacroObjectDescriptor( >+ parent, referenceId); >+ if (correspondingObject == null) { >+ Integer[] lineLevelDetail = (Integer[]) lineTable.get(node); >+ AutoGUIUtil >+ .throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, >+ referenceId), lineLevelDetail == null ? 0 >+ : lineLevelDetail[0].intValue()); >+ } else { >+ return correspondingObject; >+ } >+ >+ /* Code not reached beyond this point */ >+ return null; >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateLoader.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateLoader.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateLoader.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateLoader.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+/** >+ * Represents each widgetResolver element that appears under a widgetResolver >+ * extension >+ * >+ * @author Ali Mehregani >+ * @author Alexander Nyssen >+ */ >+public class UIObjectResolverDelegateLoader { >+ >+ /** The id of the widget resolver */ >+ private String id; >+ >+ /** The widget resolver class */ >+ private IUIObjectResolverDelegate uiObjectResolverDelegate; >+ >+ /** The priority of this widget resolver registeration */ >+ private int priority; >+ >+ /** >+ * Limit the visibility of the constructor >+ */ >+ protected UIObjectResolverDelegateLoader(String id, >+ IUIObjectResolverDelegate resolver, int priority) { >+ this.id = id; >+ this.uiObjectResolverDelegate = resolver; >+ this.priority = priority; >+ } >+ >+ /** >+ * @return the id >+ */ >+ public String getId() { >+ return id; >+ } >+ >+ /** >+ * @return the priority >+ */ >+ public int getPriority() { >+ return priority; >+ } >+ >+ /** >+ * @return the widgetResolver >+ */ >+ public IUIObjectResolverDelegate getUIObjectResolverDelegate() { >+ return uiObjectResolverDelegate; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/PrimitiveUIObjectIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/PrimitiveUIObjectIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/PrimitiveUIObjectIdentifier.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/PrimitiveUIObjectIdentifier.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,78 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject; >+ >+/** >+ * A primitive string UI object identifier. The string object must be an exact >+ * match for the two given ids to equal. Contributors can extend this class or >+ * provide a direct implementation of {@link IUIObjectIdentifier} >+ * >+ * @author Ali Mehregani >+ * @author Alexander Nyssen >+ */ >+public class PrimitiveUIObjectIdentifier implements IUIObjectIdentifier { >+ >+ /** The resolver objectId */ >+ private String resolverId; >+ >+ private String widgetId; >+ >+ /** The string objectId of the object */ >+ private String objectId; >+ >+ public PrimitiveUIObjectIdentifier(String widgetId) { >+ this.widgetId = widgetId; >+ } >+ >+ public PrimitiveUIObjectIdentifier(String widgetId, String resolverId) { >+ this.widgetId = widgetId; >+ this.resolverId = resolverId; >+ } >+ >+ public PrimitiveUIObjectIdentifier(String widgetId, String objectId, String resolverId) { >+ this.widgetId = widgetId; >+ this.objectId = objectId; >+ this.resolverId = resolverId; >+ } >+ >+ public String getResolverId() { >+ return resolverId; >+ } >+ >+ public void setResolverId(String resolverId) { >+ this.resolverId = resolverId; >+ } >+ >+ public String getWidgetId() { >+ return widgetId; >+ } >+ >+ public String getObjectId(){ >+ return objectId; >+ } >+ >+ public boolean equals(Object obj) { >+ if (!(obj instanceof PrimitiveUIObjectIdentifier)) { >+ return false; >+ } else { >+ PrimitiveUIObjectIdentifier other = (PrimitiveUIObjectIdentifier) obj; >+ boolean equals = (widgetId == null) ? other.widgetId == null >+ : widgetId.equals(other.widgetId); >+ return equals; >+ } >+ } >+ >+ public String toString() { >+ return widgetId; >+ } >+ >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObject.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObject.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,25 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject; >+ >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+ >+/** >+ * @author Alexander Nyssen >+ */ >+public interface IMacroObject { >+ >+ public abstract Object getContext(); >+ >+ public abstract IUIObject getUIObject(); >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateRegistry.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateRegistry.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateRegistry.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateRegistry.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,203 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+import java.util.Hashtable; >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IConfigurationElement; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader; >+import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter; >+ >+/** >+ * This class delivers utility methods to load UIObjectResolverDelegates via the >+ * uiObjectResolverDelegate extension point. It also loads all extensions to the >+ * deprecated widgetResolver extension point and adapts them to the new >+ * interface. >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public class UIObjectResolverDelegateRegistry { >+ >+ private static final String EXTENSION_POINT_NAME = "uiObjectResolverDelegate"; >+ private static final String EXTENSION_POINT_ID = "org.eclipse.tptp.test.auto.gui." >+ + EXTENSION_POINT_NAME; >+ >+ /* Keeps an ordered list of the primitive resolver ids */ >+ private static String[] resolverIds; >+ >+ /* >+ * The widget resolver: KEY = resolver id VALUE = A class of type >+ * UIObjectResolverDelegateLoader >+ */ >+ private static Hashtable uiObjectDelegateResolverLoaders = new Hashtable(); >+ >+ /** >+ * Load the registered widget resolvers. The widget resolvers are ordered in >+ * the descending order of their priority >+ */ >+ private static void loadDelegateResolvers() { >+ IConfigurationElement[] elements = Platform.getExtensionRegistry() >+ .getConfigurationElementsFor(EXTENSION_POINT_ID); >+ Vector tempContainer = new Vector(elements.length); >+ >+ for (int i = 0; i < elements.length; i++) { >+ UIObjectResolverDelegateLoader uiObjectResolverDelegateLoader = constructUIObjectResolverLoaderInstance(elements[i]); >+ if (uiObjectResolverDelegateLoader != null) { >+ tempContainer.add(findIndex(uiObjectResolverDelegateLoader >+ .getPriority(), tempContainer), >+ uiObjectResolverDelegateLoader); >+ uiObjectDelegateResolverLoaders.put( >+ uiObjectResolverDelegateLoader.getId(), >+ uiObjectResolverDelegateLoader); >+ } >+ } >+ >+ // Also add the implementors of the old widgetResolver extension point. >+ // They are adapted to the new extension point using respective adapters >+ WidgetResolverLoader[] widgetResolverLoaders = WidgetResolverLoader >+ .getWidgetResolverLoaders(); >+ for (int i = 0; i < widgetResolverLoaders.length; i++) { >+ UIObjectResolverDelegateLoader uiObjectResolverDelegateLoader = new WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter( >+ widgetResolverLoaders[i]); >+ tempContainer.add(findIndex(widgetResolverLoaders[i].getPriority(), >+ tempContainer), uiObjectResolverDelegateLoader); >+ >+ uiObjectDelegateResolverLoaders.put(uiObjectResolverDelegateLoader >+ .getId(), uiObjectResolverDelegateLoader); >+ } >+ >+ resolverIds = new String[tempContainer.size()]; >+ for (int i = 0; i < resolverIds.length; i++) { >+ resolverIds[i] = ((UIObjectResolverDelegateLoader) tempContainer >+ .get(i)).getId(); >+ } >+ } >+ >+ private static int findIndex(int desiredPriority, Vector container, >+ int startIntervalInx, int endIntervalInx, int length) { >+ if (startIntervalInx == endIntervalInx >+ || startIntervalInx == endIntervalInx - 1) { >+ if (length > 0) { >+ UIObjectResolverDelegateLoader widgetResolverReg = (UIObjectResolverDelegateLoader) container >+ .get(startIntervalInx); >+ int priority = widgetResolverReg.getPriority(); >+ if (desiredPriority < priority) >+ return startIntervalInx; >+ } >+ return endIntervalInx; >+ } >+ >+ /* What's in the middle? */ >+ int middleInx = startIntervalInx >+ + (int) Math.ceil((endIntervalInx - startIntervalInx) / 2); >+ UIObjectResolverDelegateLoader widgetResolverReg = (UIObjectResolverDelegateLoader) container >+ .get(middleInx); >+ int middleElementPriority = widgetResolverReg.getPriority(); >+ >+ if (middleElementPriority > desiredPriority) >+ endIntervalInx = middleInx; >+ else if (middleElementPriority < desiredPriority) >+ startIntervalInx = middleInx; >+ else >+ return middleInx; >+ return findIndex(desiredPriority, container, startIntervalInx, >+ endIntervalInx, length); >+ } >+ >+ private static int findIndex(int priority, Vector container) { >+ int length = container.size(); >+ return findIndex(priority, container, 0, length, length); >+ } >+ >+ /** >+ * This method should not be called by clients. It is only used from >+ * UIObjectDeprecatedDeresolvingSupport >+ * >+ * @return >+ */ >+ public static Hashtable getDelegateResolverLoaders() { >+ if (resolverIds == null) { >+ UIObjectResolverDelegateRegistry.loadDelegateResolvers(); >+ } >+ return uiObjectDelegateResolverLoaders; >+ } >+ >+ /** >+ * Returns the list of resolver delegates, sorted by priority >+ * >+ * @return >+ */ >+ public static IUIObjectResolverDelegate[] getDelegateResolvers() { >+ if (resolverIds == null) { >+ UIObjectResolverDelegateRegistry.loadDelegateResolvers(); >+ } >+ >+ IUIObjectResolverDelegate[] resolvers = new IUIObjectResolverDelegate[resolverIds.length]; >+ for (int i = 0; i < resolverIds.length; i++) { >+ resolvers[i] = ((UIObjectResolverDelegateLoader) uiObjectDelegateResolverLoaders >+ .get(resolverIds[i])).getUIObjectResolverDelegate(); >+ } >+ return resolvers; >+ } >+ >+ public static final IUIObjectResolverDelegate getDelegateResolver( >+ String resolverId) { >+ if (resolverIds == null) { >+ UIObjectResolverDelegateRegistry.loadDelegateResolvers(); >+ } >+ >+ UIObjectResolverDelegateLoader widgetResolverLoader = (UIObjectResolverDelegateLoader) uiObjectDelegateResolverLoaders >+ .get(resolverId); >+ return widgetResolverLoader.getUIObjectResolverDelegate(); >+ } >+ >+ /** >+ * Constructs an instance of this class based on the configuration element >+ * passed in >+ * >+ * @param confiugrationElement >+ * The configuration element to be loaded >+ * @return An instance of this class based on the configuration element >+ * passed in. null will be returned if there is an error loading the >+ * configuration element. >+ */ >+ private static UIObjectResolverDelegateLoader constructUIObjectResolverLoaderInstance( >+ IConfigurationElement configurationElement) { >+ String name = configurationElement.getName(); >+ if (!EXTENSION_POINT_NAME.equals(configurationElement.getName())) >+ return null; >+ >+ try { >+ String id = configurationElement.getAttribute("id"); >+ IUIObjectResolverDelegate uiObjectResolverDelegate = (IUIObjectResolverDelegate) configurationElement >+ .createExecutableExtension("class"); >+ int priority = Integer.parseInt(configurationElement >+ .getAttribute("priority")); >+ >+ if (id == null || uiObjectResolverDelegate == null) >+ return null; >+ >+ return new UIObjectResolverDelegateLoader(id, >+ uiObjectResolverDelegate, priority); >+ >+ } catch (CoreException e) { >+ e.printStackTrace(); >+ } >+ >+ return null; >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/ObjectBasedCommand.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/ObjectBasedCommand.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/ObjectBasedCommand.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/ObjectBasedCommand.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,321 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.commands; >+ >+import java.util.Hashtable; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.w3c.dom.Node; >+ >+/** >+ * @author Alexander Nyssen >+ * >+ */ >+public abstract class ObjectBasedCommand extends AbstractMacroCommand { >+ >+ /** The macro object of interest to the command */ >+ protected IMacroObject macroObject; >+ >+ /** The macro object id associated with this command */ >+ protected IMacroObjectIdentifier macroObjectIdentifier; >+ >+ /** The corresponding macro object for this object-based macro command */ >+ protected MacroObjectDescriptor macroObjectDescriptor; >+ >+ // used to detect wether a descriptive field has to be detected >+ boolean needsDescriptiveField = false; >+ >+ /** >+ * @param parent >+ * @param widgetId >+ */ >+ public ObjectBasedCommand(MacroCommandShell parent) { >+ super(parent); >+ } >+ >+ protected void preProcessEvent(Event event) throws CoreException { >+ macroObject = locateMacroObject(event); >+ >+ // retrieve the macro object identifier >+ IMacroObjectIdentifier identifier = MacroObjectResolver.resolve( >+ getParent().getShell(), macroObject); >+ if (identifier == null) { >+ AutoGUIUtil >+ .throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE, macroObject.getUIObject().getWidget())); >+ } >+ setMacroObjectIdentifier(identifier); >+ >+ // register with object mine if in use and not already done >+ MacroObjectDescriptor uiObject = null; >+ if (useObjectMine()) { >+ /* >+ * Lookup the widget of this command. If it already exists in our >+ * object mine, then have it referenced by setting the reference id >+ * of the command. >+ */ >+ MacroObjectDescriptorMine objectMine = MacroManager.getInstance() >+ .getObjectMine(); >+ >+ try { >+ MacroObjectDescriptor activeObject = objectMine >+ .getActiveObject(); >+ uiObject = objectMine.lookupMacroObjectDescriptor(activeObject, >+ identifier.getContextIdentifier() == null ? null >+ : identifier.getContextIdentifier(), identifier >+ .getObjectIdentifier().getWidgetId(), identifier.getObjectIdentifier().getObjectId()); >+ >+ /* >+ * The object is not registered with the object mine - register >+ * it >+ */ >+ if (uiObject == null) { >+ needsDescriptiveField = true; >+ uiObject = MacroObjectDescriptor.createInstance(this, >+ activeObject); >+ objectMine.registerObject((MacroObjectDescriptor) uiObject); >+ } >+ setCorrespondingMacroObjectDescriptor(uiObject); >+ } >+ >+ /* >+ * We can't afford to show an error message in case of an unexpected >+ * error during registeration. We'll ignore the error and not make >+ * use of the object mine. >+ */ >+ catch (UIObjectNotFound e) { >+ /* Should not happen */ >+ } catch (IDCollisionException e) { >+ /* Should not happen */ >+ } catch (CoreException e) { >+ /* Should not happen */ >+ e.printStackTrace(); >+ } >+ } >+ } >+ >+ protected void doProcessEvent(Event event) throws CoreException { >+ // nothing to do by default >+ } >+ >+ protected final void postProcessEvent(Event event) throws CoreException { >+ // initialize the descriptive field of the associated macro object >+ // descriptor >+ if (useObjectMine() && needsDescriptiveField >+ && getCorrespondingMacroObjectDescriptor() != null) { >+ // may safely cast into MacroObjectDescriptor here, as >+ // needsDescriptiveField is only true if we have created a new one. >+ ((MacroObjectDescriptor) getCorrespondingMacroObjectDescriptor()) >+ .setDescriptive(getObjectClassName(event.widget) >+ + (getDescriptiveField() == null ? MacroConstants.EMPTY_STRING >+ : ": " + getDescriptiveField())); >+ } >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand#processEvent(org.eclipse.swt.widgets.Event) >+ */ >+ public final void processEvent(Event event) throws CoreException { >+ preProcessEvent(event); >+ >+ // let the original implementation do its job (detect the descriptive >+ // field, for example) >+ doProcessEvent(event); >+ >+ postProcessEvent(event); >+ } >+ >+ /** >+ * This can be changed by subclasses, if for example a String entry of a >+ * combo box has to be checked... >+ * >+ * @param event >+ * @return >+ */ >+ protected IMacroObject locateMacroObject(Event event) { >+ return new MacroObject(new UIObject(event.widget)); >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getCorrespondingMacroObjectDescriptor() >+ */ >+ public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() { >+ return macroObjectDescriptor; >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#setCorrespondingMacroObjectDescriptor(org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptor) >+ */ >+ protected void setCorrespondingMacroObjectDescriptor( >+ MacroObjectDescriptor uiObject) { >+ this.macroObjectDescriptor = uiObject; >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getMacroObjectIdentifier() >+ */ >+ public IMacroObjectIdentifier getMacroObjectIdentifier() { >+ return macroObjectIdentifier; >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#setMacroObjectIdentifier(IMacroObjectIdentifier) >+ */ >+ protected void setMacroObjectIdentifier( >+ IMacroObjectIdentifier objectIdentifier) { >+ this.macroObjectIdentifier = objectIdentifier; >+ } >+ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, lineTable); >+ >+ loadMacroObjectIdentifier(node, lineTable); >+ } >+ >+ protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable) >+ throws CoreException { >+ MacroObjectDescriptor commandObject = null; >+ if (MacroManager.getInstance().getObjectMine() != null) { >+ commandObject = MacroManager.getInstance().getObjectMine().lookupReferenceId( >+ getParent().getCorrespondingMacroObjectDescriptor(), node, >+ lineTable); >+ } >+ boolean isObjectFound = commandObject != null; >+ if (isObjectFound) { >+ setCorrespondingMacroObjectDescriptor(commandObject); >+ } >+ >+ String cid = isObjectFound ? commandObject.getContextId() : MacroUtil >+ .getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ String wid = isObjectFound ? commandObject.getWidgetId() : MacroUtil >+ .getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE); >+ String obj = isObjectFound ? commandObject.getObjectId() : MacroUtil >+ .getAttribute(node, MacroConstants.OBJECT_ID_ATTRIBUTE); >+ String rid = isObjectFound ? commandObject.getResolverId() : MacroUtil >+ .getAttribute(node, MacroConstants.RESOLVER_ID_ATTRIBUTE); >+ >+ if (cid != null && wid != null) { >+ PrimitiveUIObjectIdentifier objectIdentifier = null; >+ if (wid == null) { >+ objectIdentifier = new PrimitiveUIObjectIdentifier( >+ MacroConstants.EMPTY_STRING, rid); >+ } else { >+ objectIdentifier = new PrimitiveUIObjectIdentifier(wid, >+ obj, rid); >+ } >+ setMacroObjectIdentifier(new MacroObjectIdentifier( >+ cid == null ? MacroConstants.EMPTY_STRING : cid, >+ objectIdentifier)); >+ } >+ } >+ >+ public void write(int indent, StringBuffer sb, boolean close, boolean end) { >+ // let the super implementation write the element, we will just add our >+ // attributes >+ super.write(indent, sb, false, false); >+ >+ writeMacroObjectIdentifier(indent, sb, close, end); >+ } >+ >+ protected void writeMacroObjectIdentifier(int indent, StringBuffer sb, >+ boolean close, boolean end) { >+ boolean noWidgetId = getMacroObjectIdentifier() == null; >+ boolean objectMineInUse = useObjectMine(); >+ MacroUtil >+ .addAttribute( >+ sb, >+ new String[] { MacroConstants.RESOLVER_ID_ATTRIBUTE, >+ MacroConstants.CONTEXT_ID_ATTRIBUTE, >+ MacroConstants.WIDGET_ID_ATTRIBUTE, >+ MacroConstants.OBJECT_ID_ATTRIBUTE, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE }, >+ new String[] { >+ objectMineInUse || noWidgetId ? null >+ : getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getResolverId(), >+ objectMineInUse || noWidgetId ? null >+ : getMacroObjectIdentifier() >+ .getContextIdentifier(), >+ objectMineInUse || noWidgetId ? null >+ : getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getWidgetId(), >+ objectMineInUse || noWidgetId ? null >+ : getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .getObjectId(), >+ objectMineInUse ? getCorrespondingMacroObjectDescriptor() >+ .getReferenceId() >+ : null }, close, end); >+ } >+ >+ protected boolean useObjectMine() { >+ return MacroManager.getInstance().isObjectMineOn(); >+ } >+ >+ public boolean playback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException { >+ if (getMacroObjectIdentifier() != null) { >+ macroObject = MacroObjectResolver.deresolve(parent, >+ getMacroObjectIdentifier()); >+ } >+ return doPlayback(display, parent, monitor); >+ } >+ >+ public boolean doPlayback(Display display, Shell parent, >+ IProgressMonitor monitor) throws CoreException{ >+ // nothing to do by default >+ return false; >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#equals(java.lang.Object) >+ */ >+ public boolean equals(Object obj) { >+ if (!super.equals(obj)) { >+ return false; >+ } >+ if (!(obj instanceof ObjectBasedCommand)) { >+ return false; >+ } >+ ObjectBasedCommand compareWithObj = (ObjectBasedCommand) obj; >+ return compareWithObj.getMacroObjectIdentifier() != null >+ && compareWithObj.getMacroObjectIdentifier().equals( >+ getMacroObjectIdentifier()); >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/NonTrivialUIObjectResolverDelegate.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/NonTrivialUIObjectResolverDelegate.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/NonTrivialUIObjectResolverDelegate.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/NonTrivialUIObjectResolverDelegate.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,879 @@ >+/******************************************************************************* >+ * Copyright (c) 2005, 2007 IBM Corporation and others. >+ * 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 >+ * $Id: NonTrivialUIObjectResolverDelegate.java,v 1.4 2007/05/02 19:35:58 paules Exp $ >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.hyades.models.hierarchy.TRCAgentProxy; >+import org.eclipse.jface.action.ActionContributionItem; >+import org.eclipse.jface.action.IAction; >+import org.eclipse.jface.action.IContributionItem; >+import org.eclipse.jface.window.Window; >+import org.eclipse.jface.wizard.IWizardPage; >+import org.eclipse.jface.wizard.WizardDialog; >+import org.eclipse.swt.custom.CCombo; >+import org.eclipse.swt.custom.CTabFolder; >+import org.eclipse.swt.custom.CTabItem; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.widgets.Button; >+import org.eclipse.swt.widgets.Combo; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Group; >+import org.eclipse.swt.widgets.Item; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.swt.widgets.Text; >+import org.eclipse.swt.widgets.ToolBar; >+import org.eclipse.swt.widgets.ToolItem; >+import org.eclipse.swt.widgets.Tree; >+import org.eclipse.swt.widgets.TreeItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.WeightedPropertyUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport; >+import org.eclipse.tptp.trace.ui.internal.launcher.core.AnalysisType; >+import org.eclipse.tptp.trace.ui.internal.launcher.core.DataCollectorTreeContentProvider.ParentChildNode; >+import org.eclipse.ui.IPluginContribution; >+import org.eclipse.ui.IViewPart; >+import org.eclipse.ui.IWorkbenchPage; >+import org.eclipse.ui.IWorkbenchPart; >+import org.eclipse.ui.IWorkbenchWindow; >+import org.eclipse.ui.dialogs.FileSystemElement; >+import org.eclipse.ui.model.IWorkbenchAdapter; >+import org.eclipse.ui.views.IViewCategory; >+ >+/** >+ * <p> >+ * The purpose of this class is to resolve widgets that cannot be resolved using >+ * the AdaptiveUIObjectResolverDelegate. These widgets will likely require >+ * nested calls in order to be determined. >+ * </p> >+ * <p> >+ * Some of the properties used to resolve a widget are locale dependent (e.g. >+ * the name of a button or the closest label to a text box) >+ * </p> >+ * >+ * @since 4.1 >+ * @author Ali Mehregani >+ * @author Alexander Nyssen >+ */ >+public class NonTrivialUIObjectResolverDelegate implements >+ IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade { >+ >+ /** >+ * The id of this resolver -- must be in sync with the id registered with >+ * the widgetResolver extension. >+ */ >+ public static final String ID = "org.eclipse.tptp.test.auto.gui.nontrivial"; >+ >+ public IUIObjectIdentifier resolve(Object context, IUIObject uiObject) >+ throws CoreException { >+ Widget widget = uiObject.getWidget(); >+ Object object = uiObject.getObject(); >+ >+ Object data = widget.getData(); >+ >+ IUIObjectIdentifier widgetId = null; >+ >+ /* Resolve the object based on the data type of the widget */ >+ /* An agent */ >+ if (data instanceof TRCAgentProxy) { >+ widgetId = resolveAgentProxy(widget); >+ } >+ /* A file system element */ >+ else if (data instanceof FileSystemElement) { >+ widgetId = resolveFileSystemElement(widget); >+ } >+ /* A view catgory */ >+ else if (data instanceof IViewCategory) { >+ String id = ((IViewCategory) data).getId(); >+ if (id != null && id.length() > 0) { >+ widgetId = new PrimitiveUIObjectIdentifier(id, ID); >+ } >+ } >+ /* Analysis type */ >+ else if (data instanceof ParentChildNode) { >+ Object child = ((ParentChildNode) data).child; >+ if (child instanceof AnalysisType) { >+ widgetId = resolveAnalysisType((AnalysisType) child); >+ } >+ } >+ /* A menu item or a tree item */ >+ else if (widget instanceof MenuItem || widget instanceof TreeItem) { >+ widgetId = resolveItem((Item) widget); >+ } >+ /* A TabItem or CTabItem */ >+ else if (widget instanceof TabItem || widget instanceof CTabItem) { >+ String itemText = validateText(widget instanceof TabItem ? ((TabItem) widget) >+ .getText() >+ : ((CTabItem) widget).getText()); >+ widgetId = itemText != null ? new PrimitiveUIObjectIdentifier( >+ itemText, ID) : null; >+ } >+ /* A tool item */ >+ else if (widget instanceof ToolItem) { >+ widgetId = resolveToolbarItem((ToolItem) widget); >+ } >+ /* A menu (added by ANy) */ >+ else if (widget instanceof Menu) { >+ widgetId = getActionId((Menu) widget); >+ } >+ // controls >+ else if (widget instanceof Control) { >+ /* A button */ >+ if (widget instanceof Button) { >+ widgetId = resolveButton((Button) widget); >+ } >+ /* A text box */ >+ else if (widget instanceof Text) { >+ widgetId = resolveText((Text) widget); >+ } >+ /* A toolbar */ >+ else if (widget instanceof ToolBar) { >+ widgetId = resolveToolBar((ToolBar) widget); >+ } >+ /* Resolve the object based on its widget type */ >+ /* A control (added by ANy) */ >+ else if (widget instanceof Shell) { >+ widgetId = getShellId((Shell) widget); >+ } >+ >+ if (widgetId == null) { >+ Control control = (Control) widget; >+ Shell shell = control.getShell(); >+ Object shellData = shell.getData(); >+ if (shellData instanceof WizardDialog) { >+ // in wizard >+ WizardDialog wd = (WizardDialog) shellData; >+ IWizardPage page = wd.getCurrentPage(); >+ Control pageControl = page.getControl(); >+ widgetId = computeRelativePath((Composite) pageControl, >+ null, control); >+ if (widgetId == null) { >+ // check for wizard buttons >+ if (control instanceof Button) { >+ widgetId = computeRelativePath(shell, >+ (Composite) pageControl, control); >+ } >+ } >+ } else if (shellData instanceof IWorkbenchWindow) { >+ >+ IWorkbenchWindow window = (IWorkbenchWindow) shellData; >+ IWorkbenchPage page = window.getActivePage(); >+ IWorkbenchPart part = page.getActivePart(); >+ >+ Composite paneComposite = MacroUtil >+ .getWorkbenchPartControl(part); >+ >+ /* >+ * If the control we are looking for is a local tool bar, go >+ * up one level >+ */ >+ if (part instanceof IViewPart && control instanceof ToolBar) { >+ paneComposite = paneComposite.getParent(); >+ } >+ widgetId = computeRelativePath(paneComposite, null, control); >+ } else { >+ /* unknown shell - fetch controls starting from the shell */ >+ widgetId = computeRelativePath(shell, null, control); >+ } >+ >+ // ANy: in case we have items on a combo box or tab folder >+ if (uiObject.getObject() != null && (widget instanceof Combo >+ || widget instanceof CCombo)) { >+ >+ widgetId = new PrimitiveUIObjectIdentifier(widgetId >+ .getWidgetId(), computeDefaultChoiceId(widget, >+ uiObject.getObject()).toString(), ID); >+ } >+ } >+ } >+ >+ /* >+ * (added by ANy) Defect #: 112668: If we have to resolve an Item try >+ * the old policy before giving up >+ */ >+ if (widgetId == null && widget instanceof Item) { >+ widgetId = determineItemId((Item) widget); >+ } >+ >+ return widgetId; >+ } >+ >+ public IUIObject deresolve(Object context, >+ IUIObjectIdentifier uiObjectIdentifier) throws CoreException { >+ return UIObjectDeprecatedDeresolvingSupport.deresolve(context, >+ uiObjectIdentifier); >+ } >+ >+ private IUIObjectIdentifier resolveAnalysisType(AnalysisType analysisType) { >+ Object[] properties = { new Object[] { analysisType.getId(), "1.0" }, }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ >+ private IUIObjectIdentifier resolveToolBar(ToolBar toolbar) { >+ int itemCount = toolbar.getItemCount(); >+ String firstItem = itemCount > 1 ? limitText(toolbar.getItem(0) >+ .getToolTipText()) : null, lastItem = itemCount > 2 ? limitText(toolbar >+ .getItem(itemCount - 1).getToolTipText()) >+ : null; >+ int style = toolbar.getStyle(); >+ >+ if (firstItem == null && lastItem == null) >+ return null; >+ >+ Object[] properties = { new Object[] { firstItem, "0.5" }, >+ new Object[] { lastItem, "0.5" }, >+ new Object[] { String.valueOf(itemCount), "0.3" }, >+ new Object[] { String.valueOf(style), "0.2" } }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ >+ private IUIObjectIdentifier resolveToolbarItem(ToolItem item) { >+ String text = limitText(item.getToolTipText()); >+ String actionId = getActionId(item).toString(); >+ String style = String.valueOf(item.getStyle()); >+ >+ Object[] properties = { new Object[] { text, "0.7" }, >+ new Object[] { actionId, "0.7" }, new Object[] { style, "0.3" } }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ >+ private String limitText(String str) { >+ final int MAX_HOVER_TEXT_SIZE = 20; >+ if (str != null && str.length() > MAX_HOVER_TEXT_SIZE) { >+ return str.substring(0, MAX_HOVER_TEXT_SIZE) + "..."; >+ } >+ return str; >+ } >+ >+ /* >+ * Needed to find buttons, which are identified by a deprecated identifier >+ * format >+ */ >+ private IUIObjectIdentifier resolveButtonDeprecated(Button button, >+ IUIObjectIdentifier id) { >+ String text = null, hoverText = null, size = null, location = null; >+ if ((text = button.getText()) != null) { >+ text = text.replaceAll("\\&", ""); >+ } >+ /* First 20 characters of the hover text */ >+ hoverText = limitText(button.getToolTipText()); >+ Point sizePt = button.getSize(); >+ Point locationPt = button.getLocation(); >+ size = "(" + sizePt.x + "," + sizePt.y + ")"; >+ >+ if (id != null && countTokens(id.toString()) == 3) { >+ >+ Object[] properties = { new Object[] { text, "0.5" }, >+ new Object[] { hoverText, "0.5" }, >+ new Object[] { size, "0.5" } }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ return null; >+ } >+ >+ private IUIObjectIdentifier resolveButton(Button button) { >+ String text = null, hoverText = null, size = null, location = null; >+ if ((text = button.getText()) != null) { >+ text = text.replaceAll("\\&", ""); >+ } >+ /* First 20 characters of the hover text */ >+ hoverText = limitText(button.getToolTipText()); >+ Point sizePt = button.getSize(); >+ Point locationPt = button.getLocation(); >+ size = "(" + sizePt.x + "," + sizePt.y + ")"; >+ location = "(" + locationPt.x + "," + locationPt.y + ")"; >+ >+ if (button.getParent() != null) { >+ // Control[] children = ((Composite)parent).getChildren(); >+ Control[] children = button.getParent().getChildren(); >+ int buttonInx = 0; >+ >+ /* Find the index of the button */ >+ for (int i = 0; i < children.length; i++) { >+ if (button == children[i]) { >+ buttonInx = i; >+ break; >+ } >+ } >+ >+ Object[] properties = { new Object[] { text, "0.3" }, >+ new Object[] { hoverText, "0.3" }, >+ new Object[] { String.valueOf(children.length), "0.3" }, >+ new Object[] { size, "0.2" }, >+ new Object[] { location, "0.1" }, >+ new Object[] { String.valueOf(buttonInx), "0.2" }, }; >+ >+ float threshold = 0.7f; >+ threshold += text != null ? 0.3 : 0; >+ threshold += hoverText != null ? 0.3 : 0; >+ >+ if (threshold >= 1.0) >+ return WeightedPropertyUIObjectIdentifier.constructId( >+ properties, (float) 1.0, ID); >+ } >+ >+ return null; >+ } >+ >+ /** >+ * The text of the closest label to a text box is used as a unique >+ * identifier of the text box. The label must be in a limited vicinity of >+ * the text box for its text to be considered as an identifier. If the text >+ * box is owned by a group and the group only owns one text box, then the >+ * group text is used to identify the widget. >+ * >+ * @param text >+ * The text box >+ * @return The widget id for text >+ */ >+ private IUIObjectIdentifier resolveText(Text text) { >+ Composite parent = text.getParent(); >+ Control[] children = parent.getChildren(); >+ >+ String groupText = null; >+ if (parent instanceof Group >+ && (groupText = ((Group) parent).getText()) != null >+ && (groupText = groupText.replaceAll("\\&", "")).length() > 0) { >+ int textBoxNum = 0; >+ for (int i = 0; i < children.length && textBoxNum <= 1; i++) { >+ if (children[i] instanceof Text) >+ textBoxNum++; >+ } >+ >+ if (textBoxNum <= 1) >+ return new PrimitiveUIObjectIdentifier(groupText, ID); >+ } >+ >+ Label closestLabel = null; >+ Point textLocation = text.getLocation(); >+ Point currentDistance = new Point(0, 0); >+ Point tempDistance = new Point(0, 0); >+ for (int i = 0; i < children.length; i++) { >+ Point childLocation = children[i].getLocation(); >+ if (children[i] instanceof Label >+ && (closestLabel == null || (tempDistance = isLabelCloser( >+ childLocation, currentDistance, textLocation)) != null)) { >+ boolean firstLabel = closestLabel == null; >+ closestLabel = (Label) children[i]; >+ ; >+ if (firstLabel) { >+ currentDistance = new Point(Math.abs(childLocation.x >+ - textLocation.x), Math.abs(childLocation.y >+ - textLocation.y)); >+ } else { >+ currentDistance = tempDistance; >+ } >+ } >+ } >+ >+ String closestLabelText = null; >+ if (closestLabel != null >+ && currentDistance.x + currentDistance.y <= 100 >+ && closestLabel.getText() != null >+ && (closestLabelText = closestLabel.getText().replaceAll("\\&", >+ "")).length() > 0) >+ return new PrimitiveUIObjectIdentifier(closestLabelText, ID); >+ return null; >+ } >+ >+ private Point isLabelCloser(Point newlblLocation, Point currentDistance, >+ Point textLocation) { >+ Point tempLocation = new Point(Math.abs(newlblLocation.x >+ - textLocation.x), Math.abs(newlblLocation.y - textLocation.y)); >+ if (tempLocation.x + tempLocation.y < currentDistance.x >+ + currentDistance.y) >+ return tempLocation; >+ return null; >+ } >+ >+ public static String validateText(String text) { >+ if (text != null && (text = text.replaceAll("\\&", "")).length() > 0) >+ return text; >+ return null; >+ } >+ >+ /** >+ * Computes the item id based on the following properties and weights. The >+ * threshold is set to 1.0: >+ * >+ * <ul> >+ * <li> (Descriptive name of the item, 1.0) </li> >+ * </ul> >+ * >+ * @param item >+ * The item >+ * @return The weighted id >+ */ >+ private IUIObjectIdentifier resolveItem(Item item) { >+ StringBuffer descriptiveText = new StringBuffer(); >+ findItemText(item, descriptiveText); >+ >+ /* Remove the ampersands */ >+ String itemText = descriptiveText.toString().replaceAll("\\&", ""); >+ >+ Object[] properties = { new Object[] { itemText, "1.0" }, }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ >+ /** >+ * Walk through the item and return a descriptive text that corresponds to >+ * all item selections leading to the item. (e.g. File-New-Project) >+ * >+ * @param item >+ * The item >+ * @param descriptiveText >+ * In the end, this buffer will contain a descriptive text of all >+ * items leading to the item that is passed in as argument >+ */ >+ private void findItemText(Item item, StringBuffer descriptiveText) { >+ if (item == null) >+ return; >+ >+ String descriptiveTextStr = item.getText(); >+ if (descriptiveText.length() > 0) >+ descriptiveTextStr += "-"; >+ >+ descriptiveText.insert(0, descriptiveTextStr); >+ >+ Item parentItem = null; >+ if (item instanceof MenuItem) { >+ Menu menu = ((MenuItem) item).getParent(); >+ parentItem = (menu == null ? null : menu.getParentItem()); >+ } else if (item instanceof TreeItem) { >+ parentItem = ((TreeItem) item).getParentItem(); >+ } >+ >+ if (parentItem != null) >+ findItemText(parentItem, descriptiveText); >+ } >+ >+ private IUIObjectIdentifier resolveFileSystemElement(Widget widget) { >+ >+ FileSystemElement fileSystemElement = (FileSystemElement) widget >+ .getData(); >+ if (fileSystemElement.isDirectory()) >+ return null; >+ >+ Object[] properties = { new Object[] { >+ ((IWorkbenchAdapter) fileSystemElement >+ .getAdapter(IWorkbenchAdapter.class)).getLabel(null), >+ "1.0" } }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 1.0, ID); >+ } >+ >+ private WeightedPropertyUIObjectIdentifier resolveAgentProxy(Widget widget) { >+ StringBuffer treeIndex = new StringBuffer(); >+ if (widget instanceof TreeItem) >+ findTreeItemIndex((TreeItem) widget, treeIndex); >+ else >+ return null; >+ >+ TRCAgentProxy proxy = (TRCAgentProxy) widget.getData(); >+ Object[] properties = { >+ new Object[] { treeIndex.toString(), "0.4" }, >+ new Object[] { proxy.getProcessProxy().getName(), "0.2" }, >+ new Object[] { proxy.getProcessProxy().getVmArguments(), "0.1" }, >+ new Object[] { proxy.getProcessProxy().getClasspath(), "0.1" }, >+ new Object[] { proxy.getProcessProxy().getLocation(), "0.1" }, >+ new Object[] { proxy.getProcessProxy().getParameters(), "0.1" }, >+ new Object[] { proxy.getProfileFile(), "0.1" }, >+ new Object[] { proxy.getName(), "0.1" }, >+ new Object[] { String.valueOf(proxy.isAttached()), "0.1" }, >+ new Object[] { String.valueOf(proxy.isMonitored()), "0.1" }, >+ new Object[] { String.valueOf(proxy.isToProfileFile()), "0.1" }, }; >+ >+ return WeightedPropertyUIObjectIdentifier.constructId(properties, >+ (float) 0.7, ID); >+ } >+ >+ private void findTreeItemIndex(TreeItem treeItem, StringBuffer sb) { >+ TreeItem parentItem = treeItem.getParentItem(); >+ if (parentItem != null) { >+ int index = parentItem.indexOf(treeItem); >+ if (index != -1) >+ sb.append("|" + String.valueOf(index + 1)); >+ >+ findTreeItemIndex(parentItem, sb); >+ } >+ Tree tree = treeItem.getParent(); >+ int index = tree.indexOf(treeItem); >+ if (index != -1) >+ sb.append("|" + String.valueOf(index)); >+ >+ } >+ >+ /** >+ * @deprecated This can be removed the resolver does not longer depend on >+ * the UIDeprecatedDeresolvingSupport to deresolve UI objects. >+ * {@inheritDoc} >+ * @see org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.internal.uiobject.resolver.delegate.IUIObjectDeprecatedDeresolvingFacade#foundWidget(org.eclipse.swt.widgets.Widget, >+ * org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier) >+ */ >+ public boolean foundWidget(Widget widget, IUIObjectIdentifier widgetId) { >+ IUIObjectIdentifier objectId = null; >+ >+ // ANy: It seems that the resolving for buttons was changed. For >+ // backwards compatibility, >+ // the foundWidget has to accept the old button identifier format as >+ // well. >+ if (widget instanceof Button) { >+ Button button = (Button) widget; >+ objectId = resolveButtonDeprecated(button, widgetId); >+ } >+ >+ if (objectId == null) >+ try { >+ objectId = UIObjectResolver.resolve(new MacroObject( >+ new UIObject(widget)).getContext(), >+ new UIObject(widget)); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ } >+ if (widgetId == null || widgetId.getWidgetId() == null) { >+ return false; >+ } else { >+ if (objectId == null) { >+ return false; >+ } else { >+ return objectId.equals(widgetId); >+ } >+ } >+ } >+ >+ /** >+ * Given a string representation of the id, this method will return the >+ * number of tokens that it contains. A token is a name, value pair in the >+ * format. >+ * >+ * @param id >+ * The string representation of the id >+ * @return The number of tokens of the id >+ */ >+ public static int countTokens(String id) { >+ if (id == null) >+ return 0; >+ >+ char[] characters = id.toCharArray(); >+ boolean braceInxHit = false; >+ int tokenCount = 0; >+ for (int i = 0; i < characters.length; i++) { >+ if (characters[i] == '{') { >+ if (braceInxHit) { >+ tokenCount++; >+ } else { >+ braceInxHit = true; >+ continue; >+ } >+ } >+ braceInxHit = false; >+ } >+ >+ return tokenCount / 2; >+ } >+ >+ /** >+ * Defect #: 112668 This method is invoked to retrieve the id of a menu >+ * item. Here's the policy that it employs: >+ * <ol> >+ * <li> Use the contributed widget resolvers </li> >+ * <li> If failed, default to what was being used before </li> >+ * </ol> >+ * >+ * @param item >+ * The menu item >+ * @return The id of the passed item. >+ */ >+ private IUIObjectIdentifier determineItemId(Item item) { >+ if (item instanceof ToolItem) { >+ return getActionId((ToolItem) item); >+ } else if (item instanceof MenuItem) { >+ return getActionId((MenuItem) item); >+ } else if (item instanceof IContributionItem) { >+ return getActionId((IContributionItem) item); >+ } >+ return null; >+ } >+ >+ /** >+ * @param widget >+ * @return >+ */ >+ public static IUIObjectIdentifier getActionId(Widget widget) { >+ Object data = widget.getData(); >+ PrimitiveUIObjectIdentifier widgetId = null; >+ if (data != null && (data instanceof IContributionItem)) { >+ widgetId = getActionId((IContributionItem) data); >+ if (widgetId != null >+ && !widgetId.toString().equals(MacroConstants.EMPTY_STRING)) { >+ if (widget instanceof MenuItem) { >+ String menuInx = findMenuItemIndex((MenuItem) widget, ""); >+ widgetId = new PrimitiveUIObjectIdentifier(widgetId >+ .toString() >+ + menuInx, ID); >+ } >+ } >+ } else { >+ widgetId = new PrimitiveUIObjectIdentifier( >+ "readablename/" + ((widget instanceof MenuItem) ? getDisplayName((MenuItem) widget) : getDisplayName((ToolItem) widget)), ID); //$NON-NLS-1$ >+ } >+ >+ return widgetId; >+ } >+ >+ public static PrimitiveUIObjectIdentifier getActionId( >+ IContributionItem contrib) { >+ String id = null; >+ PrimitiveUIObjectIdentifier widgetId = null; >+ >+ if (contrib instanceof IPluginContribution) { >+ id = ((IPluginContribution) contrib).getLocalId(); >+ } >+ id = id == null ? contrib.getId() : id; >+ if (id != null) { >+ widgetId = new PrimitiveUIObjectIdentifier("contribid/" + id, ID); //$NON-NLS-1$ >+ } else { >+ if (contrib instanceof ActionContributionItem) { >+ ActionContributionItem actionItem = (ActionContributionItem) contrib; >+ id = actionItem.getId(); >+ if (id != null) { >+ widgetId = new PrimitiveUIObjectIdentifier( >+ "actionid/" + id, ID); //$NON-NLS-1$ >+ } else { >+ IAction action = actionItem.getAction(); >+ id = action.getActionDefinitionId(); >+ if (id != null) { >+ widgetId = new PrimitiveUIObjectIdentifier( >+ "defid/" + id, ID); //$NON-NLS-1$ >+ } else { >+ widgetId = new PrimitiveUIObjectIdentifier( >+ "actionclass/" + action.getClass().getName(), ID); //$NON-NLS-1$ >+ } >+ } >+ } else { >+ widgetId = new PrimitiveUIObjectIdentifier( >+ "contribclass/" + contrib.getClass().getName(), ID); //$NON-NLS-1$ >+ } >+ } >+ >+ return widgetId; >+ } >+ >+ /** >+ * @deprecated Should not be done here, but in the delegators Walks through >+ * all parent menus of the menuItem and returns an index of >+ * format <num>|<num>|<num>|... For example >+ * assuming menuItem is placed as follows: >+ * >+ * item 1 |_item 2 | |_item 4 |_item 3 |_menuItem >+ * >+ * then its respective index will be 1|2|1 >+ * >+ * @param menuItem >+ * The menu item whose index will be determined >+ * @return The index of the menu item as described above. >+ */ >+ private static String findMenuItemIndex(MenuItem menuItem, String menuInx) { >+ if (menuItem == null) >+ return menuInx; >+ >+ if (menuInx.length() > 0) >+ menuInx = "|" + menuInx; >+ menuInx = menuItem.getParent().indexOf(menuItem) + menuInx; >+ return findMenuItemIndex(menuItem.getParent().getParentItem(), menuInx); >+ } >+ >+ /** >+ * Returns an identifier for the given Menu, based on its user-readable >+ * strings >+ * >+ * @param menu >+ * @return >+ */ >+ private static String getDisplayName(Menu menu) { >+ >+ MenuItem parentItem = menu.getParentItem(); >+ >+ if (parentItem == null) { >+ return MacroConstants.EMPTY_STRING; >+ } >+ >+ return getDisplayName(parentItem); >+ } >+ >+ /** >+ * Returns an identifier for the given MenuItem, based on its user-readable >+ * strings >+ * >+ * @param menuItem >+ * @return >+ */ >+ private static String getDisplayName(MenuItem menuItem) { >+ if (menuItem.getParent() == null >+ || menuItem.getParent().getParentItem() == null) { >+ return MacroUtil.removeChar(menuItem.getText(), '&'); >+ } >+ >+ return getDisplayName(menuItem.getParent()) + "/" //$NON-NLS-1$ >+ + MacroUtil.removeChar(menuItem.getText(), '&'); >+ } >+ >+ /** >+ * @param toolItem >+ * @return >+ */ >+ private static String getDisplayName(ToolItem toolItem) { >+ String name = toolItem.getText(); >+ >+ if (name != null && !name.equals(MacroConstants.EMPTY_STRING)) { >+ return name; >+ } >+ >+ name = toolItem.getToolTipText(); >+ >+ if (name != null) { >+ return name; >+ } >+ >+ return "unknown"; //$NON-NLS-1$ >+ } >+ >+ /** >+ * @deprecated Use resolveUIObject instead (move implementation there) >+ * @param context >+ * @param parent >+ * @param skip >+ * @param control >+ * @return >+ */ >+ public static IUIObjectIdentifier computeRelativePath(Composite parent, >+ Composite skip, Control control) { >+ int[] counter = MacroUtil.newCounter(); >+ Vector indices = new Vector(); >+ boolean result = computeControlIndex(parent, skip, control, counter, >+ indices); >+ if (!result && skip == null) >+ return null; >+ >+ int index = result ? ((Integer) indices.get(0)).intValue() : 0; >+ return computeDefaultControlId(control, index); >+ } >+ >+ /** >+ * Determines the index of the desiredControl relative to the parent control >+ * sent in. The Index is stored in index[0]. >+ * >+ * @param parent >+ * The parent control >+ * @param skip >+ * Indicates whether a composite should be skipped >+ * @param desiredControl >+ * The desired control >+ * @param index >+ * The current index calculated thus far (stored in index[0]. The >+ * type of this parameter is an int array because its value needs >+ * to be preserved between recursive calls. >+ * >+ * @return true if the index was found; false otherwise. >+ */ >+ private static boolean computeControlIndex(Composite parent, >+ Composite skip, Control desiredControl, int[] index, Vector indices) { >+ return UIObjectDeprecatedDeresolvingSupport.recursiveSearch(parent, >+ skip, desiredControl, null, null, index, new Vector(), indices) != null; >+ } >+ >+ public static IUIObjectIdentifier computeDefaultControlId(Control control, >+ int controlIndex) { >+ PrimitiveUIObjectIdentifier primitiveWidgetId = new PrimitiveUIObjectIdentifier( >+ control.getClass().getName() + "#" + controlIndex, ID); >+ return primitiveWidgetId; >+ } >+ >+ /** >+ * Moved here from ChoiceCommand >+ * >+ * @param widget >+ * @param item >+ * @return >+ */ >+ private IUIObjectIdentifier computeDefaultChoiceId(Widget widget, >+ Object item) { >+ int index = -1; >+ boolean isCombo = widget instanceof Combo; >+ boolean isCCombo = isCombo ? false : widget instanceof CCombo; >+ if (isCombo || isCCombo) { >+ Combo combo = isCombo ? ((Combo) widget) : null; >+ CCombo ccombo = isCCombo ? ((CCombo) widget) : null; >+ >+ index = isCombo ? combo.indexOf((String) item) : ccombo >+ .indexOf((String) item); >+ } else { >+ boolean isTabFolder = widget instanceof TabFolder; >+ boolean isCTabFolder = isTabFolder ? false >+ : widget instanceof CTabFolder; >+ if (isTabFolder || isCTabFolder) { >+ index = isTabFolder ? ((TabFolder) widget) >+ .indexOf((TabItem) item) : ((CTabFolder) widget) >+ .indexOf((CTabItem) item); >+ } >+ } >+ >+ if (index != -1) >+ return new PrimitiveUIObjectIdentifier("item#" + index, ID); >+ return null; >+ } >+ >+ private static IUIObjectIdentifier getShellId(Shell shell) { >+ return getDefaultShellId(shell); >+ } >+ >+ private static IUIObjectIdentifier getDefaultShellId(Shell shell) { >+ Object data = shell.getData(); >+ String id = ""; >+ if (data instanceof WizardDialog) { >+ id = data.getClass().getName().toString(); >+ } else if (data instanceof Window) { >+ id = data.getClass().getName().toString(); >+ } >+ >+ PrimitiveUIObjectIdentifier widgetId = new PrimitiveUIObjectIdentifier( >+ id, ID); >+ return widgetId; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactory.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactory.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactory.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactory.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,619 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.commands.factory; >+ >+import java.util.ArrayList; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.CCombo; >+import org.eclipse.swt.custom.CTabFolder; >+import org.eclipse.swt.custom.StyledText; >+import org.eclipse.swt.widgets.Button; >+import org.eclipse.swt.widgets.Combo; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.List; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.Text; >+import org.eclipse.swt.widgets.ToolItem; >+import org.eclipse.swt.widgets.Tree; >+import org.eclipse.swt.widgets.TreeItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.BooleanSelectionCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.CheckCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.ChoiceSelectionCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.CloseWorkbenchPartCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.ExpansionCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.FocusCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.KeyEventCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.MouseEventCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.StructuredSelectionCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand; >+import org.eclipse.tptp.test.auto.gui.internal.macro.EventConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+ >+/** >+ * @author Alexander Nyssen >+ * >+ */ >+public class MacroCommandFactory implements IMacroCommandFactory { >+ >+ /* The last event received */ >+ protected transient Event lastEvent; >+ >+ /* Indicates user interaction -- Set when a key up event is received */ >+ protected transient boolean isKeyPressed; >+ >+ /* Indicates user interaction -- Set when a mouse up event is received */ >+ protected transient boolean isMousePressed; >+ >+ /* Stores an event that is only acknowledged followed by user interaction. */ >+ protected transient Event toBeAckEvent; >+ >+ /* Set when the stored event in toBeAckEvent is acknowledged */ >+ protected transient boolean ackEvent; >+ >+ /* Stores the time for which a command was last created in */ >+ protected long lastCommandCreationTime; >+ >+ public IMacroCommand createCommand(MacroCommandShell commandShell, >+ ArrayList commands, Event event) throws CoreException { >+ >+ // see if we can merge the event with the last created command >+ AbstractMacroCommand lastCommand = getLastCommand(commands); >+ if (lastEvent != null >+ && (lastEvent.detail == EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT || (lastEvent.widget != null >+ && lastEvent.widget.equals(event.widget) && (lastEvent.type == event.type || (lastEvent.type == SWT.Selection && event.type == SWT.DefaultSelection))))) { >+ try { >+ if (lastCommand != null && lastCommand.mergeEvent(event)) { >+ return null; >+ } >+ } catch (Exception e) { >+ // simply continue (the last command could not merge the >+ // event) >+ } >+ } >+ >+ AbstractMacroCommand command = null; >+ if (event.detail == EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT) >+ command = createPositionBasedCommand(commandShell, event); >+ else if (event.detail == EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) { >+ command = createVerificationHookInsertionCommand(commandShell, >+ event); >+ } else { >+ command = createObjectBasedCommand(commandShell, commands, event); >+ } >+ >+ if (command != null) { >+ /* >+ * Take out the last command if it is a focus command and the >+ * command just passed in implicitly does a focus >+ */ >+ if (lastCommand != null >+ && (lastCommand instanceof ObjectBasedCommand >+ && command instanceof ObjectBasedCommand >+ && ((ObjectBasedCommand) lastCommand) >+ .getMacroObjectIdentifier() >+ .equals( >+ ((ObjectBasedCommand) command) >+ .getMacroObjectIdentifier()) >+ && lastCommand.getType().equals(FocusCommand.TYPE) && isFocusCommand(command >+ .getType()))) { >+ // focus followed by select or modify - focus implied >+ commands.remove(lastCommand); >+ } >+ >+ /* Modify the last event accordinggly */ >+ if (ackEvent) { >+ ackEvent = false; >+ lastEvent = toBeAckEvent; >+ toBeAckEvent = null; >+ } else { >+ lastEvent = event; >+ } >+ >+ /* Add the artificial wait time if required */ >+ if (MacroManager.getInstance().isArtificialWaitOn() >+ && lastCommandCreationTime > 0) { >+ long currentTime = System.currentTimeMillis(); >+ long difference = currentTime - lastCommandCreationTime; >+ command.setTimeDifference(difference); >+ } >+ >+ lastCommandCreationTime = System.currentTimeMillis(); >+ >+ /* >+ * Ali M.: The following block of code provides a workaround for a >+ * limitation that exists for CloseWorkbenchPartCommand. We are only >+ * able to capture this event after the entire part has been >+ * disposed. Things would be ideal if this event could be captured >+ * right after the user clicks on the close button of the part >+ */ >+ if (command instanceof CloseWorkbenchPartCommand) { >+ int commandSize = commands.size(); >+ if (commandSize > 0) { >+ /* >+ * If the last command corresponds to the message dialog >+ * that prompts the user to save an editor, then store it >+ * after the close command >+ * >+ * ANy: Since Eclipse 3.4 this does not seem to be a >+ * MessageDialog any more, but a private anonymous Dialog >+ * implementation in org.eclipse.ui.internal.SaveablesList, >+ * so I adopted this here. >+ */ >+ /* If the last stored command is a shell */ >+ Object lastCommandStored = commands.get(commandSize - 1); >+ if (lastCommandStored instanceof MacroCommandShell >+ && >+ /* >+ * If the part is an editor >+ */ >+ ((CloseWorkbenchPartCommand) command) >+ .getMacroObjectIdentifier() >+ .getContextIdentifier().equals( >+ MacroConstants.EDITOR_VALUE) >+ && >+ /* >+ * If the shell is a MessageDialog or it is a >+ * private dialog inside the SaveablesList (Eclipse >+ * 3.4) >+ */ >+ (((MacroCommandShell) lastCommandStored) >+ .getMacroObjectIdentifier() >+ .getObjectIdentifier().getWidgetId() >+ .startsWith("org.eclipse.ui.internal.SaveablesList")) >+ || ((MacroCommandShell) lastCommandStored) >+ .getMacroObjectIdentifier() >+ .getObjectIdentifier().getWidgetId() >+ .equals(MessageDialog.class.getName())) >+ >+ { >+ commands.add(commandSize - 1, command); >+ } >+ >+ } >+ >+ } else { >+ /* >+ * Added for defect 164197 in order to add an item-expansion to >+ * the parent whenever the child is selected in a case where the >+ * parent has been pre-expanded. Liz D. >+ */ >+ if (command instanceof StructuredSelectionCommand >+ && event.widget instanceof Tree) { >+ StructuredSelectionCommand s = (StructuredSelectionCommand) command; >+ >+ TreeItem[] items = (TreeItem[]) s.getItemsForEvent(event); >+ for (int i = 0; i < items.length; i++) { >+ TreeItem selectedItem = (TreeItem) items[i]; >+ >+ while (selectedItem.getParentItem() != null) { >+ TreeItem parent = selectedItem.getParentItem(); >+ if (parent.getExpanded() == true) {// necessary so >+ // that >+ // we only apply >+ // this in the case >+ // where the parent >+ // is already >+ // expanded >+ Event expansionEvent = new Event(); >+ expansionEvent.widget = parent; >+ expansionEvent.item = parent; >+ ExpansionCommand parentExpand = new ExpansionCommand( >+ commandShell, s >+ .getMacroObjectIdentifier()); >+ parentExpand.doProcessEvent(expansionEvent, >+ true); >+ commands.add(parentExpand); >+ } >+ selectedItem = parent; >+ }// end while >+ } >+ } >+ >+ // add the command at the end of the list >+ commands.add(command); >+ } >+ } >+ return command; >+ } >+ >+ /** >+ * Handles object-based events >+ */ >+ protected AbstractMacroCommand createObjectBasedCommand( >+ MacroCommandShell commandShell, ArrayList commands, Event event) { >+ /* >+ * A quick way to get out if we're only getting key up or mouse events >+ * that have been detected before >+ */ >+ if ((isKeyPressed && event.type == SWT.KeyUp) >+ || (isMousePressed && event.type == SWT.MouseUp)) >+ return null; >+ >+ ObjectBasedCommand command = null; >+ >+ /* Check to see if we are a drop-down menu selection */ >+ AbstractMacroCommand lastCommand = getLastCommand(commands); >+ if (lastCommand != null >+ && lastCommand.getType() == BooleanSelectionCommand.TYPE >+ && ((BooleanSelectionCommand) lastCommand).getDetail() == SWT.DROP_DOWN) { >+ ((BooleanSelectionCommand) lastCommand).setItemSelected(event); >+ return null; >+ } >+ >+ if (event.type == EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) { >+ /* >+ * 110810 -- Create the close workbench command only if there is >+ * only one frame in our shell stack >+ */ >+ if (MacroManager.getInstance().getCurrentMacro() >+ .getShellStackSize() == 1) { >+ command = new CloseWorkbenchPartCommand(commandShell); >+ } >+ } else { >+ // process standard SWT event types >+ switch (event.type) { >+ case SWT.Modify: >+ if (!isEditable(event.widget)) >+ return null; >+ >+ /* >+ * This block of code is used to avoid displaying the browse >+ * native dialog when the user clicks a browse button - it >+ * doesn't cover all cases >+ */ >+ // ANy: Added check that button is not disposed >+ if (lastEvent != null && lastEvent.type == SWT.Selection >+ && lastEvent.widget instanceof Button >+ && !lastEvent.widget.isDisposed()) { >+ String text = ((Button) lastEvent.widget).getText(); >+ if (text != null) { >+ text = text.replaceAll("\\&", ""); >+ text = text.toLowerCase(); >+ if (text >+ .indexOf(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BROWSE) != -1) { >+ int size = 0; >+ if (commands != null >+ && (size = commands.size()) > 0) { >+ commands.remove(size - 1); >+ command = new ModifyCommand(commandShell); >+ break; >+ } >+ } >+ } >+ } >+ >+ /* Only acknowledge modifies that are followed by a key up event */ >+ toBeAckEvent = event; >+ break; >+ >+ case SWT.Selection: >+ case SWT.DefaultSelection: >+ command = createSelectionCommand(commandShell, event); >+ break; >+ >+ case SWT.FocusIn: >+ /** >+ * Ali M.: While recording, the SWT display listener has the >+ * tendency to report focus events on controls that are actually >+ * not visible to the user. When the macro is played back, the >+ * control cannot be located. To avoid this problem we only >+ * acknowledge focus events that are followed by a mouse up or >+ * key up event (i.e. The user explicitly focuses on the >+ * control). >+ */ >+ toBeAckEvent = event; >+ break; >+ >+ case SWT.Expand: >+ case SWT.Collapse: >+ command = new ExpansionCommand(commandShell); >+ break; >+ >+ case SWT.KeyUp: >+ isKeyPressed = true; >+ if (toBeAckEvent != null && toBeAckEvent.type == SWT.Modify) { >+ command = new ModifyCommand(commandShell); >+ ackEvent = true; >+ } else if (toBeAckEvent != null >+ && toBeAckEvent.type == SWT.FocusIn) { >+ command = new FocusCommand(commandShell); >+ ackEvent = true; >+ } >+ break; >+ >+ case SWT.MouseUp: >+ isMousePressed = true; >+ if (toBeAckEvent != null && toBeAckEvent.type == SWT.FocusIn) { >+ command = new FocusCommand(commandShell); >+ ackEvent = true; >+ } >+ break; >+ } >+ } >+ >+ if (event.type != SWT.KeyUp) >+ isKeyPressed = false; >+ if (event.type != SWT.MouseUp) >+ isMousePressed = false; >+ >+ if (command != null) { >+ try { >+ if (ackEvent) { >+ command.processEvent(toBeAckEvent); >+ } else { >+ command.processEvent(event); >+ } >+ } catch (Exception e) { >+ e.printStackTrace(); >+ command = null; >+ } >+ } >+ >+ /* Ensure that redundant commands are not created */ >+ if (lastCommand != null && command != null >+ && command.isRepeatRedundant() && command.equals(lastCommand)) { >+ return null; >+ } >+ return command; >+ } >+ >+ /** >+ * Handles position-based events >+ */ >+ protected AbstractMacroCommand createPositionBasedCommand( >+ MacroCommandShell commandShell, Event event) { >+ AbstractMacroCommand command = null; >+ >+ switch (event.type) { >+ case SWT.MouseUp: >+ case SWT.MouseDown: >+ case SWT.MouseMove: >+ case SWT.MouseDoubleClick: >+ command = new MouseEventCommand(commandShell); >+ break; >+ >+ case SWT.KeyUp: >+ case SWT.KeyDown: >+ command = new KeyEventCommand(commandShell); >+ break; >+ >+ } >+ >+ if (command != null) >+ try { >+ command.processEvent(event); >+ } catch (Exception e) { >+ command = null; >+ } >+ return command; >+ } >+ >+ protected ObjectBasedCommand createSelectionCommand( >+ MacroCommandShell commandShell, Event event) { >+ if (event.widget instanceof MenuItem >+ || event.widget instanceof ToolItem >+ || (event.widget instanceof Button >+ /* >+ * A CCombo will cause a button selection followed by a combo >+ * selection. We need to ignore the button selection >+ */ >+ && !(event.widget instanceof Control && ((Control) event.widget) >+ .getParent() instanceof CCombo))) { >+ ObjectBasedCommand selectionCommand = new BooleanSelectionCommand( >+ commandShell); >+ return selectionCommand; >+ } >+ >+ if (event.widget instanceof Tree || event.widget instanceof Table >+ || event.widget instanceof List) { >+ if (event.detail == SWT.CHECK) { >+ ObjectBasedCommand selectionCommand = new CheckCommand( >+ commandShell); >+ return selectionCommand; >+ } else { >+ String type = event.type == SWT.DefaultSelection ? StructuredSelectionCommand.DEFAULT_SELECT >+ : StructuredSelectionCommand.ITEM_SELECT; >+ ObjectBasedCommand selectionCommand = new StructuredSelectionCommand( >+ commandShell, type); >+ return selectionCommand; >+ } >+ } >+ >+ if (event.widget instanceof TabFolder >+ || event.widget instanceof CTabFolder) { >+ ObjectBasedCommand selectionCommand = new ChoiceSelectionCommand( >+ commandShell); >+ return selectionCommand; >+ } >+ if (event.widget instanceof Combo || event.widget instanceof CCombo) { >+ ObjectBasedCommand selectionCommand = new ChoiceSelectionCommand( >+ commandShell); >+ return selectionCommand; >+ } >+ return null; >+ } >+ >+ /** >+ * @param event >+ * @return >+ */ >+ protected AbstractMacroCommand createVerificationHookInsertionCommand( >+ MacroCommandShell commandShell, Event event) throws CoreException { >+ >+ VerificationCommand command = null; >+ >+ String error = ""; >+ >+ try { >+ /* Ignore all command except for a focus in command */ >+ switch (event.type) { >+ case SWT.Activate: >+ case SWT.Selection: >+ case SWT.FocusIn: >+ >+ IMacroObjectIdentifier widgetID = MacroObjectResolver.resolve( >+ commandShell.getShell(), new MacroObject(new UIObject( >+ event.widget))); >+ String path = (widgetID == null ? "" : new Path(widgetID >+ .getContextIdentifier() == null ? "" : widgetID >+ .getContextIdentifier()) >+ .append( >+ new Path(widgetID.getObjectIdentifier() >+ .getWidgetId() == null ? "" : widgetID >+ .getObjectIdentifier().getWidgetId())) >+ .toString()); >+ >+ if (VerificationCommand.findFocusType(path) == -1) { >+ error = AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON; >+ break; >+ } >+ >+ /* We only acknowledge after there is a mouse up event */ >+ toBeAckEvent = event; >+ break; >+ >+ case SWT.MouseUp: >+ >+ if (toBeAckEvent == null) >+ break; >+ >+ /* Create the verification command instance */ >+ command = new VerificationCommand(commandShell); >+ command.processEvent(toBeAckEvent); >+ >+ ackEvent = true; >+ break; >+ >+ default: >+ toBeAckEvent = null; >+ error = AutoGUIMessages.AUTO_GUI_ERROR_VER_WRONG_EVENT; >+ } >+ } catch (Exception e) { >+ error = e.getMessage(); >+ e.printStackTrace(); >+ } >+ >+ if (error != null && !(error.equals(""))) { >+ AutoGUIUtil.throwCoreException(error); >+ } >+ return command; >+ } >+ >+ AbstractMacroCommand getLastCommand(ArrayList commands) { >+ if (commands.size() > 0) { >+ Object item = commands.get(commands.size() - 1); >+ if (item instanceof AbstractMacroCommand) >+ return (AbstractMacroCommand) item; >+ } >+ return null; >+ } >+ >+ boolean isFocusCommand(String type) { >+ return type.equals(BooleanSelectionCommand.TYPE) >+ || type.equals(StructuredSelectionCommand.ITEM_SELECT) >+ || type.equals(StructuredSelectionCommand.DEFAULT_SELECT) >+ || type.equals(ExpansionCommand.TYPE) >+ || type.equals(CheckCommand.TYPE) >+ || type.equals(ModifyCommand.TYPE); >+ } >+ >+ private boolean isEditable(Widget widget) { >+ if (widget instanceof Control) { >+ Control control = (Control) widget; >+ if (!control.isEnabled()) >+ return false; >+ if (control instanceof Text) >+ return ((Text) control).getEditable(); >+ if (control instanceof Combo || control instanceof CCombo) >+ return ((control.getStyle() & SWT.READ_ONLY) == 0); >+ if (control instanceof StyledText) >+ return ((StyledText) control).getEditable(); >+ } >+ return true; >+ } >+ >+ public IMacroCommand createCommand(MacroCommandShell commandShell, >+ String type) throws CoreException { >+ // construct a new command dependent on the type >+ AbstractMacroCommand command = null; >+ >+ if (type.equals(ModifyCommand.TYPE)) >+ command = new ModifyCommand(commandShell); >+ >+ else if (type.equals(BooleanSelectionCommand.TYPE)) >+ command = new BooleanSelectionCommand(commandShell); >+ >+ else if (type.equals(StructuredSelectionCommand.ITEM_SELECT) >+ || type.equals(StructuredSelectionCommand.DEFAULT_SELECT)) >+ command = new StructuredSelectionCommand(commandShell, type); >+ >+ else if (type.equals(ExpansionCommand.TYPE)) >+ command = new ExpansionCommand(commandShell); >+ >+ else if (type.equals(CheckCommand.TYPE)) >+ command = new CheckCommand(commandShell); >+ >+ else if (type.equals(FocusCommand.TYPE)) >+ command = new FocusCommand(commandShell); >+ >+ else if (type.equals(ChoiceSelectionCommand.TYPE)) >+ command = new ChoiceSelectionCommand(commandShell); >+ >+ else if (type.equals(WaitCommand.TYPE)) >+ command = new WaitCommand(commandShell); >+ >+ /* The verification command */ >+ else if (type.equals(VerificationCommand.TYPE)) >+ command = new VerificationCommand(commandShell); >+ >+ /* The close workbench part command */ >+ else if (type.equals(CloseWorkbenchPartCommand.TYPE)) >+ command = new CloseWorkbenchPartCommand(commandShell); >+ >+ /* Mouse events */ >+ else if (type.equals(MouseEventCommand.MOUSE_UP) >+ || type.equals(MouseEventCommand.MOUSE_DOWN) >+ || type.equals(MouseEventCommand.MOUSE_MOVE) >+ || type.equals(MouseEventCommand.MOUSE_CLICK)) >+ command = new MouseEventCommand(commandShell); >+ >+ /* Key events */ >+ else if (type.equals(KeyEventCommand.KEY_UP) >+ || type.equals(KeyEventCommand.KEY_DOWN) >+ || type.equals(KeyEventCommand.KEY_PRESS)) >+ command = new KeyEventCommand(commandShell); >+ >+ return command; >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/IMacroCommandFactory.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/IMacroCommandFactory.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/IMacroCommandFactory.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/IMacroCommandFactory.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,56 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.commands.factory; >+ >+import java.util.ArrayList; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+ >+/** >+ * Factory to create commands to record certain events or to create respective commands during playback >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public interface IMacroCommandFactory { >+ >+ /** >+ * Factory method to create a new IMacroCommand during recording. This >+ * method is called by the command shell for every event it processes. >+ * Multiple calls to this method for succeeding events may be necessary, >+ * before an event is actually created and returned). >+ * >+ * @param commandShell >+ * @param commands >+ * @param event >+ * @return >+ * @throws CoreException >+ */ >+ public IMacroCommand createCommand(MacroCommandShell commandShell, >+ ArrayList commands, Event event) throws CoreException; >+ >+ >+ /** >+ * Factory method to create a command instance for a certain command type. This >+ * method is called during playback to obtain a command that can then be played-back. >+ * >+ * @param commandShell >+ * @param type >+ * @return >+ * @throws CoreException >+ */ >+ public IMacroCommand createCommand(MacroCommandShell commandShell, String type) throws CoreException; >+ >+} >Index: schema/uiObjectResolverDelegate.exsd >=================================================================== >RCS file: schema/uiObjectResolverDelegate.exsd >diff -N schema/uiObjectResolverDelegate.exsd >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ schema/uiObjectResolverDelegate.exsd 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,137 @@ >+<?xml version='1.0' encoding='UTF-8'?> >+<!-- Schema file written by PDE --> >+<schema targetNamespace="org.eclipse.tptp.test.auto.gui" xmlns="http://www.w3.org/2001/XMLSchema"> >+<annotation> >+ <appinfo> >+ <meta.schema plugin="org.eclipse.tptp.test.auto.gui" id="uiObjectResolverDelegate" name="uiObjectResolverDelegate"/> >+ </appinfo> >+ <documentation> >+ Use this extension to define a class that is capable of resolving widgets and nested objects on them. >+ </documentation> >+ </annotation> >+ >+ <element name="extension"> >+ <annotation> >+ <appinfo> >+ <meta.element /> >+ </appinfo> >+ <documentation> >+ The following internal extension provides the mean for defining custom widget resolvers. >+ </documentation> >+ </annotation> >+ <complexType> >+ <sequence> >+ <element ref="uiObjectResolverDelegate" minOccurs="1" maxOccurs="unbounded"/> >+ </sequence> >+ <attribute name="point" type="string" use="required"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="id" type="string"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="name" type="string"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ <appinfo> >+ <meta.attribute translatable="true"/> >+ </appinfo> >+ </annotation> >+ </attribute> >+ </complexType> >+ </element> >+ >+ <element name="uiObjectResolverDelegate"> >+ <complexType> >+ <attribute name="class" type="string" use="required"> >+ <annotation> >+ <documentation> >+ The class that is invoked to resolve a widget or a nested object on a widget. >+Must implement the following interface: org.eclipse.tptp.test.auto.gui.uiObject.resolver.delegate.IUIObjectResolverDelegate >+ </documentation> >+ <appinfo> >+ <meta.attribute kind="java" basedOn="org.eclipse.tptp.test.auto.gui.uiObject.resolver.delegate.IUIObjectResolverDelegate"/> >+ </appinfo> >+ </annotation> >+ </attribute> >+ <attribute name="priority" type="string" use="required"> >+ <annotation> >+ <documentation> >+ This attribute indicates the priority of the resolver delegate relative to the other registered widget resolvers. UIObjectResolverDelegats are invoked in an descending order of their priority (e.g. The resolver delegate with the highest priority attribute will be invoked first). >+The value of this attribute is expected to be an integer >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="id" type="string" use="required"> >+ <annotation> >+ <documentation> >+ The unique id of the resolver. Keeps this id short as it is commonly used in a macro. The suggested format is CONTRIBUTING_PLUGIN_ID.RESOLVER_NAME e.g. org.eclipse.tptp.test.auto.gui.adaptive. >+ </documentation> >+ </annotation> >+ </attribute> >+ </complexType> >+ </element> >+ >+ <annotation> >+ <appinfo> >+ <meta.section type="since"/> >+ </appinfo> >+ <documentation> >+ Since TPTP v4.5 >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appinfo> >+ <meta.section type="examples"/> >+ </appinfo> >+ <documentation> >+ <!-- Define a UI object resolver delegate with priority 10 --> >+ <extension >+ point="org.eclipse.tptp.test.auto.gui.uiObjectResolverDelegate"> >+ <widgetResolver >+ id = "org.eclipse.tptp.test.auto.gui.adaptive" >+ class="org.eclipse.tptp.test.auto.gui.internal.recorder.AdaptiveWidgetResolver" >+ priority="10" >+ /> >+ </extension> >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appinfo> >+ <meta.section type="apiInfo"/> >+ </appinfo> >+ <documentation> >+ [Enter API information here.] >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appinfo> >+ <meta.section type="implementation"/> >+ </appinfo> >+ <documentation> >+ [Enter information about supplied implementation of this extension point.] >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appinfo> >+ <meta.section type="copyright"/> >+ </appinfo> >+ <documentation> >+ Copyright (c) 2005, 2006 IBM Corporation and others. 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 <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> >+ </documentation> >+ </annotation> >+ >+</schema> >Index: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIMacroObjectDescriptorMineTreeStructure.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIMacroObjectDescriptorMineTreeStructure.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIMacroObjectDescriptorMineTreeStructure.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIMacroObjectDescriptorMineTreeStructure.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,510 @@ >+/******************************************************************************* >+ * Copyright (c) 2006, 2008 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.editor; >+ >+import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Iterator; >+import java.util.List; >+ >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.emf.ecore.EStructuralFeature; >+import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >+import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil; >+import org.eclipse.hyades.test.common.util.XMLUtil; >+import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter; >+import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider; >+import org.eclipse.hyades.ui.editor.IEditorExtension; >+import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider; >+import org.eclipse.jface.action.Action; >+import org.eclipse.jface.action.IMenuManager; >+import org.eclipse.jface.dialogs.IDialogConstants; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.jface.viewers.IContentProvider; >+import org.eclipse.jface.viewers.ILabelProvider; >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.Viewer; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >+import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >+import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestSuiteDialog; >+import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MessageUIElement; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager; >+ >+/** >+ * Represents the object mine tree that is displayed in the test case page of >+ * the editor. >+ * >+ * @author Ali Mehregani >+ * @author Paul E. Slauenwhite >+ * @version March 7, 2008 >+ * @since July 10, 2006 >+ */ >+public class AutoGUIMacroObjectDescriptorMineTreeStructure extends >+ AutoGUIAbstractTreeStructure { >+ /** Represents the root element in the object mine tree */ >+ private static final RootUMacroObjectDescriptorMineTreeNode ROOT_ELEMENT = new RootUMacroObjectDescriptorMineTreeNode(); >+ >+ /** The test case form */ >+ private AutoGUITestCasesForm testCaseForm; >+ >+ /** The content provider */ >+ private ObjectMineTreeContentProvider contentProvider; >+ >+ /** The label provider */ >+ private ObjectMineLabelProvider labelProvider; >+ >+ /** >+ * The line number and offset relation. The index of the list represents the >+ * line number and the value is an object of type Integer[0] indicating the >+ * start and end offset >+ */ >+ private List lineOffsetRelation; >+ >+ /** The include object mine menu item */ >+ private IncludeObjectMineAction includeObjectMineAction; >+ >+ /** Change output menu item */ >+ private ChangeOutputAction changeOutputAction; >+ >+ /** Keeps track of the test suite used as input */ >+ private ITestSuite testSuiteInput; >+ >+ /** Stores any error that occurred while loading the object mine */ >+ private Object[] error; >+ >+ public AutoGUIMacroObjectDescriptorMineTreeStructure( >+ AutoGUITestCasesForm testCaseForm, IEditorExtension editorPart) { >+ super(editorPart, null); >+ this.testCaseForm = testCaseForm; >+ lineOffsetRelation = new ArrayList(); >+ includeObjectMineAction = new IncludeObjectMineAction(); >+ changeOutputAction = new ChangeOutputAction(); >+ } >+ >+ /** >+ * Overwrite this method so that a custom content provider can be registered >+ * with the tree >+ */ >+ protected IContentProvider createContentProvider() { >+ if (contentProvider == null) >+ contentProvider = new ObjectMineTreeContentProvider(editorPart, >+ getEStructuralFeature()); >+ return contentProvider; >+ } >+ >+ /** >+ * Overwrite this method so that a custom label provider can be registered >+ * with the tree >+ * >+ * @return The label provider for the object mine tree >+ */ >+ protected ILabelProvider createLabelProvider() { >+ if (labelProvider == null) >+ labelProvider = new ObjectMineLabelProvider( >+ TestWorkbenchAdapter.class); >+ return labelProvider; >+ } >+ >+ /** >+ * Overwrite this method so that custom buttons can be added beside the >+ * object mine tree. >+ */ >+ protected void adjustButtonLabels(String addLabel) { >+ setButtonLabels(new String[0]); >+ } >+ >+ /** >+ * Need to overwrite this method since there are no buttons whose status >+ * need to be updated. >+ */ >+ protected void updateActionsAndButtons( >+ IStructuredSelection structuredSelection) { >+ /* purposely left blank */ >+ } >+ >+ /** >+ * Refreshes the content of this tree by forcing the test suite to reload >+ * its object mine. >+ */ >+ public void refresh() { >+ MacroObjectDescriptorMineManager.getInstance().clearCache(); >+ loadObjectMine(testSuiteInput, false); >+ getTreeViewer().refresh(); >+ } >+ >+ public List getLineOffsetRelation() { >+ return lineOffsetRelation; >+ } >+ >+ /** >+ * Needs to be overwritten to modify the default tree style >+ */ >+ public int getTreeStryle() { >+ return super.getTreeStryle() | SWT.BORDER; >+ } >+ >+ private Object[] createErrorItem(String prefix, Exception e) { >+ Throwable cause = AutoGUIUtil.findCause(e); >+ prefix += prefix == null ? "" : ": "; >+ prefix += (cause.getMessage() == cause.getClass().getName() ? "" : " " >+ + cause.getMessage()); >+ prefix += ": " + e.getStackTrace()[0].getClassName() + ":" >+ + e.getStackTrace()[0].getLineNumber(); >+ return new Object[] { new MessageUIElement(IStatus.ERROR, prefix) }; >+ } >+ >+ /** >+ * Overwrite this method so that custom menu items can be added to the >+ * entries that are displayed in the object mine tree. >+ * >+ * @param menuManager >+ * The menu manager >+ */ >+ protected void fillContextMenu(IMenuManager menuManager) { >+ IStructuredSelection selection = getStructuredSelection(); >+ if (!selection.isEmpty() >+ && selection.size() == 1 >+ && selection.getFirstElement() instanceof RootUMacroObjectDescriptorMineTreeNode) { >+ menuManager.add(includeObjectMineAction); >+ menuManager.add(changeOutputAction); >+ } >+ } >+ >+ private MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite, >+ boolean showError) { >+ MacroObjectDescriptorMine input = null; >+ if (testSuite == null) { >+ testSuiteInput = null; >+ return null; >+ } >+ >+ try { >+ testSuiteInput = (ITestSuite) testSuite; >+ input = MacroObjectDescriptorMineManager.getInstance() >+ .loadObjectMine(testSuiteInput); >+ String objectMineXML = HyadesUtil.getTestSuiteVariable( >+ testSuiteInput, >+ GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE); >+ lineOffsetRelation = AutoGUIMacroObjectDescriptorMineTreeStructure.this >+ .findLineOffsetIndicator(objectMineXML); >+ error = null; >+ } catch (Exception e) { >+ if (showError) { >+ AutoGUIUtil.openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE + ": " >+ + testSuite.getName(), e); >+ } else { >+ error = createErrorItem( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, e); >+ } >+ >+ input = null; >+ } >+ >+ return input; >+ } >+ >+ /** >+ * The content provider for the object mine tree. >+ * >+ * @author Ali Mehregani >+ */ >+ private class ObjectMineTreeContentProvider extends >+ EObjectTreeContentProvider { >+ public ObjectMineTreeContentProvider(IEditorExtension editorPart, >+ EStructuralFeature eStructuralFeature) { >+ super(editorPart, eStructuralFeature); >+ } >+ >+ public Object[] getElements(Object inputElement) { >+ return new Object[] { ROOT_ELEMENT }; >+ } >+ >+ /** >+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) >+ */ >+ public Object[] getChildren(Object parentElement) { >+ MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput, >+ false); >+ if (input == null) { >+ if (parentElement == ROOT_ELEMENT && error != null) >+ return error; >+ } >+ >+ /* >+ * If the test suite doesn't have an object mine then return an >+ * empty list >+ */ >+ String objectMineXML = null; >+ if (testSuiteInput == null >+ || (objectMineXML = HyadesUtil.getTestSuiteVariable( >+ testSuiteInput, >+ GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE)) == null >+ || objectMineXML.length() <= 0) >+ return null; >+ >+ if (parentElement == ROOT_ELEMENT) { >+ return input.getChildren(); >+ } else if (parentElement instanceof MacroObjectDescriptor) { >+ return ((MacroObjectDescriptor) parentElement).getChildren(); >+ } >+ >+ return null; >+ } >+ >+ public boolean hasChildren(Object parentElement) { >+ MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput, >+ false); >+ if (parentElement == ROOT_ELEMENT) { >+ return input == null ? error != null >+ : input.getChildren().length > 0; >+ } else if (parentElement instanceof MacroObjectDescriptor) { >+ return ((MacroObjectDescriptor) parentElement).childCount() > 0; >+ } >+ >+ return false; >+ } >+ >+ /** >+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) >+ */ >+ public Object getParent(Object element) { >+ if (element instanceof MacroObjectDescriptor) { >+ MacroObjectDescriptor parent = ((MacroObjectDescriptor) element) >+ .getParent(); >+ return parent == null ? (Object) ROOT_ELEMENT : parent; >+ } >+ return null; >+ } >+ >+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { >+ if (!(newInput instanceof ITestSuite)) >+ return; >+ >+ loadObjectMine((ITestSuite) newInput, false); >+ >+ } >+ } >+ >+ private class ObjectMineLabelProvider extends WorkbenchAdapterLabelProvider { >+ >+ public ObjectMineLabelProvider(Class cl) >+ throws IllegalArgumentException { >+ super(cl); >+ } >+ >+ public String getText(Object element) { >+ if (element == ROOT_ELEMENT) { >+ return AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_MINE; >+ } else if (element instanceof MacroObjectDescriptor) { >+ String descriptiveField = ((MacroObjectDescriptor) element) >+ .getDescriptive(); >+ return descriptiveField == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_OBJECT >+ : XMLUtil.removeXMLSymbols(descriptiveField); >+ } else if (element instanceof MessageUIElement) { >+ String message = ((MessageUIElement) element).getText(); >+ return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE >+ : message; >+ } >+ >+ return MacroConstants.EMPTY_STRING; >+ } >+ >+ public Image getImage(Object element) { >+ if (element == ROOT_ELEMENT) { >+ return AutoGUIImages.getInstance().getImage( >+ AutoGUIImages.OBJECT_MINE); >+ } else if (element instanceof MacroObjectDescriptor) { >+ MacroObjectDescriptor parent = ((MacroObjectDescriptor) element) >+ .getParent(); >+ return parent == null ? AutoGUIImages.getInstance().getImage( >+ AutoGUIImages.SHELL) : AutoGUIImages.getInstance() >+ .getImage(AutoGUIImages.WIDGET); >+ } else if (element instanceof MessageUIElement) { >+ return ((MessageUIElement) element).getIcon(); >+ } >+ >+ return null; >+ } >+ } >+ >+ /** >+ * A dummy class that represents the root element in the object mine tree. >+ */ >+ private static class RootUMacroObjectDescriptorMineTreeNode { >+ } >+ >+ /** >+ * The include object mine action. The purpose of this action is to allow >+ * the user to include object mines under the test suite's object mine >+ * >+ * @author Ali Mehregani >+ */ >+ private class IncludeObjectMineAction extends Action { >+ /** >+ * Perform the action. >+ * >+ */ >+ public void run() { >+ /* Display the test suite list dialog */ >+ AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog( >+ GuiPlugin.getDefault().getWorkbench() >+ .getActiveWorkbenchWindow().getShell(), >+ testSuiteInput, >+ AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, false); >+ >+ if (autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID) >+ return; >+ >+ /* >+ * Get the selected test suites and include them as part of this >+ * test suite's object mine >+ */ >+ Collection tests = autoGUITestSuiteDialog.getTests(); >+ MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput, >+ true); >+ boolean markdirty = false; >+ for (Iterator testIterator = tests.iterator(); testIterator >+ .hasNext();) { >+ Object currentTestSuite = testIterator.next(); >+ if (!(currentTestSuite instanceof ITestSuite)) >+ continue; >+ >+ ITestSuite testSuite = (ITestSuite) currentTestSuite; >+ try { >+ MacroObjectDescriptorMine objectMine = MacroObjectDescriptorMineManager >+ .getInstance().loadObjectMine(testSuite); >+ if (objectMine != null >+ && !input.getIncludes().contains(objectMine)) { >+ markdirty = true; >+ input.addInclude(objectMine); >+ } >+ } catch (Exception e) { >+ /* Display an error */ >+ AutoGUIUtil >+ .openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_DIALOG_TST_INCL, >+ testSuite.getName()), e); >+ } >+ } >+ >+ if (markdirty) { >+ testCaseForm.updateTestProperty(null, >+ input.serializeToString(), true); >+ getTreeViewer().setSelection(getTreeViewer().getSelection()); >+ } >+ } >+ >+ public boolean isEnabled() { >+ return testSuiteInput != null; >+ } >+ >+ public String getText() { >+ return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_INCL; >+ } >+ >+ public ImageDescriptor getImageDescriptor() { >+ return AutoGUIImages.getInstance().getImageDescriptor("e", >+ AutoGUIImages.INCLUDE); >+ } >+ } >+ >+ /** >+ * This action changes the output of the object mine to another test suite. >+ * >+ * @author Ali Mehregani >+ */ >+ private class ChangeOutputAction extends Action { >+ /** >+ * Perform the action. >+ */ >+ public void run() { >+ /* Display the test suite list dialog */ >+ AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog( >+ GuiPlugin.getDefault().getWorkbench() >+ .getActiveWorkbenchWindow().getShell(), >+ testSuiteInput, >+ AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, true); >+ >+ if (autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID) >+ return; >+ >+ /* >+ * Get the selected test suites and include them as part of this >+ * test suite's object mine >+ */ >+ Collection tests = autoGUITestSuiteDialog.getTests(); >+ if (tests == null) >+ return; >+ >+ Object[] selectedTestContainer = tests.toArray(); >+ if (selectedTestContainer.length != 1 >+ || !(selectedTestContainer[0] instanceof ITestSuite)) >+ return; >+ >+ MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput, >+ true); >+ MacroObjectDescriptorMine oldOutputObjectMine = input >+ .getOutputSource(); >+ ITestSuite oldOutput = oldOutputObjectMine == null ? null >+ : oldOutputObjectMine.getOwner(); >+ ITestSuite newOutput = (ITestSuite) selectedTestContainer[0]; >+ if (oldOutput == null >+ || (!oldOutput.getId().equals(newOutput.getId()))) { >+ MacroObjectDescriptorMine objectMine = null; >+ try { >+ objectMine = MacroObjectDescriptorMineManager.getInstance() >+ .loadObjectMine(newOutput); >+ input.setOutputSource(objectMine); >+ testCaseForm.updateTestProperty(null, input >+ .serializeToString(), true); >+ getTreeViewer() >+ .setSelection(getTreeViewer().getSelection()); >+ } catch (Exception e) { >+ input.setOutputSource(null); >+ AutoGUIUtil >+ .openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, >+ newOutput.getName()), e); >+ } >+ } >+ } >+ >+ public boolean isEnabled() { >+ return testSuiteInput != null; >+ } >+ >+ public String getText() { >+ return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_OUPUT; >+ } >+ >+ public ImageDescriptor getImageDescriptor() { >+ return AutoGUIImages.getInstance().getImageDescriptor("e", >+ AutoGUIImages.OUTPUT); >+ } >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/SingleSelectionCommand.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/SingleSelectionCommand.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/SingleSelectionCommand.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/SingleSelectionCommand.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,30 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.commands; >+ >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell; >+ >+ >+/** >+ * @author Alexander Nyssen >+ * >+ */ >+public abstract class SingleSelectionCommand extends ObjectBasedCommand { >+ >+ /** >+ * @param parent >+ * @param widgetId >+ */ >+ public SingleSelectionCommand(MacroCommandShell parent) { >+ super(parent); >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/resolver/MacroObjectResolver.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/resolver/MacroObjectResolver.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/resolver/MacroObjectResolver.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/resolver/MacroObjectResolver.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,763 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.jface.action.CoolBarManager; >+import org.eclipse.jface.action.ICoolBarManager; >+import org.eclipse.jface.action.IMenuManager; >+import org.eclipse.jface.action.IToolBarManager; >+import org.eclipse.jface.action.MenuManager; >+import org.eclipse.jface.action.ToolBarManager; >+import org.eclipse.jface.window.ApplicationWindow; >+import org.eclipse.jface.wizard.IWizardPage; >+import org.eclipse.jface.wizard.WizardDialog; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.custom.CTabFolder; >+import org.eclipse.swt.custom.CTabItem; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Decorations; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.swt.widgets.ToolBar; >+import org.eclipse.swt.widgets.ToolItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.DeresolvingAmbiguityException; >+import org.eclipse.ui.IActionBars; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IViewPart; >+import org.eclipse.ui.IViewSite; >+import org.eclipse.ui.IWorkbenchPart; >+ >+/** >+ * Provides functionality to resolve a IMacroObject into an >+ * IMacroObjectIdentifier that can be persistently stored, and to deresolve an >+ * IMacroObjectIdentifier back into an IMacroObject. >+ * >+ * During resolving a context identifier for the context of the IMacroObject is >+ * computed and the resolving of the IUIObject nested inside the IMacroObject is >+ * delegated to the UIObjectResolver (the resulting IUIObjectIdentifier is then >+ * be nested into the returned IMacroObjectIdentifier). >+ * >+ * During deresolving the context object is first deresolved, then the IUIObject >+ * nested inside the IMacroObject is deresolved by delegating to the >+ * IUIObjectResolver again. >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public final class MacroObjectResolver { >+ >+ /** >+ * Resolve a IMacroObject into an IMacroObjectIdentifier representation, >+ * that can be persistently stored and that allows to deresolve the >+ * IMacroObject during playback. Delegates to UIObjectResolver's resolve() >+ * method to obtain the IUIObjectIdentifier part of the >+ * IMacroObjectIdentifier >+ * >+ * @param macroObject >+ * @return >+ */ >+ public static IMacroObjectIdentifier resolve(Shell shell, >+ IMacroObject macroObject) throws CoreException { >+ // retrieve the context id of the UI object >+ >+ // compute a context identifier based on the context object of the >+ // macroObject >+ String contextIdentifier = resolveContextIdentifier(shell, macroObject); >+ >+ // compute the object id by delegating to the UIObjectResolver >+ IUIObjectIdentifier uiObjectIdentifier = UIObjectResolver.resolve( >+ macroObject.getContext(), macroObject.getUIObject()); >+ >+ IMacroObjectIdentifier identifier = null; >+ // compute the object id and build a new MacroObjectIdentifier from both >+ if (contextIdentifier != null && uiObjectIdentifier != null) { >+ // identifier = new MacroObjectIdentifier(contextIdentifier, >+ // uiObjectIdentifier); >+ identifier = checkAnfFixUnambiguousIdentifier(shell, macroObject, >+ new MacroObjectIdentifier(contextIdentifier, >+ uiObjectIdentifier)); >+ } >+ return identifier; >+ } >+ >+ /** >+ * This method implements a workaround for defect #147766. It checks whether >+ * the provided IMacroObject can be unambiguously deresolved by using the >+ * provided IMacroObjectIdentifier. >+ * >+ * As detection of deresolving ambiguities is limited to Control instances, >+ * this method does only have an effect, if the passed in macro object >+ * contains a control as the widget of its nested UI object. >+ * >+ * If the passed in IMacroObjectIdentifier is ambiguous, an index is added >+ * to the widget id of the nested UIObjectIdnentifier to ensure unambiguity >+ * during deresolving (the locateVisibleChild() method of the >+ * UIObjectDeprecatedDeresolvingSupport class handles this case). If the >+ * passed in IMacroObjectIdentifier is unambiguous or the deresolving did >+ * fail because of any other reason, this method does not have any effect >+ * and simply returns the passed in IMacroObjectIdentifier. >+ */ >+ private static IMacroObjectIdentifier checkAnfFixUnambiguousIdentifier( >+ Shell shell, IMacroObject macroObject, >+ IMacroObjectIdentifier macroObjectIdentifier) throws CoreException { >+ try { >+ // ANy: IMPORTANT: I observed that in case of MenuItems, deresolving >+ // during recording causes the widget to get disposed as a >+ // side-effect. >+ // Also because of this, limiting the check to Control instances is >+ // necessary. >+ if (macroObject.getUIObject().getWidget() instanceof Control) { >+ deresolve(shell, new MacroObjectIdentifier( >+ macroObjectIdentifier.getContextIdentifier(), >+ macroObjectIdentifier.getObjectIdentifier())); >+ } >+ } catch (Throwable t) { >+ // ANy: IMPORTANT: In case we get a core exception we have to check >+ // if >+ // ambiguity of the passed in identifier was the reason. >+ if (t instanceof CoreException >+ && ((CoreException) t).getCause() instanceof DeresolvingAmbiguityException) { >+ // provide a workaround by adding a respective >+ // identifier suffix to identify the desired match >+ IUIObjectIdentifier unambiguousUIObjectIdentifier = computeUnambigousUIObjectIdentifier( >+ macroObject.getContext(), macroObject.getUIObject(), >+ macroObjectIdentifier.getObjectIdentifier(), >+ ((DeresolvingAmbiguityException) ((CoreException) t) >+ .getCause()).getNumberOfMatches()); >+ if (unambiguousUIObjectIdentifier != null) { >+ // if we were successful, return the new - now unambiguous - >+ // identifier. >+ return new MacroObjectIdentifier(macroObjectIdentifier >+ .getContextIdentifier(), >+ unambiguousUIObjectIdentifier); >+ } else { >+ // throw an exception to notify the user. >+ AutoGUIUtil >+ .throwCoreException( >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS, >+ macroObjectIdentifier >+ .getObjectIdentifier() >+ .getWidgetId(), >+ macroObjectIdentifier >+ .getObjectIdentifier() >+ .getObjectId()), t >+ .getCause()); >+ return null; >+ } >+ } else { >+ // All other reasons are ignored here, so return the passed in >+ // macro object identifier. >+ return macroObjectIdentifier; >+ } >+ } >+ // if no exeption is thrown, the deresolving worked, so return the >+ // passed in macro object identifier. >+ return macroObjectIdentifier; >+ } >+ >+ private static IUIObjectIdentifier computeUnambigousUIObjectIdentifier( >+ Object context, IUIObject uiObject, >+ IUIObjectIdentifier ambigousIdentifier, int numberOfMatches) { >+ IUIObjectIdentifier unambigousIdentifier = null; >+ // check each match to see which one is the desired target >+ for (int i = 0; i < numberOfMatches && unambigousIdentifier == null; i++) { >+ try { >+ String uniqueWidgetId = ambigousIdentifier >+ .getWidgetId() >+ .concat( >+ MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR >+ + new Integer(i).toString()); >+ IUIObjectIdentifier modifiedUIObjectIdentifier = new PrimitiveUIObjectIdentifier( >+ uniqueWidgetId, ambigousIdentifier.getObjectId(), >+ ambigousIdentifier.getResolverId()); >+ IUIObject deresolvedUIObject = UIObjectResolver.deresolve( >+ context, modifiedUIObjectIdentifier); >+ if (deresolvedUIObject != null >+ && deresolvedUIObject.getWidget() == uiObject >+ .getWidget()) { >+ unambigousIdentifier = modifiedUIObjectIdentifier; >+ } >+ } catch (Throwable t) { >+ } >+ } >+ return unambigousIdentifier; >+ } >+ >+ private static String resolveContextIdentifier(Shell shell, >+ IMacroObject macroObject) throws CoreException { >+ Widget widget = macroObject.getUIObject().getWidget(); >+ if (widget instanceof MenuItem) { >+ if (macroObject.getContext() instanceof Menu) { >+ IViewPart view = null; >+ if (MacroUtil.onMenubar((MenuItem) widget)) { >+ return new Path(MacroConstants.MENUS_VALUE).toString(); //$NON-NLS-1$ >+ } else if ((view = MacroUtil >+ .onWorkbenchPartToolbar((MenuItem) widget)) != null) { >+ return new Path(MacroConstants.LOCAL_TOOLBAR_MENU_VALUE) >+ .append( >+ new Path(MacroConstants.VIEW_VALUE) >+ .append(view.getSite().getId())) >+ .toString(); >+ } >+ return null; >+ >+ } else if (macroObject.getContext() instanceof Control) { >+ IMacroObjectIdentifier focusControlIdentifier = resolve(shell, >+ new MacroObject(new UIObject((Control) macroObject >+ .getContext()))); >+ if (focusControlIdentifier == null) { >+ return null; >+ } else { >+ // the context id of a popup menu item is the concatenation >+ // of the >+ // MacroConstants.POPUP_VALUE keyword followed by the >+ // IMacroObjectIdentifier >+ // of the focus control >+ return new Path(MacroConstants.POPUP_VALUE) >+ .append( >+ MacroObjectIdentifier >+ .serializeMacroObjectIdentifier(focusControlIdentifier)) >+ .toString(); //$NON-NLS-1$ >+ } >+ } >+ return null; >+ } else if (widget instanceof ToolItem) { >+ /* >+ * Check to see if this toolbar belongs to the global toolbar of the >+ * workbench >+ */ >+ if (macroObject.getContext() instanceof IToolBarManager >+ || macroObject.getContext() instanceof ICoolBarManager) { >+ // global toolbar of the workbench >+ return new Path(MacroConstants.TOOLBAR_VALUE).toString(); //$NON-NLS-1$ >+ } else if (macroObject.getContext() instanceof ToolBar) { >+ // Local toolbar somewhere - locate the parent first and use its >+ // IMacroObjectIdentifier as >+ // context, as in case of the LOCAL_TOOLBAR_MENU_VALUE >+ ToolBar toolBar = (ToolBar) macroObject.getContext(); >+ IMacroObjectIdentifier toolBarIdentifier = resolve(shell, >+ new MacroObject(new UIObject(toolBar))); >+ if (toolBarIdentifier != null) { >+ return new Path(MacroConstants.LOCAL_TOOLBAR_VALUE) >+ .append( >+ MacroObjectIdentifier >+ .serializeMacroObjectIdentifier(toolBarIdentifier)) >+ .toString(); //$NON-NLS-1$ >+ } else { >+ return null; >+ } >+ } else { >+ return null; >+ } >+ } else if (widget instanceof TabItem || widget instanceof CTabItem) { >+ IMacroObjectIdentifier tabFolderIdentifier = null; >+ if (widget instanceof TabItem) { >+ TabFolder tabFolder = (TabFolder) macroObject.getContext(); >+ tabFolderIdentifier = resolve(shell, new MacroObject( >+ new UIObject(tabFolder))); >+ } else { >+ CTabFolder tabFolder = (CTabFolder) macroObject.getContext(); >+ tabFolderIdentifier = resolve(shell, new MacroObject( >+ new UIObject(tabFolder))); >+ } >+ if (tabFolderIdentifier != null) { >+ return new Path(MacroConstants.TAB_VALUE) >+ .append( >+ MacroObjectIdentifier >+ .serializeMacroObjectIdentifier(tabFolderIdentifier)) >+ .toString(); >+ } >+ >+ } else if (widget instanceof Menu) { >+ // it seems that menus are never resolved (as the deresolver does >+ // not have any capability to deresolve them) >+ AutoGUIUtil >+ .throwCoreException("Menus are not suppported by current implementation"); >+ // return new Path(MacroConstants.MENUS_VALUE).toString(); >+ } else if (widget instanceof Control) { >+ return resolveControlContextIdentifier(macroObject); >+ } >+ return null; >+ } >+ >+ private static String resolveControlContextIdentifier( >+ IMacroObject macroObject) { >+ if (macroObject.getContext() instanceof WizardDialog) { >+ return new Path(MacroConstants.WIZARD_VALUE).toString(); >+ } else if (macroObject.getContext() instanceof IWizardPage) { >+ return new Path(MacroConstants.WIZARD_PAGE_VALUE).append( >+ ((IWizardPage) macroObject.getContext()).getName()) >+ .toString(); >+ } else if (macroObject.getContext() instanceof IWorkbenchPart) { >+ IWorkbenchPart part = (IWorkbenchPart) macroObject.getContext(); >+ if (part instanceof IViewPart) { >+ return new Path(MacroConstants.VIEW_VALUE).append( >+ part.getSite().getId()).toString(); >+ } else if (part instanceof IEditorPart) { >+ String inputName = ((IEditorPart) part).getEditorInput() >+ .getName(); >+ return new Path(MacroConstants.EDITOR_VALUE).append( >+ part.getSite().getId()).append(inputName).toString(); >+ } else { >+ return null; >+ } >+ } else if (macroObject.getContext() instanceof Shell) { >+ return new Path(MacroConstants.SHELL_VALUE).toString(); >+ } else { >+ return null; >+ } >+ } >+ >+ /** >+ * TODO: split deresolving of context object from deresolving of UI object, >+ * which has to be done by UIObjectResolver.... >+ * >+ * @param shell >+ * @param macroObjectIdentifier >+ * @param parents >+ * @return >+ * @throws CoreException >+ */ >+ public static IMacroObject deresolve(Shell shell, >+ IMacroObjectIdentifier macroObjectIdentifier) throws CoreException { >+ String contextId = macroObjectIdentifier.getContextIdentifier(); >+ >+ String firstToken = new Path(contextId).segment(0); >+ String id = new Path(contextId).segment(1); >+ >+ Object context = null; >+ >+ if (MacroConstants.MENUS_VALUE.equals(firstToken)) { >+ context = findMenuContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.POPUP_VALUE.equals(firstToken)) { >+ context = findPopupMenuItemContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.TOOLBAR_VALUE.equals(firstToken)) { >+ context = findToolItemContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.LOCAL_TOOLBAR_VALUE.equals(firstToken)) { >+ context = findLocalToolItemContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.LOCAL_TOOLBAR_MENU_VALUE.equals(firstToken)) { >+ context = findToolBarMenuItemContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.TAB_VALUE.equals(firstToken)) { >+ // ANy: added to properly deresolve TabItems and CTabItems (was done >+ // locally by commands before) >+ context = findTabItemContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.WIZARD_VALUE.equals(firstToken)) { >+ context = findWizardContext(shell, macroObjectIdentifier); >+ } else if (MacroConstants.WIZARD_PAGE_VALUE.equals(firstToken)) { >+ context = findWizardPageContext(shell, id, macroObjectIdentifier); >+ } else if (MacroConstants.VIEW_VALUE.equals(firstToken)) { >+ context = findViewContext(shell, id, macroObjectIdentifier); >+ } else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) { >+ String inputName = new Path(contextId).segment(2); >+ context = findEditorContext(shell, id, inputName, >+ macroObjectIdentifier); >+ } else if (MacroConstants.SHELL_VALUE.equals(firstToken)) { >+ context = shell; >+ } >+ // else if (MacroConstants.LOCAL_SHELL_VALUE.equals(firstToken)) { >+ // context = shell.getData(); >+ // } >+ >+ if (context != null) { >+ IUIObject uiObject = UIObjectResolver.deresolve(context, >+ macroObjectIdentifier.getObjectIdentifier()); >+ if (uiObject != null) { >+ return new MacroObject(context, uiObject); >+ } else { >+ return null; >+ } >+ } >+ return null; >+ } >+ >+ private static Object findTabItemContext(Shell shell, >+ IMacroObjectIdentifier macroObjectIdentifier) throws CoreException { >+ IPath contextPath = new Path(macroObjectIdentifier >+ .getContextIdentifier()).removeFirstSegments(1); >+ >+ IMacroObjectIdentifier tabFolderIdentifier = MacroObjectIdentifier >+ .deserializeMacroObjectIdentifier(contextPath.toString()); >+ IMacroObject tabFolder = deresolve(shell, tabFolderIdentifier); >+ >+ if (tabFolder != null) { >+ return tabFolder.getUIObject().getWidget(); >+ } >+ return null; >+ } >+ >+ private static Object findEditorContext(Shell shell, String id, >+ String inputName, IMacroObjectIdentifier wid) throws CoreException { >+ UIObject control = null; >+ >+ try { >+ IEditorPart editor = MacroUtil.locateEditor(shell, id, inputName); >+ return editor; >+ } catch (Throwable t) { >+ t.printStackTrace(); >+ } >+ return null; >+ } >+ >+ private static Object findLocalToolItemContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ // construct a IMacroObjectIdentifier for the toolbar >+ // by splitting the context id. >+ >+ // 1) truncate the leading MacroConstants.LOCAL_TOOLBAR_MENU_VALUE >+ // segment >+ IPath wpath = new Path(wid.getContextIdentifier()) >+ .removeFirstSegments(1); >+ >+ IMacroObjectIdentifier toolBarIdentifier = MacroObjectIdentifier >+ .deserializeMacroObjectIdentifier(wpath.toString()); >+ >+ // now try to deresolve the toolbar with the given identifier >+ ToolBar toolbar = null; >+ try { >+ IMacroObject toolbarObject = deresolve(shell, toolBarIdentifier); >+ if (toolbarObject != null) { >+ toolbar = (ToolBar) toolbarObject.getUIObject().getWidget(); >+ } >+ } catch (Throwable t) { >+ t.printStackTrace(); >+ } >+ return toolbar; >+ // try{ >+ // String firstToken = wpath.segment(0); >+ // IWorkbenchPart workbenchPart = null; >+ // Composite parent = null; >+ // IMacroObject target = null; >+ // >+ // if (MacroConstants.VIEW_VALUE.equals(firstToken)) { >+ // String id = wpath.segment(1); >+ // workbenchPart = MacroUtil.locateView(shell, id); >+ // } else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) { >+ // String id = wpath.segment(1); >+ // workbenchPart = MacroUtil.locateEditor(shell, id, null); >+ // } else if (MacroConstants.SHELL_VALUE.equals(firstToken)) { >+ // parent = shell; >+ // } >+ // >+ // if (workbenchPart != null) { >+ // Composite comp = MacroUtil >+ // .getWorkbenchPartControl(workbenchPart); >+ // MacroUtil.processDisplayEvents(shell.getDisplay()); >+ // parent = comp.getParent(); >+ // } >+ // >+ // if (parent != null) { >+ // IMacroObjectIdentifier widgetIdentifier = new MacroObjectIdentifier( >+ // wid.getContextIdentifier(), >+ // new PrimitiveUIObjectIdentifier(new Path(wid >+ // .getContextIdentifier()).lastSegment(), wid >+ // .getObjectIdentifier().getResolverId())); >+ // UIObject control = UIObjectDeprecatedDeresolvingSupport >+ // .locateVisibleChild(parent, null, widgetIdentifier); >+ // >+ // if (control != null && control.getWidget() instanceof ToolBar) { >+ // target = locateToolItem((ToolBar) control.getWidget(), wid); >+ // } >+ // } >+ // >+ // if (target != null) >+ // return target; >+ // >+ // } catch (Throwable t) { >+ // /* The next line will throw an exception */ >+ // t.printStackTrace(); >+ // } >+ // >+ // AutoGUIUtil.throwCoreException(NLS.bind( >+ // AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR, wid >+ // .getContextIdentifier() >+ // + wid.getObjectIdentifier().getObjectId())); >+ // return null; >+ } >+ >+ private static Object findMenuContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ Menu menuBar = shell.getMenuBar(); >+ return menuBar; >+ } >+ >+ // private static MenuItem locateMenuItem(MenuManager mng, >+ // IMacroObjectIdentifier widgetId) { >+ // IContributionItem[] items = mng.getItems(); >+ // >+ // String lastSegment = getLastSegment(new >+ // Path(widgetId.getObjectIdentifier().getObjectId())); >+ // String parentId = null; >+ // >+ // for (int i = 0; i < items.length; i++) { >+ // IContributionItem citem = items[i]; >+ // >+ // if (citem instanceof MenuManager) { >+ // MenuManager submenu = (MenuManager) citem; >+ // String subId = submenu.getId(); >+ // >+ // if (subId.equals(parentId)) >+ // { >+ // >+ // // show this menu to force dynamic items >+ // // to show >+ // Menu menu = submenu.getMenu(); >+ // forceMenuOpen(null, menu); >+ // >+ // MenuItem hit = locateMenuItem(submenu, widgetId); >+ // forceMenuClosed(menu); >+ // if (hit != null) >+ // return hit; >+ // } >+ // >+ // } else { >+ // /* >+ // * Ali M.: I believe that the first line and the following block >+ // * were for optimization purposes only >+ // */ >+ // String itemId = >+ // NonTrivialUIObjectResolverDelegate.getActionId(citem).getObjectId(); >+ // if (itemId != null && >+ // widgetId.getObjectIdentifier().getObjectId().equals(itemId)) { >+ // MenuItem hit = locateMenuItem(mng.getMenu(), widgetId); >+ // if (hit != null) >+ // return hit; >+ // } >+ // } >+ // } >+ // return null; >+ // } >+ >+ private static Object findPopupMenuItemContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ // try { >+ >+ IPath contextPath = new Path(wid.getContextIdentifier()) >+ .removeFirstSegments(1); >+ >+ IMacroObjectIdentifier focusControlIdentifier = MacroObjectIdentifier >+ .deserializeMacroObjectIdentifier(contextPath.toString()); >+ IMacroObject focusControlObject = deresolve(shell, >+ focusControlIdentifier); >+ >+ if (focusControlObject != null) { >+ Control control = (Control) focusControlObject.getUIObject() >+ .getWidget(); >+ Menu popupMenu = control.getMenu(); >+ return popupMenu; >+ } else { >+ return null; >+ } >+ >+ // IPath wpath = new Path(getLastSegment(contextPath)); >+ // >+ // int widgetPathInx = contextPath.toString() >+ // .indexOf(wpath.toString()); >+ // if (widgetPathInx > 0) >+ // contextPath = new Path(contextPath.toString().substring(0, >+ // widgetPathInx - 1)); >+ // IMacroObject target = deresolve(shell, new MacroObjectIdentifier( >+ // contextPath.toString(), new PrimitiveUIObjectIdentifier( >+ // wpath.toString(), null))); >+ // if (target != null) { >+ // // for (int i = 0; i < targets.length; i++) { >+ // Control control = (Control) target.getUIObject().getWidget(); >+ // Menu popupMenu = control.getMenu(); >+ // if (popupMenu != null) { >+ // MacroUtil.forceMenuOpen(popupMenu); >+ // UIObject menuItem = locateMenuItem(popupMenu, wid >+ // .getObjectIdentifier()); >+ // MacroUtil.forceMenuClosed(popupMenu); >+ // if (menuItem != null) { >+ // return new MacroObject(control, menuItem); >+ // } >+ // } >+ // // } >+ // } >+ // } catch (Throwable t) { >+ // /* The next line will throw an exception */ >+ // t.printStackTrace(); >+ // } >+ // AutoGUIUtil.throwCoreException(NLS.bind( >+ // AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid >+ // .getObjectIdentifier().getObjectId())); >+ // return null; >+ } >+ >+ private static Object findToolBarMenuItemContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ // try { >+ IPath contextPath = new Path(wid.getContextIdentifier()) >+ .removeFirstSegments(1); >+ >+ /* The context is a menu */ >+ IViewPart view = null; >+ if (MacroConstants.VIEW_VALUE.equals(contextPath.segment(0))) { >+ view = MacroUtil.locateView(shell, contextPath.segment(1)); >+ } >+ >+ IViewSite viewSite = view == null ? null : view.getViewSite(); >+ IMenuManager menuManager = null; >+ if (viewSite != null) { >+ IActionBars actionBar = viewSite.getActionBars(); >+ actionBar.updateActionBars(); >+ menuManager = actionBar.getMenuManager(); >+ } >+ >+ if (menuManager != null && menuManager instanceof MenuManager) { >+ Menu menu = ((MenuManager) menuManager).getMenu(); >+ if (menu == null) { >+ // try to create menu >+ ((MenuManager) menuManager).createMenuBar((Decorations) view >+ .getSite().getShell()); >+ } >+ return menu; >+ } else { >+ return null; >+ } >+ } >+ >+ private static String getLastSegment(IPath contextPath) { >+ String[] segments = contextPath.segments(); >+ String candidate = ""; >+ for (int i = segments.length - 1; i >= 0; i--) { >+ if (candidate.length() > 0) >+ candidate = "/" + candidate; >+ candidate = segments[i] + candidate; >+ int openingBracesInx = candidate.indexOf('{'); >+ int closingBracesInx = candidate.indexOf('}'); >+ if ((openingBracesInx == -1 && closingBracesInx == -1) >+ || (openingBracesInx >= 0 && openingBracesInx < closingBracesInx)) >+ return candidate; >+ } >+ >+ return ""; >+ } >+ >+ // private static IMacroObject locateShellControl(Shell shell, >+ // IMacroObjectIdentifier wid) throws CoreException { >+ // UIObject control = null; >+ // Window window = null; >+ // boolean ambiguous = false; >+ // try { >+ // window = (Window) shell.getData(); >+ // control = UIObjectDeprecatedDeresolvingSupport.locateVisibleChild( >+ // shell, null, wid); >+ // } catch (Throwable t) { >+ // if (t instanceof CoreException) { >+ // AutoGUIUtil.throwCoreException(NLS.bind( >+ // AutoGUIMessages.AUTO_GUI_MACRO_UI_OBJECT_AMBIGUOUS, wid >+ // .getObjectIdentifier(), wid >+ // .getContextIdentifier())); >+ // } >+ // } >+ // if (control == null) >+ // AutoGUIUtil.throwCoreException(NLS.bind( >+ // AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL, wid >+ // .getObjectIdentifier().getObjectId())); >+ // >+ // // IMacroObject[] windowCommandTarget = new >+ // // IMacroObject[controls.length]; >+ // // for (int i = 0; i < controls.length; i++) { >+ // // if (controls[i].isDisposed()) >+ // // AutoGUIUtil.throwCoreException(NLS.bind( >+ // // AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid >+ // // .getObjectIdentifier().getObjectId())); >+ // // windowCommandTarget[i] = new MacroObject(window, new UIObject( >+ // // controls[i])); >+ // // } >+ // // >+ // // return windowCommandTarget; >+ // return new MacroObject(window, control); >+ // } >+ >+ private static Object findToolItemContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ >+ try { >+ Object data = shell.getData(); >+ if (data instanceof ApplicationWindow) { >+ ApplicationWindow window = (ApplicationWindow) data; >+ CoolBarManager coolMng = window.getCoolBarManager(); >+ if (coolMng != null) { >+ return coolMng; >+ } >+ ToolBarManager toolMng = window.getToolBarManager(); >+ if (toolMng != null) { >+ return toolMng; >+ } >+ } >+ } catch (Throwable t) { >+ t.printStackTrace(); >+ } >+ return null; >+ } >+ >+ private static Object findViewContext(Shell shell, String id, >+ IMacroObjectIdentifier wid) throws CoreException { >+ try { >+ IViewPart view = MacroUtil.locateView(shell, id); >+ return view; >+ } catch (Throwable t) { >+ t.printStackTrace(); >+ } >+ return null; >+ } >+ >+ private static Object findWizardContext(Shell shell, >+ IMacroObjectIdentifier wid) throws CoreException { >+ WizardDialog wdialog = null; >+ if (shell.getData() instanceof WizardDialog) { >+ wdialog = (WizardDialog) shell.getData(); >+ Assert >+ .isLegal( >+ wdialog.getShell() == shell, >+ "If the current shell is not the shell of the wizard, we have a deresolving problem"); >+ } >+ return wdialog; >+ } >+ >+ private static Object findWizardPageContext(Shell shell, String id, >+ IMacroObjectIdentifier wid) throws CoreException { >+ IWizardPage page = null; >+ Object data = shell.getData(); >+ if (data instanceof WizardDialog) { >+ WizardDialog wdialog = (WizardDialog) data; >+ page = wdialog.getCurrentPage(); >+ } >+ return page; >+ >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverToUIObjectResolverDelegateAdapter.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverToUIObjectResolverDelegateAdapter.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverToUIObjectResolverDelegateAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverToUIObjectResolverDelegateAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,48 @@ >+package org.eclipse.tptp.test.auto.gui.internal.core; >+ >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport; >+ >+public class WidgetResolverToUIObjectResolverDelegateAdapter implements >+ IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade { >+ >+ private IWidgetResolver widgetResolver = null; >+ >+ public WidgetResolverToUIObjectResolverDelegateAdapter(IWidgetResolver widgetResolver) { >+ super(); >+ this.widgetResolver = widgetResolver; >+ } >+ >+ public boolean foundWidget(Widget object, IUIObjectIdentifier objectId) { >+ return widgetResolver.foundWidget(object, objectId.getWidgetId()); >+ } >+ >+ public IUIObject deresolve(Object context, >+ IUIObjectIdentifier uiObjectIdentifier) throws CoreException { >+ return UIObjectDeprecatedDeresolvingSupport.deresolve(context, >+ uiObjectIdentifier); >+ } >+ >+ public IUIObjectIdentifier resolve(Object context, IUIObject uiObject) >+ throws CoreException { >+ >+ IWidgetId widgetId = null; >+ if(uiObject.getObject() == null){ >+ widgetId = widgetResolver.getUniqueId(uiObject.getWidget() instanceof Control ? ((Control)uiObject.getWidget()).getParent() : null, uiObject.getWidget()); >+ } >+ else{ >+ widgetId = widgetResolver.getUniqueId(uiObject.getWidget(), uiObject.getObject()); >+ } >+ return widgetId == null ? null : new PrimitiveUIObjectIdentifier(widgetId.toString(), widgetId.getResolverId()); >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptor.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptor.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,236 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine; >+ >+import java.util.ArrayList; >+import java.util.Hashtable; >+import java.util.LinkedList; >+import java.util.Map; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+ >+public class MacroObjectDescriptor { >+ >+ /** The context id */ >+ private String contextId; >+ >+ /** The widget id of the UI object being resolved */ >+ private String widgetId; >+ >+ /** The (optional) object id of the UI object to be resolved */ >+ private String objectId; >+ >+ /** The reference id of this object */ >+ private String referenceId; >+ >+ /** The descriptive attribute (a human readable identification) of this UI object */ >+ private String descriptive; >+ >+ /** Keeps track of the hierarchical relationship */ >+ private LinkedList hierarchicalRelation; >+ >+ /** The parent of this UI object */ >+ private MacroObjectDescriptor parent; >+ >+ /** The properties of this UI Object */ >+ private Hashtable properties; >+ >+ /** The id of the resolver that has resolved this object */ >+ private String resolverId; >+ >+ /** The children of this object */ >+ private ArrayList children; >+ >+ /** The associated data of this object */ >+ private Object data; >+ >+ /** >+ * Children indexed based on their reference id KEY = Reference id VALUE = MacroObjectDescriptor that is a child of this object >+ */ >+ private Hashtable idIndexedChildren; >+ >+ public MacroObjectDescriptor(MacroObjectDescriptor parent) { >+ this.parent = parent; >+ properties = new Hashtable(); >+ children = new ArrayList(); >+ idIndexedChildren = new Hashtable(); >+ } >+ >+ /** >+ * Creates an instace of this class based on a command passed in. >+ * >+ * @param objectMine >+ * The object mine that this object will be registered with >+ * @param command >+ * The command that this object will be based on >+ * @param parent >+ * The parent of this object >+ * >+ * @return An instance of this class based on widgetIdentifier >+ */ >+ public static MacroObjectDescriptor createInstance(ObjectBasedCommand command, MacroObjectDescriptor parent) { >+ IMacroObjectIdentifier macroObjectIdentifier = command.getMacroObjectIdentifier(); >+ MacroObjectDescriptor uiObject = new MacroObjectDescriptor(parent); >+ uiObject.setContextId(macroObjectIdentifier.getContextIdentifier() != null >+ ? macroObjectIdentifier.getContextIdentifier().toString() >+ : MacroConstants.EMPTY_STRING); >+ uiObject.setWidgetId(macroObjectIdentifier.getObjectIdentifier().getWidgetId()); >+ uiObject.setObjectId(macroObjectIdentifier.getObjectIdentifier().getObjectId()); >+ uiObject.setDescriptive(command.getDescriptiveField()); >+ uiObject.setResolver(macroObjectIdentifier.getObjectIdentifier().getResolverId()); >+ >+ return uiObject; >+ } >+ >+ public String getContextId() { >+ return contextId; >+ } >+ >+ public String getDescriptive() { >+ return descriptive; >+ } >+ >+ public LinkedList getHierarchicalRelation() { >+ if (hierarchicalRelation != null) >+ return hierarchicalRelation; >+ >+ hierarchicalRelation = new LinkedList(); >+ findHierarchicalRelation(this); >+ >+ return hierarchicalRelation; >+ } >+ >+ private void findHierarchicalRelation(MacroObjectDescriptor currentObject) { >+ if (currentObject == null) >+ return; >+ hierarchicalRelation.addFirst(currentObject); >+ findHierarchicalRelation(currentObject.getParent()); >+ } >+ >+ public String getObjectId(){ >+ return objectId; >+ } >+ >+ public void setObjectId(String objectId){ >+ this.objectId = objectId; >+ } >+ >+ public String getWidgetId() { >+ return widgetId; >+ } >+ >+ public Map getProperties() { >+ return properties; >+ } >+ >+ public String getProperty(String name) { >+ return (String) properties.get(name); >+ } >+ >+ public String getReferenceId() { >+ return referenceId; >+ } >+ >+ public void setContextId(String contextId) { >+ this.contextId = contextId; >+ } >+ >+ public void setDescriptive(String descriptive) { >+ this.descriptive = descriptive; >+ } >+ >+ public void setWidgetId(String id) { >+ this.widgetId = id; >+ } >+ >+ public void addProperty(String name, String value) { >+ properties.put(name, >+ value); >+ } >+ >+ public void setReferenceId(String referenceId) { >+ this.referenceId = referenceId; >+ } >+ >+ public MacroObjectDescriptor getParent() { >+ return parent; >+ } >+ >+ public void setParent(MacroObjectDescriptor parent) { >+ this.parent = parent; >+ } >+ >+ public String getResolverId() { >+ return resolverId; >+ } >+ >+ public void setResolver(String resolverId) { >+ this.resolverId = resolverId; >+ } >+ >+ public void addChild(MacroObjectDescriptor child) throws CoreException { >+ if (!children.contains(child)) { >+ try { >+ /* If there is a collision, then try to resolve it */ >+ int referenceId = Integer.parseInt(child.getReferenceId()); >+ while (idIndexedChildren.get(child.getReferenceId()) != null) { >+ referenceId++; >+ } >+ child.setReferenceId(String.valueOf(referenceId)); >+ } >+ catch (NumberFormatException nfe) { >+ /* Ignore the error */ >+ } >+ >+ /* If there is still a collision, then throw an exception */ >+ if (idIndexedChildren.get(child.getReferenceId()) != null) >+ AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, >+ child.getReferenceId())); >+ >+ idIndexedChildren.put(child.getReferenceId(), >+ child); >+ children.add(child); >+ } >+ } >+ >+ public int childCount() { >+ return children.size(); >+ } >+ >+ public MacroObjectDescriptor[] getChildren() { >+ MacroObjectDescriptor[] objects = new MacroObjectDescriptor[children.size()]; >+ children.toArray(objects); >+ return objects; >+ } >+ >+ public MacroObjectDescriptor removeChild(MacroObjectDescriptor child) { >+ children.remove(child); >+ return child; >+ } >+ >+ public Object getData() { >+ return data; >+ } >+ >+ public void setData(Object data) { >+ this.data = data; >+ } >+ >+ public MacroObjectDescriptor findChild(String referenceId) { >+ return (MacroObjectDescriptor) idIndexedChildren.get(referenceId); >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObjectIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObjectIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObjectIdentifier.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObjectIdentifier.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,42 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject; >+ >+ >+/** >+ * @author Alexander Nyssen >+ */ >+public interface IUIObjectIdentifier { >+ >+ /** >+ * Returns the id of the widget object to be identified >+ * >+ * @return The widget id >+ */ >+ public String getWidgetId(); >+ >+ /** >+ * Returns the id of the nested object to be identified on the respective widget, >+ * e.g. a String to name an item on a ComboBox. >+ * @return The id of the nested object >+ */ >+ public String getObjectId(); >+ >+ /** >+ * Returns the id of the ui object resolver delegate that generated this identifier. >+ * >+ * @return The id of the ui object resolver delegate that generated this identifier. >+ */ >+ public String getResolverId(); >+ >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMineManager.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMineManager.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMineManager.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMineManager.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,403 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine; >+ >+import java.io.ByteArrayInputStream; >+import java.io.IOException; >+import java.util.Hashtable; >+import java.util.List; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.emf.common.util.URI; >+import org.eclipse.emf.ecore.EObject; >+import org.eclipse.emf.ecore.resource.Resource; >+import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; >+import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil; >+import org.eclipse.hyades.test.core.util.EMFUtil; >+import org.eclipse.hyades.test.tools.ui.common.internal.util.FormUtil; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound; >+import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler; >+import org.w3c.dom.NamedNodeMap; >+import org.w3c.dom.Node; >+import org.w3c.dom.NodeList; >+import org.xml.sax.SAXException; >+ >+/** >+ * In addition to the macro of each test case, a test suite also contains an >+ * object mine keeps a reference of all resolved objects. The purpose of the >+ * object mine is to resolve a widget once and use it many times. >+ * >+ * This is a singleton class that can be accessed via <code>getInstance()</code> >+ * >+ * @author Ali Mehregani >+ */ >+public class MacroObjectDescriptorMineManager { >+ /** The instance of this class */ >+ private static MacroObjectDescriptorMineManager instance = new MacroObjectDescriptorMineManager(); >+ >+ /** >+ * Cached object mines KEY = Test suite id VALUE = An object of type >+ * MacroObjectDescriptorMine that represents the object mine of the test >+ * suite >+ */ >+ private Hashtable cachedObjectMines; >+ >+ /** >+ * Indicates whether a test suite's object mine is dirty or not KEY = test >+ * suite id VALUE = Boolean.TRUE if object mine is dirty; Boolean.FALSE >+ * otherwise >+ */ >+ private Hashtable dirtyStateTable; >+ >+ /** >+ * Restrict the visibility of the constructor >+ */ >+ private MacroObjectDescriptorMineManager() { >+ cachedObjectMines = new Hashtable(); >+ dirtyStateTable = new Hashtable(); >+ } >+ >+ /** >+ * Return the instance of this singleton class >+ * >+ * @return The instance of this class >+ */ >+ public static MacroObjectDescriptorMineManager getInstance() { >+ return instance; >+ } >+ >+ /** >+ * Load the object mine of the passed in test suite >+ * >+ * @param testSuite >+ * The test suite whose object mine is requested >+ * @param useCache >+ * Uses the cached value if this is set to true; otherwise the >+ * object mine is reloaded and returned. >+ * >+ * @return the object mine of the test suite that is passed in. >+ * >+ * @throws UIObjectNotFound >+ * In case an expected object is not found >+ * @throws IDCollisionException >+ * In case there is a collision id >+ * @throws CoreException >+ * In case of any unexpected error >+ */ >+ public MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite, >+ boolean useCache) throws UIObjectNotFound, IDCollisionException, >+ CoreException { >+ /* Is the object mine in cache? */ >+ String testSuiteId = testSuite.getId(); >+ MacroObjectDescriptorMine objectMine = null; >+ if (useCache >+ && (objectMine = (MacroObjectDescriptorMine) cachedObjectMines >+ .get(testSuiteId)) != null) { >+ objectMine.setOwner(testSuite); >+ return objectMine; >+ } >+ >+ /* >+ * Otherwise, it needs to be loaded. We need: - Get the object mine XML >+ * fragment - Parse it and load it >+ */ >+ String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuite, >+ GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE); >+ if (objectMineXML == null || objectMineXML.length() <= 0) { >+ /* Return a fresh object mine */ >+ objectMine = new MacroObjectDescriptorMine(testSuite, null); >+ } >+ >+ if (objectMine == null) { >+ objectMine = loadObjectMine(testSuite, objectMineXML); >+ } >+ >+ if (objectMine != null) { >+ cachedObjectMines.put(testSuiteId, objectMine); >+ } >+ >+ return objectMine; >+ } >+ >+ private MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite, >+ String objectMineXML) throws UIObjectNotFound, >+ IDCollisionException, CoreException { >+ if (objectMineXML == null || objectMineXML.length() <= 0) >+ return new MacroObjectDescriptorMine(testSuite, null); >+ >+ XMLDefaultHandler handler = null; >+ >+ try { >+ handler = MacroUtil.createXMLDocument(new ByteArrayInputStream( >+ objectMineXML.getBytes("UTF-8"))); >+ } catch (SAXException e) { >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >+ } catch (IOException e) { >+ AutoGUIUtil.throwCoreException( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e); >+ } >+ >+ /* Walk through the elemets and parse the document */ >+ Node rootElement = handler.getDocumentElement(); >+ NodeList children = rootElement.getChildNodes(); >+ >+ MacroObjectDescriptorMine objectMine = new MacroObjectDescriptorMine( >+ testSuite, handler); >+ for (int i = 0, childCount = children.getLength(); i < childCount; i++) { >+ Node currentChild = children.item(i); >+ String nodeName = currentChild.getNodeName(); >+ if (MacroConstants.HEADER_ELEMENT.equals(nodeName)) { >+ loadHeader(objectMine, currentChild); >+ } else if (MacroConstants.OBJECTS_ELEMENT.equals(nodeName)) { >+ loadObjects(objectMine, currentChild); >+ } >+ } >+ >+ return objectMine; >+ } >+ >+ /** >+ * This method should be used if the object mine will be loaded for reading >+ * purposes. Contributors will not be able to use this returned object mine >+ * to write any objects. >+ * >+ * @param objectMineXML >+ * The XML string representing the object mine >+ * >+ * @return the object mine of the test suite that is passed in. >+ * >+ * @throws UIObjectNotFound >+ * In case an expected object is not found >+ * @throws IDCollisionException >+ * In case there is a collision id >+ * @throws CoreException >+ * In case of any unexpected error >+ */ >+ public MacroObjectDescriptorMine loadObjectMine(String objectMineXML) >+ throws UIObjectNotFound, IDCollisionException, CoreException { >+ return loadObjectMine(null, objectMineXML); >+ } >+ >+ private void loadHeader(MacroObjectDescriptorMine objectMine, >+ Node headerNode) throws CoreException, UIObjectNotFound, >+ IDCollisionException { >+ /* Let's first read in the contribute attribute */ >+ NamedNodeMap attributes = headerNode.getAttributes(); >+ Node contributeAtt = attributes >+ .getNamedItem(MacroConstants.OUTPUT_ATTRIBUTE); >+ if (contributeAtt != null) { >+ ITestSuite testSuite = loadTestSuite(contributeAtt.getNodeValue()); >+ if (testSuite == null) { >+ AutoGUIUtil.openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUT_NF, null); >+ >+ } else { >+ try { >+ MacroObjectDescriptorMine outputObjectMine = MacroObjectDescriptorMineManager >+ .getInstance().loadObjectMine(testSuite); >+ objectMine.setOutputSource(outputObjectMine); >+ } catch (Exception e) { >+ objectMine.setOutputSource(null); >+ AutoGUIUtil >+ .openErrorWithDetail( >+ AutoGUIMessages.AUTO_GUI_COMMON_ERROR, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, >+ testSuite.getName()), e); >+ } >+ } >+ } >+ >+ /* Now load in all includes */ >+ NodeList children = headerNode.getChildNodes(); >+ for (int i = 0, childCount = children.getLength(); i < childCount; i++) { >+ Node currentChild = children.item(i); >+ String nodeName = currentChild.getNodeName(); >+ if (MacroConstants.INCLUDE_ELEMENT.equals(nodeName)) { >+ Node pathAttribute = currentChild.getAttributes().getNamedItem( >+ MacroConstants.PATH_ATTRIBUTE); >+ if (pathAttribute != null) { >+ ITestSuite testSuite = loadTestSuite(pathAttribute >+ .getNodeValue()); >+ MacroObjectDescriptorMine includedObjectMine = loadObjectMine(testSuite); >+ objectMine.addInclude(includedObjectMine); >+ } >+ } >+ } >+ } >+ >+ private void loadObjects(MacroObjectDescriptorMine objectMine, >+ Node objectsNode) throws CoreException, UIObjectNotFound, >+ IDCollisionException { >+ NodeList children = objectsNode.getChildNodes(); >+ registerObjects(objectMine, null, children); >+ } >+ >+ private void registerObjects(MacroObjectDescriptorMine objectMine, >+ MacroObjectDescriptor parent, NodeList children) >+ throws CoreException, UIObjectNotFound, IDCollisionException { >+ /* For every object */ >+ for (int i = 0, childCount = children.getLength(); i < childCount; i++) { >+ Node currentNode = children.item(i); >+ >+ NamedNodeMap attributes = currentNode.getAttributes(); >+ Node referenceIdNode = attributes >+ .getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE); >+ String referenceId = null; >+ if (referenceIdNode == null >+ || (referenceId = referenceIdNode.getNodeValue()) == null) { >+ Node widetIdAttribute = attributes >+ .getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE); >+ Node objectIdAttribute = attributes >+ .getNamedItem(MacroConstants.OBJECT_ID_ATTRIBUTE); >+ String widgetId = widetIdAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN >+ : widetIdAttribute.getNodeValue(); >+ String objectId = objectIdAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN >+ : objectIdAttribute.getNodeValue(); >+ AutoGUIUtil.throwCoreException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REF, >+ widgetId, objectId), 0); >+ } >+ >+ MacroObjectDescriptor guiObject = objectMine >+ .lookupMacroObjectDescriptor(parent, referenceId); >+ >+ /* Register the object if it's not yet registered */ >+ if (guiObject == null) { >+ guiObject = objectMine.registerObject(parent, currentNode); >+ } >+ /* Otherwise throw an exception if there is an id collision */ >+ else { >+ Node contextIdNode = attributes >+ .getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE); >+ Node widgetIdNode = attributes >+ .getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE); >+ Node objectIdNode = attributes >+ .getNamedItem(MacroConstants.OBJECT_ID_ATTRIBUTE); >+ String contextId = contextIdNode == null ? null : contextIdNode >+ .getNodeValue(); >+ String widgetId = widgetIdNode == null ? null : widgetIdNode >+ .getNodeValue(); >+ String objectId = objectIdNode == null ? null : objectIdNode >+ .getNodeValue(); >+ >+ if (((contextId == null && guiObject.getContextId() != null) || (contextId != null && !contextId >+ .equals(guiObject.getContextId()))) >+ || ((widgetId == null && guiObject.getWidgetId() != null) || (widgetId != null && !widgetId >+ .equals(guiObject.getWidgetId()))) >+ || ((objectId == null && guiObject.getObjectId() != null) || (objectId != null && !objectId >+ .equals(guiObject.getObjectId())))) { >+ throw new IDCollisionException(NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, >+ referenceId)); >+ } >+ } >+ >+ /* Load the children of this object */ >+ if (currentNode.getChildNodes().getLength() > 0) >+ registerObjects(objectMine, guiObject, currentNode >+ .getChildNodes()); >+ } >+ } >+ >+ private ITestSuite loadTestSuite(String testSuitePath) throws CoreException { >+ if (testSuitePath == null || testSuitePath.length() <= 0) >+ return null; >+ >+ IPath path = new Path(testSuitePath); >+ URI uri = URI.createPlatformResourceURI(path.toString()); >+ EObject[] eObjects = EMFUtil.getEObjects(uri, true); >+ return eObjects != null && eObjects.length > 0 >+ && eObjects[0] instanceof ITestSuite ? (ITestSuite) eObjects[0] >+ : null; >+ } >+ >+ public void writeObjectMine(MacroObjectDescriptorMine objectMine) { >+ writeObjectMine(objectMine, false); >+ } >+ >+ private void writeObjectMine(MacroObjectDescriptorMine objectMine, >+ boolean autoSave) { >+ ITestSuite testSuite = objectMine.getOwner(); >+ Resource testSuiteResource = ((EObject) testSuite).eResource(); >+ autoSave = autoSave >+ && (testSuiteResource != null && !testSuiteResource >+ .isModified()); >+ >+ String xmlSerialization = objectMine.serializeToString(); >+ HyadesUtil.setTestSuiteVariable(testSuite, >+ GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE, >+ xmlSerialization); >+ >+ if (autoSave) { >+ try { >+ EMFUtil.save(testSuiteResource); >+ } catch (Exception e) { >+ /* Shouldn't happen */ >+ e.printStackTrace(); >+ } >+ } >+ >+ /* >+ * We also need to update all object mines included by the object mine >+ * passed in >+ */ >+ List includes = objectMine.getIncludes(); >+ for (int i = 0, includeCount = includes.size(); i < includeCount; i++) { >+ MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes >+ .get(i); >+ writeObjectMine(currentObjectMine, true); >+ } >+ >+ dirtyStateTable.put(testSuite.getId(), Boolean.TRUE); >+ } >+ >+ public MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite) >+ throws UIObjectNotFound, IDCollisionException, CoreException { >+ Boolean dirtyState = (Boolean) dirtyStateTable.get(testSuite.getId()); >+ boolean isObjectMineDirty = dirtyState == null ? false : dirtyState >+ .booleanValue(); >+ dirtyStateTable.put(testSuite.getId(), Boolean.FALSE); >+ return loadObjectMine(testSuite, !isObjectMineDirty); >+ } >+ >+ /** >+ * Marks the object mine of the passed in test suite as dirty >+ * >+ * @param testSuite >+ * The test suite >+ */ >+ public void markObjectMineDirty(ITestSuite testSuite) { >+ if (testSuite == null) >+ return; >+ >+ dirtyStateTable.put(testSuite.getId(), Boolean.TRUE); >+ } >+ >+ /** >+ * Removes all entries in cache. This should be carefully used. >+ */ >+ public void clearCache() { >+ cachedObjectMines.clear(); >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/UIObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/UIObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/UIObject.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/UIObject.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,47 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject; >+ >+import org.eclipse.swt.widgets.Widget; >+ >+ >+/** >+ * Represents a widget or a nested object on a widget (e.g. a String item on a ComboBox) >+ * >+ * @author ANy >+ * @version $Revision$ >+ * >+ */ >+public class UIObject implements IUIObject { >+ >+ private Widget widget = null; >+ private Object object = null; >+ >+ public UIObject(Widget widget, Object object) { >+ super(); >+ this.widget = widget; >+ this.object = object; >+ } >+ >+ public UIObject(Widget widget) { >+ super(); >+ this.widget = widget; >+ } >+ >+ public Object getObject() { >+ return object; >+ } >+ >+ public Widget getWidget() { >+ return widget; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/DeresolvingAmbiguityException.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/DeresolvingAmbiguityException.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/DeresolvingAmbiguityException.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/DeresolvingAmbiguityException.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,32 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+/** >+ * Exception to indicate that multiple MacroObjects are found while deresolving an IMacroObjectIdentifier >+ * @author Alexander Nyssen >+ * >+ */ >+public class DeresolvingAmbiguityException extends Exception { >+ >+ private static final long serialVersionUID = 6617530463057206145L; >+ >+ private int numberOfMatches = 0; >+ >+ public DeresolvingAmbiguityException(int numberOfMatches) { >+ this.numberOfMatches = numberOfMatches; >+ } >+ >+ public int getNumberOfMatches(){ >+ return numberOfMatches; >+ } >+} >Index: CHANGES.txt >=================================================================== >RCS file: CHANGES.txt >diff -N CHANGES.txt >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ CHANGES.txt 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,59 @@ >+1) Total refactoring of the widget resolving mechanism: >+ >+ - The former widget resolving mechanism was totally revised. It now works as follows: IMacroObjects are resolved into IMacroObjectIdentifiers during recording in a two step process. >+ First, the context of the IMacroObject is resolved into a contextId (by a newly introduced MacroObjectResolver), then the nested UIObject (widget with optional nested object) is >+ resolved into a IUIObjectIdentifier (by a newly introduced UIObjectResolver), which contains the info formerly captured in a WidgetIdentifier (widgetId, resolverId, optional objectId). >+ During playback the deresolving of IMacroObjectIdentifiers is done in the same two step process. The MacroObjectResolver locates (deresolves) the context, and the UIObjectResolver >+ than locates the UIObject (under the given context). He delegates the resolving/deresolving of UIObjects/UIObjectIdentifiers to so called IUIObjectResolverDelegates, which are >+ loaded via a newly introduced extension point (which is a replacement of the former WigetResolver extension point). >+ >+ - Different to the old WidgetResolvers, the newly introduced IUIObjectResolverDelegates are responsible not only to resolve a respective IUIObjectIdentifier >+ for a given UIObject, but also to deresolve(i.e. relocating) a respective UIObject during playback (i.e. they take the second part of the two step deresolving mechanism). The old >+ WidgetResolvers were migrated to the new IUIObjectResolverDelegate interface. A DeprecatedDeresolvingSupport class was introduced to preserve the old implementation that >+ used the foundWidget method to relocated items. The WidgetIdentifier extension point was marked as deprecated. All extensions are loaded and adapterd dynamically to the new >+ UIObjectResolverDelegate interface by using DeprecatedDeresolvingSupport >+ >+ - The new resolving/deresolving mechanism relies on that the computed IMacroObjectIdentifier are unique, i.e. the desired UIObject can be unambiguously identified in its context during playback. >+ An exception is now thrown, if a recorded id cannot be unambiguously resolved. The old implementation contained a hack for bug#147766, which played back commands for all found matches >+ (or only the first one), which is not a valid solution. Consider the build.properties editor as an example. If checking an item of the SourceBuild-Tree during recording, the old >+ implementation would select the respectively named item in the BinaryBuild-Tree, as it plays the command for the first match. >+ I therefore propose to reopen bug#147766. It needs a proper fix that computes a unique IMacroObjectIdentifier for such tree items, so that during playback the single selected item >+ can be identified unambiguously. >+ >+ - All commands that relied on resolving/deresolving widgets (and nested objects) where migrated to have a common superclass ObjectBasedCommand. All those object-based commands >+ now rely on recording and playing back IMacroObjects. An IMacroObject (formerly CommandTarget) consists of a context and a UIObject, which is a widget or a nested object on >+ a widget (e.g. a String item on a ComboBox). >+ >+ - The listener registration for Workbench closing events was extracted from the resolving mechanism (was located as a side effect in MacroUtil.getWidgetIdentifier()), the resolving/deresolving >+ is now side-effect free. >+ >+2) Refactored ObjectMining. Renamed UIObject to MacroObjectDescriptor and ObjectMine into MacroObjectMine, UIObjectMineManager into MacroObjectManager to reflect what is actually stored in it. >+ - Refactored the identifier providing mechanism; a new MacroObjectDescriptor is now equipped with a unique id internally by the object mine when registering the object >+ - Removed the unneeded abstraction interface IUIObject (which is now used to represent a UIObject, i.e. a widget and a respective nested object) and unneeded corresponding IUIObjectMine interface. >+ >+4) Refactored VerficationCommand to be handled as all other object-based commands >+ - moved static construction method out changed constructor signature of Verification command to be in line with other object-based commands >+ - refactored loading/writing to rely on super implemenation where possible >+ - Removed VerficationMetaData which is now not needed any more (as in case of other commands that do not have something like this as well) >+ - Implemented enhancements to verification hook insertion (i.e. resolved bug #201248). It now supports an extented mode (that is also needed in case of Draw2d). In extended >+ mode, verification does not rely on the context but also on a selected UIObject (i.e. widget and possibly nested object). >+ >+5) Introduced a command factory that encapsulates creation of commands (factored respective code out of MacroCommandShell). Introduced a respective extension point >+ to replace the command factory. This will be needed to add support for draw2d, as the commands are responsible of locating their respective macro objects in a respective event, >+ and the default implementation of the commands do not pay any interest to nested objects beyond the widget level (e.g. Figures on a FigureCanvas). >+ >+6) Refactored MacroManager >+ - moved event constants into EventConstants interface, which defines the custom event types and details >+ - moved mode constants into own ModeConstants interface >+ >+7) Removed unneeded IRecorderListener interface (never used) >+ >+8) Fixed that in Eclispe Ganymede, when closing an unsaved editor, the workbench close command was created after the message dialog selection command. >+ >+9) Introduced mouse move commands to explitly capture mouse move events, as needed to test GEF-applications. >+ >+10) Several minor fixes and cleanups. >+ >+TODO: >+ - Migrate BooleanSelectionCommand and AbstractStructuredCommand to fully use the new resolving/deresolving mechanisms for macro objects (they are still based on parts >+ of the old resolving mechanism, respectively do resolving/deresolving on their own), which should be taken care of. >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObject.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObject.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,26 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject; >+ >+import org.eclipse.swt.widgets.Widget; >+ >+ >+/** >+ * @author Alexander Nyssen >+ * >+ */ >+public interface IUIObject { >+ >+ public abstract Widget getWidget(); >+ >+ public abstract Object getObject(); >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/IUIObjectResolverDelegate.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/IUIObjectResolverDelegate.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/IUIObjectResolverDelegate.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/IUIObjectResolverDelegate.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,53 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+ >+/** >+ * This interface is registered using extension point >+ * <code>org.eclipse.tptp.test.auto.gui.internal.widgetResolver</code> which is >+ * expected to return a unique identifier from a provided widget. The identifier >+ * must be reproducable between sessions so that it can be used to locate the >+ * widget on playback. >+ * >+ * @since 3.1 >+ */ >+public interface IUIObjectResolverDelegate { >+ >+ /** >+ * Returns a unique identifier for the provided UI object. >+ * >+ * @param context >+ * The context of the UI object (usually retrieved from an >+ * IMacroObject) >+ * @param uiObject >+ * The object whose id is suppose to be resolved. The type of >+ * this object is <b>usually</b> a widget, but it can also be a >+ * <code>java.lang.String</code> or any other arbitrary type >+ * depending on the implementation of the widget. For example, >+ * when attempting to resolve a combo box item, parent will point >+ * to the combo box and object will point to a >+ * <code>java.lang.String</code> item representing the item >+ * selected. >+ * >+ * @return unique identifier that can be used to locate the UI object within >+ * the context or <code>null</code> if none can be found. >+ */ >+ public IUIObjectIdentifier resolve(Object context, IUIObject uiObject) >+ throws CoreException; >+ >+ public IUIObject deresolve(Object context, >+ IUIObjectIdentifier uiObjectIdentifier) throws CoreException; >+ >+} >Index: .settings/org.eclipse.jdt.core.prefs >=================================================================== >RCS file: .settings/org.eclipse.jdt.core.prefs >diff -N .settings/org.eclipse.jdt.core.prefs >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ .settings/org.eclipse.jdt.core.prefs 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,12 @@ >+#Tue Jan 22 16:24:58 CET 2008 >+eclipse.preferences.version=1 >+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled >+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 >+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve >+org.eclipse.jdt.core.compiler.compliance=1.4 >+org.eclipse.jdt.core.compiler.debug.lineNumber=generate >+org.eclipse.jdt.core.compiler.debug.localVariable=generate >+org.eclipse.jdt.core.compiler.debug.sourceFile=generate >+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning >+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning >+org.eclipse.jdt.core.compiler.source=1.3 >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/WeightedPropertyUIObjectIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/WeightedPropertyUIObjectIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/WeightedPropertyUIObjectIdentifier.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/WeightedPropertyUIObjectIdentifier.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,211 @@ >+/********************************************************************** >+ * Copyright (c) 2005, 2006 IBM Corporation and others. >+ * 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 >+ * $Id: WeightedPropertyUIObjectIdentifier.java,v 1.3 2006/12/04 02:55:08 amehregani Exp $ >+ * >+ * Contributors: >+ * IBM - Initial API and implementation >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject; >+ >+import java.util.regex.Matcher; >+import java.util.regex.Pattern; >+ >+import org.eclipse.hyades.test.common.util.XMLUtil; >+ >+/** >+ * Defines a widget Id by a set of properties that the widget must have. Each property is assigned a weight and if the total weight exceeds the >+ * threshold, then the widget is identified as a match >+ * >+ * @author Ali Mehregani >+ */ >+public class WeightedPropertyUIObjectIdentifier implements IUIObjectIdentifier { >+ >+ private WeightedPropertyUIObjectIdentifier() { >+ } >+ >+ public WeightedPropertyUIObjectIdentifier(Object[] propertyWeightPair, float threshold, String resolverId) { >+ this.propertyWeightPair = propertyWeightPair; >+ this.threshold = threshold; >+ this.resolverId = resolverId; >+ } >+ >+ private String resolverId; >+ >+ /* >+ * Stored elements are of type Object[2], where the first element is the value returned by the method corresponding to the property and the second >+ * value is the weight associated with that property. >+ */ >+ private Object[] propertyWeightPair; >+ private float threshold; >+ >+ private final static Pattern pairPattern = Pattern.compile(".*?\\{\\{([^\\}]+)\\}\\}-\\{\\{([^\\}]+)\\}\\}.*"); >+ >+ public boolean equals(Object obj) { >+ String stringToCompare = null; >+ boolean compare = false; >+ >+ /* The object is of our own kind */ >+ if (obj instanceof WeightedPropertyUIObjectIdentifier) { >+ WeightedPropertyUIObjectIdentifier idToCompareWith = (WeightedPropertyUIObjectIdentifier) obj; >+ >+ if (this == idToCompareWith) >+ return true; >+ >+ compare = true; >+ stringToCompare = idToCompareWith.toString(); >+ } >+ >+ /* The object is a string (most likely coming from a macro) */ >+ else if (obj instanceof String) { >+ compare = true; >+ stringToCompare = (String) obj; >+ } >+ // ANy: equals has to be done on strings only, as a weigthed property id becomes a primitive one after loading (during playback) >+ else if( obj instanceof IUIObjectIdentifier){ >+ compare = true; >+ stringToCompare = ((IUIObjectIdentifier)obj).getWidgetId(); >+ } >+ >+ if (!compare) >+ return false; >+ >+ /* >+ * Use regular expression to distinguish the returned value of each method from the weight >+ */ >+ float accumMatchRate = 0; >+ int loopIterationNo = -1; >+ >+ while (stringToCompare.length() > 0 && (loopIterationNo + 1) < propertyWeightPair.length) { >+ loopIterationNo++; >+ Matcher pairTokenMatcher = pairPattern.matcher(stringToCompare); >+ >+ /* Discontinue if there is no match */ >+ if (!pairTokenMatcher.matches() || pairTokenMatcher.groupCount() != 2) >+ break; >+ >+ /* Otherwise walk through each token */ >+ String originalProperty = pairTokenMatcher.group(1); >+ String prop = originalProperty; >+ if (prop.length() > 0) >+ prop = XMLUtil.removeXMLSymbols(prop); >+ float weight = Float.parseFloat(pairTokenMatcher.group(2)); >+ >+ /* The ordering of the tokens for the IDs being compared must be the same. */ >+ Object[] propertyWeightPair = (Object[]) this.propertyWeightPair[loopIterationNo]; >+ if (!prop.equals("null") && (prop.length() > 0 >+ ? prop.charAt(0) == ((String) propertyWeightPair[0]).charAt(0) || prop.charAt(0) == '&' >+ : true) && (prop.equals(propertyWeightPair[0]) || prop.replaceAll("\\&", >+ "").equals(propertyWeightPair[0]) || prop.replace('/', >+ '\\').equals(propertyWeightPair[0]))) >+ accumMatchRate += Float.parseFloat((String) propertyWeightPair[1]); >+ >+ String currentToken = "{{" + originalProperty + "}}-{{" + weight + "}}"; >+ if (currentToken.equals(stringToCompare)) >+ break; >+ >+ int inx = stringToCompare.indexOf(currentToken); >+ if (inx != -1) >+ stringToCompare = stringToCompare.substring(inx + currentToken.length(), >+ stringToCompare.length()); >+ >+ else >+ break; /* The control flow should never reach this block */ >+ >+ } >+ >+ if (accumMatchRate >= threshold) >+ return true; >+ return false; >+ } >+ >+ /** >+ * Return a string representation of this identifier. The property, weight information is organized in this format: >+ * {{property-value1}}-{{weight1}}{{property-value2}}:{{weight2}} >+ */ >+ public String getWidgetId() { >+ String retValue = ""; >+ for (int i = 0; i < this.propertyWeightPair.length; i++) >+ retValue += "{{" + ((Object[]) this.propertyWeightPair[i])[0] + "}}-{{" + ((Object[]) this.propertyWeightPair[i])[1] + "}}"; >+ >+ return XMLUtil.useXMLSymbols(retValue); >+ } >+ >+ public String toString() { >+ return getWidgetId(); >+ } >+ >+ public float getThreshold() { >+ return threshold; >+ } >+ >+ // public void setThreshold(float threshold) { >+ // this.threshold = threshold; >+ // } >+ >+ public Object[] getPropertyWeightPair() { >+ return propertyWeightPair; >+ } >+ >+ // public void setPropertyWeightPair(Object[] propertyWeightPair) { >+ // this.propertyWeightPair = propertyWeightPair; >+ // } >+ >+ /** >+ * Walk through the properties and return true for as long as one of them is not null. >+ * >+ * @return true if at least one property is not null; false otherwise >+ */ >+ public boolean noValidProperties() { >+ if (propertyWeightPair == null) >+ return true; >+ >+ for (int i = 0; i < propertyWeightPair.length; i++) { >+ String property = (String) ((Object[]) propertyWeightPair[i])[0]; >+ if (property != null && !property.equals("null")) >+ return false; >+ } >+ return true; >+ } >+ >+ /** >+ * Convenient method available for clients to use in order to construct a weighted property id >+ * >+ * @param properties >+ * The (properties, weight) pairs of the item (weights should be a value between (0, 1]) >+ * @param threshold >+ * The threshold that this property should meet (should be a value between (0-1]) >+ * @return Returns an instance of this class with the appropriate fields set. >+ */ >+ public static WeightedPropertyUIObjectIdentifier constructId(Object[] properties, float threshold, String resolverId) { >+ /* Step through the properties and replace null values with the literal string null */ >+ for (int i = 0; i < properties.length; i++) { >+ String property = (String) ((Object[]) properties[i])[0]; >+ if (property == null || property.length() <= 0) >+ ((Object[]) properties[i])[0] = "null"; >+ >+ } >+ >+ WeightedPropertyUIObjectIdentifier widgetId = new WeightedPropertyUIObjectIdentifier(properties, threshold, resolverId); >+ >+ if (widgetId.noValidProperties()) >+ return null; >+ return widgetId; >+ } >+ >+ public String getResolverId() { >+ return resolverId; >+ } >+ >+ public String getObjectId(){ >+ // nested objects not supported by this resolver >+ return null; >+ } >+ >+ // public void setResolverId(String resolverId) { >+ // this.resolverId = resolverId; >+ // } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactoryLoader.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactoryLoader.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactoryLoader.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactoryLoader.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,72 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.commands.factory; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IConfigurationElement; >+import org.eclipse.core.runtime.Platform; >+ >+/** >+ * Helper class to load a IMacroCommandFactory via the respective extension >+ * point. Only the factory with the highest priority is used. All other >+ * factories are disregarded. >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public class MacroCommandFactoryLoader { >+ >+ private static final String EXTENSION_POINT_NAME = "macroCommandFactory"; >+ private static final String EXTENSION_POINT_ID = "org.eclipse.tptp.test.auto.gui." >+ + EXTENSION_POINT_NAME; >+ >+ private static IMacroCommandFactory factory = null; >+ >+ /** >+ * Retrieves the factory with the highest priority, meaning the lowest >+ * priority number, i.e. a priority of 1 is greater than one of 2. >+ * >+ * @return >+ */ >+ public static IMacroCommandFactory getHighestPriorityFactory() { >+ if (factory == null) { >+ factory = retrieveFactoryWithHighestPriority(); >+ } >+ return factory; >+ } >+ >+ private static IMacroCommandFactory retrieveFactoryWithHighestPriority() { >+ IConfigurationElement[] elements = Platform.getExtensionRegistry() >+ .getConfigurationElementsFor(EXTENSION_POINT_ID); >+ >+ IMacroCommandFactory factory = null; >+ int priority = Integer.MAX_VALUE; >+ for (int i = 0; i < elements.length; i++) { >+ if (EXTENSION_POINT_NAME.equals(elements[i].getName())) { >+ try { >+ IMacroCommandFactory currentFactory = (IMacroCommandFactory) elements[i] >+ .createExecutableExtension("class"); >+ int currentPriority = Integer.parseInt(elements[i] >+ .getAttribute("priority")); >+ >+ if (currentFactory != null && currentPriority < priority) { >+ factory = currentFactory; >+ priority = currentPriority; >+ } >+ } catch (CoreException e) { >+ e.printStackTrace(); >+ } >+ } >+ } >+ return factory; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/UIObjectDeprecatedDeresolvingSupport.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/UIObjectDeprecatedDeresolvingSupport.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/UIObjectDeprecatedDeresolvingSupport.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/UIObjectDeprecatedDeresolvingSupport.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,667 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport; >+ >+import java.util.Enumeration; >+import java.util.Hashtable; >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.jface.action.IContributionItem; >+import org.eclipse.jface.action.ICoolBarManager; >+import org.eclipse.jface.action.IToolBarManager; >+import org.eclipse.jface.action.ToolBarContributionItem; >+import org.eclipse.jface.action.ToolBarManager; >+import org.eclipse.jface.wizard.IWizardPage; >+import org.eclipse.jface.wizard.WizardDialog; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.custom.CCombo; >+import org.eclipse.swt.custom.CTabFolder; >+import org.eclipse.swt.custom.CTabItem; >+import org.eclipse.swt.widgets.Combo; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Item; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TabFolder; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.swt.widgets.ToolBar; >+import org.eclipse.swt.widgets.ToolItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.DeresolvingAmbiguityException; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateRegistry; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IViewPart; >+ >+/** >+ * This class was merely introduced to be able to migrate the already existing >+ * WidgetResolvers to the newly introduced IUIObjectResolverDelegate interface >+ * while preserving the old implementation to deresolve UI objects (via the >+ * foundWidget method). New IUIObjectResolverDelegates should not build on this >+ * class and this class should possibly be removed by implementing proper >+ * deresolving mechanisms in the existing IUIObjectResolverDelegate >+ * implementations in the future. >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public class UIObjectDeprecatedDeresolvingSupport { >+ >+ /** >+ * Preserves the deprecated algorithm for widget resolving that was used >+ * before. Both, the AdaptiveUIObjectResolverDelegate as well as the >+ * NonTrivialUIObjectResolverDelegate refer to this implementation of >+ * deresolving. All newly introduced resolvers should not reside on this. >+ */ >+ public static IUIObject deresolve(Object context, >+ IUIObjectIdentifier identifier) throws CoreException { >+ >+ IUIObject uiObject = null; >+ String errorMessage = null; >+ Throwable cause = null; >+ >+ try { >+ if (context instanceof Menu) { >+ // normal menus and popup menus (in the latter case we have to >+ // ensure the menu is visible >+ Menu menuBar = (Menu) context; >+ MacroUtil.forceMenuOpen(menuBar); >+ uiObject = locateMenuItem(menuBar, identifier); >+ MacroUtil.forceMenuClosed(menuBar); >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof ToolBar) { >+ // deresolve tool item >+ ToolBar toolbar = (ToolBar) context; >+ uiObject = locateToolItem(toolbar, identifier); >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof ToolBarManager >+ || context instanceof ICoolBarManager) { >+ if (context instanceof ToolBarManager) { >+ // Only ToolBarManager can be deresolved, not any >+ // IToolBarManager implementation, >+ // as the interface IToolBarManager interface does not allow >+ // to obtain the control >+ ToolBarManager toolBarManager = (ToolBarManager) context; >+ uiObject = locateToolItem(toolBarManager, identifier); >+ } else { >+ ICoolBarManager coolBarManager = (ICoolBarManager) context; >+ uiObject = locateToolItem(coolBarManager, identifier); >+ } >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof TabFolder >+ || context instanceof CTabFolder) { >+ if (context instanceof TabFolder) { >+ TabFolder tabFolder = (TabFolder) context; >+ uiObject = locateTabItem(tabFolder, identifier); >+ } else { >+ CTabFolder tabFolder = (CTabFolder) context; >+ uiObject = locateCTabItem(tabFolder, identifier); >+ } >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TAB, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof WizardDialog) { >+ WizardDialog wd = (WizardDialog) context; >+ >+ IWizardPage page = wd.getCurrentPage(); >+ Composite pparent = (Composite) page.getControl(); >+ uiObject = UIObjectDeprecatedDeresolvingSupport >+ .locateVisibleChild(wd.getShell(), pparent, identifier); >+ >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof IWizardPage) { >+ IWizardPage page = (IWizardPage) context; >+ >+ Composite pparent = (Composite) page.getControl(); >+ uiObject = UIObjectDeprecatedDeresolvingSupport >+ .locateVisibleChild(pparent, null, identifier); >+ >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD_CON, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof IEditorPart) { >+ IEditorPart editor = (IEditorPart) context; >+ >+ Composite c = MacroUtil.getWorkbenchPartControl(editor); >+ uiObject = UIObjectDeprecatedDeresolvingSupport >+ .locateVisibleChild(c, null, identifier); >+ >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR_CON, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof IViewPart) { >+ IViewPart view = (IViewPart) context; >+ >+ Composite c = MacroUtil.getWorkbenchPartControl(view); >+ uiObject = UIObjectDeprecatedDeresolvingSupport >+ .locateVisibleChild((Composite) c, null, identifier); >+ >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW_CON, >+ identifier.getWidgetId()); >+ } >+ } else if (context instanceof Shell) { >+ // locate a shell control >+ Shell shell = (Shell) context; >+ >+ uiObject = UIObjectDeprecatedDeresolvingSupport >+ .locateVisibleChild(shell, null, identifier); >+ >+ if (uiObject == null) { >+ errorMessage = NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL, >+ identifier.getWidgetId()); >+ } >+ } >+ >+ } catch (Throwable t) { >+ t.printStackTrace(); >+ if (t.getCause() != null) { >+ cause = t.getCause(); >+ } else { >+ cause = t; >+ } >+ errorMessage = t.getMessage(); >+ } >+ >+ if (uiObject != null) { >+ return uiObject; >+ } else { >+ AutoGUIUtil.throwCoreException(errorMessage, cause); >+ return null; >+ } >+ } >+ >+ private static IUIObject locateCTabItem(CTabFolder tabFolder, >+ IUIObjectIdentifier identifier) { >+ CTabItem tabItem = null; >+ for (int i = 0; i < tabFolder.getItemCount() && tabItem == null; i++) { >+ CTabItem currentItem = tabFolder.getItem(i); >+ String validatedCurrentItemText = NonTrivialUIObjectResolverDelegate >+ .validateText(currentItem.getText()); >+ if (validatedCurrentItemText != null >+ && validatedCurrentItemText >+ .equals(identifier.getWidgetId())) { >+ tabItem = currentItem; >+ } >+ } >+ return new UIObject(tabItem); >+ } >+ >+ private static IUIObject locateTabItem(TabFolder tabFolder, >+ IUIObjectIdentifier identifier) { >+ TabItem tabItem = null; >+ for (int i = 0; i < tabFolder.getItemCount() && tabItem == null; i++) { >+ TabItem currentItem = tabFolder.getItem(i); >+ String validatedCurrentItemText = NonTrivialUIObjectResolverDelegate >+ .validateText(currentItem.getText()); >+ if (validatedCurrentItemText != null >+ && validatedCurrentItemText >+ .equals(identifier.getWidgetId())) { >+ tabItem = currentItem; >+ } >+ } >+ return new UIObject(tabItem); >+ } >+ >+ /** >+ * @deprecated This method should only be used internally Returns true iff >+ * the widget matches the id passed in. >+ * >+ * @param widget >+ * The widget >+ * @param objectId >+ * The resolver id -- can be null >+ * @return true iff the widget matches the id passed in. >+ */ >+ public static boolean foundWidget(Widget widget, >+ IUIObjectIdentifier widgetId) { >+ Hashtable widgetResolvers = UIObjectResolverDelegateRegistry >+ .getDelegateResolverLoaders(); >+ >+ if (widgetId != null && widgetId.getResolverId() != null) { >+ UIObjectResolverDelegateLoader loader = (UIObjectResolverDelegateLoader) widgetResolvers >+ .get(widgetId.getResolverId()); >+ if (loader != null >+ && loader.getUIObjectResolverDelegate() instanceof IUIObjectDeprecatedDeresolvingFacade) >+ return ((IUIObjectDeprecatedDeresolvingFacade) loader >+ .getUIObjectResolverDelegate()).foundWidget(widget, >+ widgetId); >+ return false; >+ } >+ >+ Enumeration keys = widgetResolvers.keys(); >+ while (keys.hasMoreElements()) { >+ IUIObjectResolverDelegate delegateResolver = ((UIObjectResolverDelegateLoader) widgetResolvers >+ .get(keys.nextElement())).getUIObjectResolverDelegate(); >+ if (delegateResolver instanceof IUIObjectDeprecatedDeresolvingFacade) { >+ if (((IUIObjectDeprecatedDeresolvingFacade) delegateResolver) >+ .foundWidget(widget, widgetId)) { >+ return true; >+ } >+ } >+ } >+ return false; >+ } >+ >+ /** >+ * @deprecated This method should only be used internally. Returns true if >+ * the id computed for 'item' matches 'id' >+ * >+ * @param item >+ * The tool item >+ * @param resolverId >+ * The resolver id -- can be null >+ * @param id >+ * The id that should be matched against >+ * @return true if there is a match, and false otherwise >+ */ >+ public static boolean foundItem(Item item, IUIObjectIdentifier objectId) { >+ /* Try the widget resolvers first */ >+ if (foundWidget(item, objectId)) >+ return true; >+ >+ /* Give the old policy a try */ >+ String toolItemIdStr = NonTrivialUIObjectResolverDelegate.getActionId( >+ item).toString(); >+ if (toolItemIdStr != null >+ && toolItemIdStr.equals(objectId.getWidgetId())) >+ return true; >+ >+ return false; >+ } >+ >+ public static Control recursiveSearch(Composite parent, Composite skip, >+ Control desiredControl, IUIObjectIdentifier id, >+ String widgetClassName, int[] index, Vector matches, Vector indices) { >+ boolean searchForControl = id == null; >+ Control[] children = parent.getChildren(); >+ boolean[] checkTypeAndEquality; >+ Control searchResult; >+ // boolean isTabFolder, isCTabFolder; >+ >+ for (int i = 0; i < children.length; i++) { >+ Control child = children[i]; >+ >+ if (!child.isVisible()) { >+ /* >+ * If the control is of the same type, then we'll need to >+ * increment the index >+ */ >+ if ((widgetClassName != null && child.getClass().getName() >+ .equals(widgetClassName)) >+ || (desiredControl != null && desiredControl.getClass() >+ .getName().equals(child.getClass().getName()))) >+ index[0]++; >+ >+ continue; >+ } >+ >+ checkTypeAndEquality = searchForControl ? checkTypeAndEqual( >+ desiredControl, child, index) : checkTypeAndId(child, id, >+ widgetClassName, index); >+ if (checkTypeAndEquality[0]) { >+ if (checkTypeAndEquality[1]) { >+ addMatch(matches, indices, child, index[0]); >+ } >+ >+ // ANy: This code is now obsolete, as we have a new deresolving >+ // policy for >+ // TabItems and CTabItems (own context info) and the respective >+ // choice command >+ // converts existing macro entries to the new format. >+ // /* Defect 111371 -- We need to step through the items of a >+ // tab */ >+ // isTabFolder = child instanceof TabFolder; >+ // isCTabFolder = child instanceof CTabFolder; >+ // if (isTabFolder || isCTabFolder) { >+ // Object[] tabItems = isTabFolder ? (Object[]) ((TabFolder) >+ // child) >+ // .getItems() >+ // : ((CTabFolder) child).getItems(); >+ // if (tabItems != null) { >+ // for (int j = 0; j < tabItems.length; j++) { >+ // Control tabItemControl = isTabFolder ? ((TabItem) >+ // tabItems[j]) >+ // .getControl() >+ // : ((CTabItem) tabItems[j]).getControl(); >+ // >+ // if (tabItemControl == null) >+ // continue; >+ // >+ // checkTypeAndEquality = searchForControl ? checkTypeAndEqual( >+ // tabItemControl, desiredControl, index) >+ // : checkTypeAndId(tabItemControl, id, >+ // widgetClassName, index); >+ // if (checkTypeAndEquality[0] >+ // && checkTypeAndEquality[1]) { >+ // addMatch(matches, indices, tabItemControl, >+ // index[0]); >+ // } >+ // if ((searchResult = recursiveSearch(tabItemControl, >+ // skip, desiredControl, id, widgetClassName, >+ // index, matches, indices)) != null) { >+ // addMatch(matches, indices, searchResult, >+ // index[0]); >+ // } >+ // } >+ // } >+ // } >+ // >+ } >+ >+ if ((searchResult = recursiveSearch(child, skip, desiredControl, >+ id, widgetClassName, index, matches, indices)) != null) { >+ addMatch(matches, indices, searchResult, index[0]); >+ } >+ } >+ >+ if (matches.size() > 0) { >+ return (Control) matches.get(0); >+ } else { >+ return null; >+ } >+ } >+ >+ /** >+ * A helper method used to indicate whether expected is of the same type as >+ * actual. The return value also indicates if expected == actual. >+ * >+ * @param expected >+ * The expected control >+ * @param actual >+ * The actual control that 'expected' is checked against >+ * @param counter >+ * A counter that is used for indexing. >+ * >+ * @return This method has the side affect of incrementing counter if the >+ * class types of the two controls are the same. The return value >+ * indicates type and whether expected == actual. >+ */ >+ private static boolean[] checkTypeAndEqual(Control expected, >+ Control actual, int[] counter) { >+ boolean[] typeAndEqualCheck = new boolean[2]; >+ if (expected.getClass().equals(actual.getClass())) { >+ typeAndEqualCheck[0] = true; >+ >+ // same type - increment counter >+ counter[0]++; >+ if (expected.equals(actual)) { >+ // bingo >+ typeAndEqualCheck[1] = true; >+ } >+ } >+ >+ return typeAndEqualCheck; >+ } >+ >+ private static Control recursiveSearch(Control currentSearchPoint, >+ Composite skip, Control desiredControl, >+ IUIObjectIdentifier desiredId, String desiredWidgetClassName, >+ int[] index, Vector matches, Vector indices) { >+ Control searchResult = null; >+ if (currentSearchPoint instanceof Composite >+ && !(skip != null && currentSearchPoint.equals(skip)) >+ && currentSearchPoint.isVisible()) { >+ searchResult = recursiveSearch((Composite) currentSearchPoint, >+ skip, desiredControl, desiredId, desiredWidgetClassName, >+ index, matches, indices); >+ } >+ >+ return searchResult; >+ } >+ >+ private static void addMatch(Vector container, Vector indices, Object item, >+ int index) { >+ if (!container.contains(item)) { >+ container.add(item); >+ indices.add(new Integer(index)); >+ } >+ } >+ >+ private static boolean[] checkTypeAndId(Control presentControl, >+ IUIObjectIdentifier desiredId, String desiredWidgetClassName, >+ int[] counter) { >+ boolean[] checkTypeAndEqualId = new boolean[2]; >+ >+ if (desiredWidgetClassName == null >+ || presentControl.getClass().getName().equals( >+ desiredWidgetClassName)) { >+ // same type - increment counter >+ if (!presentControl.isVisible()) >+ return checkTypeAndEqualId; >+ >+ checkTypeAndEqualId[0] = true; >+ counter[0]++; >+ if (foundWidget(presentControl, desiredId) >+ || NonTrivialUIObjectResolverDelegate >+ .computeDefaultControlId(presentControl, counter[0]) >+ .equals(desiredId.getWidgetId())) { >+ checkTypeAndEqualId[1] = true; >+ } >+ } >+ >+ return checkTypeAndEqualId; >+ } >+ >+ private static UIObject locateVisibleChild(Composite parent, >+ Composite skip, IUIObjectIdentifier uiObjectIdentifier) >+ throws CoreException { >+ int[] counter = new int[1]; >+ counter[0] = 0; >+ >+ // see if an uniqueness identifier was added by the UIObjectResolver >+ // because the identifier >+ // that was computed is not unique (workaround for defect #147766) >+ String widgetIdentifier = uiObjectIdentifier.getWidgetId(); >+ IUIObjectIdentifier adjustedUIObjectIdentifier = uiObjectIdentifier; >+ int matchIndex = -1; >+ if (widgetIdentifier >+ .indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR) > 0) { >+ adjustedUIObjectIdentifier = new PrimitiveUIObjectIdentifier( >+ widgetIdentifier >+ .substring( >+ 0, >+ widgetIdentifier >+ .indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR)), >+ uiObjectIdentifier.getObjectId(), uiObjectIdentifier >+ .getResolverId()); >+ matchIndex = new Integer( >+ widgetIdentifier >+ .substring(widgetIdentifier >+ .indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR) + 3)) >+ .intValue(); >+ } >+ >+ int sloc = widgetIdentifier.indexOf('#'); >+ String wclassName = null; >+ if (sloc != -1) >+ wclassName = widgetIdentifier.substring(0, sloc); >+ >+ /* >+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: We need to >+ * return all possible matches -> ANy: this does not seem to be an >+ * adequate solution. It seems as if the resolving mechanism should >+ * compute a more appropriate identifier in such a case. We will >+ * therefore not tolerate such an anambiguity. >+ */ >+ Vector matches = new Vector(); >+ Vector indices = new Vector(); >+ // do not use the extended widget identifier but only the prefix to find >+ // the widget >+ locateVisibleChild(parent, skip, adjustedUIObjectIdentifier, >+ wclassName, counter, matches, indices); >+ >+ // see if we have properly deresolved a control >+ Control control = null; >+ if (matches.size() > 0) { >+ if (matches.size() > 1) { >+ if (matchIndex != -1) { >+ control = (Control) matches.get(matchIndex); >+ } else { >+ // we have found several matches and no uniqueness >+ // identifier was added, >+ // so we cannt unambiguously identify which one was >+ // selected. >+ AutoGUIUtil >+ .throwCoreException( >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS, >+ uiObjectIdentifier >+ .getWidgetId(), >+ uiObjectIdentifier >+ .getObjectId()), >+ new DeresolvingAmbiguityException(matches >+ .size())); >+ return null; >+ } >+ } else { >+ control = (Control) matches.get(0); >+ } >+ } >+ >+ // we have located a control, see if we have to further deresolve a >+ // nested object >+ if (control != null) { >+ // added by ANy to resolve beyond the widget level for combo and >+ // ccombo controls (needed in choice command) >+ if (adjustedUIObjectIdentifier.getObjectId() != null) { >+ // find object located at the sub widget level >+ if (control instanceof Combo || control instanceof CCombo) { >+ String indexString = adjustedUIObjectIdentifier >+ .getObjectId().substring( >+ new String("item#").length()); >+ int index = new Integer(indexString).intValue(); >+ // find the item at the specified index >+ if (control instanceof Combo) { >+ String[] items = ((Combo) control).getItems(); >+ return new UIObject(control, items[index]); >+ } else if (control instanceof CCombo) { >+ String[] items = ((CCombo) control).getItems(); >+ return new UIObject(control, items[index]); >+ } >+ return null; >+ } else { >+ // anything else is ignored up to now >+ return new UIObject(control); >+ } >+ } else { >+ return new UIObject(control); >+ } >+ } else { >+ return null; >+ } >+ } >+ >+ private static Control locateVisibleChild(Composite parent, Composite skip, >+ IUIObjectIdentifier id, String wclassName, int[] index, >+ Vector matches, Vector indices) { >+ return recursiveSearch(parent, skip, null, id, wclassName, index, >+ matches, indices); >+ } >+ >+ private static IUIObject locateToolItem(ICoolBarManager coolMng, >+ IUIObjectIdentifier wid) { >+ IContributionItem[] items = coolMng.getItems(); >+ for (int i = 0; i < items.length; i++) { >+ if (items[i] instanceof ToolBarContributionItem) { >+ ToolBarContributionItem item = (ToolBarContributionItem) items[i]; >+ IToolBarManager toolMng = item.getToolBarManager(); >+ IUIObject target = locateToolItem((ToolBarManager) toolMng, wid); >+ if (target != null) >+ return target; >+ } >+ } >+ return null; >+ } >+ >+ private static IUIObject locateToolItem(ToolBarManager toolMng, >+ IUIObjectIdentifier wid) { >+ return locateToolItem(toolMng.getControl(), wid); >+ } >+ >+ private static UIObject locateMenuItem(Menu menu, >+ IUIObjectIdentifier widgetId) { >+ MenuItem[] items = menu.getItems(); >+ >+ for (int i = 0; i < items.length; i++) { >+ MenuItem item = items[i]; >+ >+ Menu submenu = item.getMenu(); >+ if (submenu != null) { >+ /* >+ * Ali M.: We have to force the menu to open, since its items >+ * may not have already been created >+ */ >+ MacroUtil.forceMenuOpen(submenu); >+ UIObject hit = locateMenuItem(submenu, widgetId); >+ if (hit != null) >+ return hit; >+ } else { >+ if (UIObjectDeprecatedDeresolvingSupport.foundItem(item, >+ widgetId)) >+ return new UIObject(item); >+ } >+ } >+ return null; >+ } >+ >+ private static IUIObject locateToolItem(ToolBar toolBar, >+ IUIObjectIdentifier wid) { >+ if (toolBar == null) >+ return null; >+ ToolItem[] items = toolBar.getItems(); >+ for (int i = 0; i < items.length; i++) { >+ ToolItem item = items[i]; >+ if (UIObjectDeprecatedDeresolvingSupport.foundItem(item, wid)) >+ return new UIObject(item); >+ } >+ return null; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroCommandShell.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroCommandShell.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroCommandShell.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroCommandShell.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,1076 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2007 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+import java.util.ArrayList; >+import java.util.Hashtable; >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.core.runtime.SubProgressMonitor; >+import org.eclipse.jface.window.Window; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.SWTException; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Listener; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants; >+import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >+import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.MouseEventCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand; >+import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.w3c.dom.Node; >+import org.w3c.dom.NodeList; >+ >+/** >+ * Keeps track of the macro commands while they are being captured. >+ * >+ * @author Alexander Nyssen (factored creation of commands out into respective >+ * factory) >+ */ >+public class MacroCommandShell extends AbstractMacroInstruction implements >+ IMacroInstruction { >+ >+ /** The widget id associated with this macro command shell */ >+ private IMacroObjectIdentifier macroObjectIdentifier; >+ >+ /** The corresponding UI object for this macro command shell */ >+ private MacroObjectDescriptor macroObjectDescriptor; >+ >+ /* The commands of this macro shell */ >+ private ArrayList commands; >+ >+ /* The expected return code */ >+ private int expectedReturnCode; >+ >+ /* The display object */ >+ private transient Display display; >+ >+ /* The shell that this macro command shell represents */ >+ private transient Shell shell; >+ >+ /* The reference id of the macro shell object */ >+ // private String referenceId; >+ /* The title of the shell that this macro command shell represents */ >+ private String shellTitle; >+ >+ private transient Window window; >+ >+ /* Set when there is a listener registered with this MacroCommandShell */ >+ private transient boolean isListenerRegistered; >+ >+ /* >+ * A queue of nested shell waiting to be activated (this is used during >+ * playback) >+ */ >+ private static Vector nestedShellQueue; >+ >+ /* Last index of the nested shell queue */ >+ private static int lastNestedShellInx; >+ >+ /* Stores the last command line executed */ >+ private static int lastCommandLineExecuted; >+ >+ /* >+ * Mutual lock used to block when a command is being executed. This lock is >+ * used to forcefully wake up the thread that this object is running in if >+ * the command has caused a stall >+ */ >+ private Boolean mutualLock; >+ >+ /* >+ * A mutual lock shared across multiple instances of this class -- It's >+ * general purpose is to lock shared static resources >+ */ >+ private static Boolean mutualGlobalLock; >+ >+ /* >+ * The parent of this macro command shell. This is null if this macro shell >+ * command is the root >+ */ >+ private MacroCommandShell parent; >+ >+ /* >+ * The index of the command being executed -- this will correspond to the >+ * last command index if isComplete = true >+ */ >+ private int currentCommandInx; >+ >+ /* Indicates if all the commands of this shell has been completed */ >+ private boolean isComplete; >+ >+ /* Indicates that the process needs to be interrupted -- due to an error */ >+ private static boolean interruptProcess; >+ >+ /* Set to true when process has been terminated */ >+ private static boolean processTerminated; >+ >+ /* The exception causing the interruption */ >+ private static Throwable interruptedException; >+ >+ /* A central container for all macro command operation being played */ >+ private static Vector macroCommandsBeingPlayed; >+ >+ /* A central container for all instances of this class */ >+ private static Vector macroCommandShellContainer; >+ >+ /* A central repository for all macro command shells */ >+ static { >+ nestedShellQueue = new Vector(); >+ macroCommandsBeingPlayed = new Vector(); >+ macroCommandShellContainer = new Vector(); >+ mutualGlobalLock = new Boolean(true); >+ } >+ >+ public MacroCommandShell(MacroCommandShell parent) { >+ this(parent, null, null); >+ } >+ >+ public MacroCommandShell(MacroCommandShell parent, Shell shell, >+ IMacroObjectIdentifier wid) { >+ setMacroObjectIdentifier(wid); >+ commands = new ArrayList(); >+ this.shell = shell; >+ this.shellTitle = shell == null || shell.isDisposed() ? null : shell >+ .getText(); >+ hookWindow(false); >+ expectedReturnCode = -1; >+ isListenerRegistered = false; >+ mutualLock = new Boolean(true); >+ this.parent = parent; >+ isComplete = false; >+ macroCommandShellContainer.add(this); >+ } >+ >+ public IMacroObjectIdentifier getMacroObjectIdentifier() { >+ return macroObjectIdentifier; >+ } >+ >+ public void setMacroObjectIdentifier(IMacroObjectIdentifier objectIdentifier) { >+ this.macroObjectIdentifier = objectIdentifier; >+ } >+ >+ public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() { >+ return macroObjectDescriptor; >+ } >+ >+ public void setCorrespondingMacroObjectDescriptor( >+ MacroObjectDescriptor uiObject) { >+ this.macroObjectDescriptor = uiObject; >+ } >+ >+ private void hookWindow(boolean playback) { >+ if (shell != null) { >+ if (!playback) >+ doHookWindow(); >+ else >+ display.syncExec(new Runnable() { >+ >+ public void run() { >+ doHookWindow(); >+ } >+ }); >+ } >+ } >+ >+ private void doHookWindow() { >+ Object data = shell.getData(); >+ if (data != null && data instanceof Window) >+ this.window = (Window) data; >+ } >+ >+ /** >+ * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node, >+ * java.util.Hashtable) >+ */ >+ public void load(Node node, Hashtable lineTable) throws CoreException { >+ super.load(node, lineTable); >+ >+ /* >+ * If the corresponding shell of this command is referenced then attempt >+ * to find the corresponding object in the object mine. >+ */ >+ if (MacroManager.getInstance().getObjectMine() != null) { >+ MacroObjectDescriptor descriptor = MacroManager.getInstance() >+ .getObjectMine().lookupReferenceId(null, node, lineTable); >+ if (descriptor != null) { >+ setCorrespondingMacroObjectDescriptor(descriptor); >+ } >+ } >+ boolean useObjectMine = getCorrespondingMacroObjectDescriptor() != null; >+ setMacroObjectIdentifier(new MacroObjectIdentifier(null, >+ new PrimitiveUIObjectIdentifier( >+ useObjectMine ? getCorrespondingMacroObjectDescriptor() >+ .getWidgetId() : MacroUtil.getAttribute(node, >+ MacroConstants.WIDGET_ID_ATTRIBUTE), >+ useObjectMine ? getCorrespondingMacroObjectDescriptor() >+ .getResolverId() : MacroUtil.getAttribute(node, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE)))); >+ String codeId = MacroUtil.getAttribute(node, >+ MacroConstants.RETURN_CODE_ATTRIBUTE); >+ if (codeId != null) { >+ try { >+ expectedReturnCode = new Integer(codeId).intValue(); >+ } catch (NumberFormatException e) { >+ } >+ } >+ NodeList children = node.getChildNodes(); >+ for (int i = 0; i < children.getLength(); i++) { >+ Node child = children.item(i); >+ if (child.getNodeType() == Node.ELEMENT_NODE) { >+ String name = child.getNodeName(); >+ if (name.equals(MacroConstants.COMMAND_ELEMENT)) >+ processCommand(child, lineTable); >+ else if (name.equals(MacroConstants.SHELL_ELEMENT)) >+ processShell(child, lineTable); >+ } >+ } >+ } >+ >+ /** >+ * Used to process the node that is passed in as argument, the lineTable >+ * hashtable indicates the range of line numbers that the node corresponds >+ * to in the macro script >+ * >+ * @param node >+ * The node to be processed >+ * @param lineTable >+ * The line number range that the node corresponds to in the >+ * script. >+ */ >+ private void processCommand(Node node, Hashtable lineTable) >+ throws CoreException { >+ >+ String type = MacroUtil.getAttribute(node, >+ MacroConstants.TYPE_ATTRIBUTE); >+ if (type == null) >+ return; >+ >+ IMacroCommand command = MacroManager.getInstance() >+ .getMacroCommandFactory().createCommand(this, type); >+ >+ if (command != null) { >+ command.load(node, lineTable); >+ commands.add(command); >+ } >+ } >+ >+ private void processShell(Node node, Hashtable lineTable) >+ throws CoreException { >+ MacroCommandShell shell = new MacroCommandShell(this); >+ shell.load(node, lineTable); >+ commands.add(shell); >+ } >+ >+ public void addCommandShell(MacroCommandShell cshell) { >+ commands.add(cshell); >+ } >+ >+ public void write(int indent, StringBuffer sb) { >+ /* If this shell command doesn't have any commands, then exit */ >+ if (commands == null || commands.size() <= 0) >+ return; >+ >+ /* <shell */ >+ MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, false, >+ false); >+ boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn(); >+ MacroUtil.addAttribute(sb, new String[] { >+ MacroConstants.DESCRIPTIVE_ATTRIBUTE, >+ MacroConstants.RESOLVER_ID_ATTRIBUTE, >+ MacroConstants.WIDGET_ID_ATTRIBUTE, >+ MacroConstants.REFERENCE_ID_ATTRIBUTE, >+ MacroConstants.RETURN_CODE_ATTRIBUTE }, new String[] { >+ getDescriptiveField(), >+ objectMineInUse ? null : getMacroObjectIdentifier() >+ .getObjectIdentifier().getResolverId(), >+ objectMineInUse ? null : getMacroObjectIdentifier() >+ .getObjectIdentifier().getWidgetId(), >+ objectMineInUse ? getCorrespondingMacroObjectDescriptor() >+ .getReferenceId() /* >+ * CHANGED BY ANY: use the ref id of >+ * the corresponing >+ * MacroObjectDescriptor rather than >+ * the id stored in the widgetId >+ */ >+ : null, String.valueOf(expectedReturnCode) }, false, true); >+ int cindent = indent + 1; >+ for (int i = 0; i < commands.size(); i++) { >+ IPersistable persistable = (IPersistable) commands.get(i); >+ persistable.writeStart(cindent, sb); >+ persistable.write(cindent, sb); >+ persistable.writeFinish(cindent, sb); >+ } >+ MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, true, >+ true); >+ } >+ >+ public String getDescriptiveField() { >+ return shellTitle == null ? null : MacroUtil >+ .normalizeDescriptiveField(MacroUtil.boundSize(shellTitle, >+ IMacroCommand.DESCRIPTIVE_FIELD_BOUND)); >+ } >+ >+ public void addEvent(Event event) { >+ if (event.widget instanceof Control) { >+ if (((Control) event.widget).isVisible() == false) >+ return; >+ } >+ >+ IMacroCommand command = null; >+ try { >+ command = MacroManager.getInstance().getMacroCommandFactory() >+ .createCommand(this, commands, event); >+ } catch (CoreException e) { >+ // it may be the case we are waiting for a verification command to >+ // be created, so notify a waiting listener (just in case) >+ MacroManager.getInstance().notifyVerificationListener( >+ e.getMessage()); >+ } >+ >+ // if we are waiting for a verification command, notify the listener >+ // that is was correctly created >+ if (command != null && command instanceof VerificationCommand) { >+ MacroManager.getInstance().notifyVerificationListener( >+ (VerificationCommand) command); >+ } >+ } >+ >+ /** >+ * Adds a wait command for as long as the last command is not already a wait >+ * (i.e. duplicate addition of wait commands are avoided through this >+ * method) >+ */ >+ public void addPause() { >+ WaitCommand command = new WaitCommand(this); >+ >+ Object lastCommand = null; >+ int commandSize = commands.size(); >+ boolean isLastCommandWait = false; >+ >+ if (commandSize <= 0) >+ return; >+ >+ lastCommand = commands.get(commandSize - 1); >+ int lastCmdInx = 2; >+ >+ /* >+ * Avoid MacroCommandShells that have no commands (since these will not >+ * be included as part of the macro) >+ */ >+ while (lastCommand instanceof MacroCommandShell >+ && ((MacroCommandShell) lastCommand).getCommands().size() <= 0) { >+ if (commandSize - lastCmdInx >= 0) >+ lastCommand = commands.get(commandSize - lastCmdInx); >+ else { >+ lastCommand = null; >+ break; >+ } >+ >+ lastCmdInx++; >+ } >+ >+ AbstractMacroCommand lastMacroCommand = null; >+ if (lastCommand instanceof AbstractMacroCommand) >+ lastMacroCommand = (AbstractMacroCommand) lastCommand; >+ >+ isLastCommandWait = lastMacroCommand != null >+ && lastMacroCommand.getType() == WaitCommand.TYPE; >+ if (commands.size() > 0 && !isLastCommandWait) { >+ commands.add(command); >+ } >+ } >+ >+ public void extractExpectedReturnCode() { >+ if (window != null) >+ expectedReturnCode = window.getReturnCode(); >+ } >+ >+ public boolean matchesReturnCode() { >+ if (window != null) { >+ return window.getReturnCode() == expectedReturnCode; >+ } >+ return true; >+ } >+ >+ public boolean isDisposed() { >+ return this.shell != null && this.shell.isDisposed(); >+ } >+ >+ public void close() { >+ if (this.shell != null && !this.shell.isDisposed()) >+ this.shell.close(); >+ } >+ >+ public boolean tracks(Shell shell) { >+ if (this.shell != null && this.shell.equals(shell)) >+ return true; >+ return false; >+ } >+ >+ public boolean playback(final Display display, Shell parent, >+ final IProgressMonitor monitor) throws CoreException { >+ if (parent instanceof Shell) { >+ this.shell = (Shell) parent; >+ this.display = display; >+ hookWindow(true); >+ } >+ >+ NestedShell nestedShell = null; >+ int commandSize = commands.size(); >+ monitor.beginTask("", commandSize); >+ final int commandTimeOut; >+ >+ int potentialTimeoutValue = MacroManager.getInstance() >+ .getCommandTimeoutThreshold(); >+ if (MacroManager.getInstance().getCommandTimeoutThreshold() > 0) >+ commandTimeOut = potentialTimeoutValue; >+ else >+ commandTimeOut = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD; >+ >+ for (int i = 0; i < commandSize; i++) { >+ currentCommandInx = i; >+ checkForInterruptions(); >+ Object c = commands.get(i); >+ final IPlayable playable = (IPlayable) c; >+ >+ /* >+ * If this is the last command of this macro command shell, then >+ * take out its entry in the shell queue >+ */ >+ if (isLastCommand(i)) { >+ if (getNestedShellQueue() != null >+ && getNestedShellQueue().size() > 0) { >+ if (lastNestedShellInx > 0) >+ lastNestedShellInx--; >+ removeNestedShell(0); >+ } >+ } >+ >+ /* >+ * If this command is a nested shell, then we need to wait until it >+ * completes before proceeding to the next command. >+ */ >+ if (c instanceof MacroCommandShell) { >+ MacroCommandShell nestedCommandShell = (MacroCommandShell) c; >+ // System.out.println("NESTED SHELL WAIT: " + >+ // nestedCommandShell.getId()); >+ Object lastNestedCommand = null; >+ Object currentNestedCommand = null; >+ synchronized (nestedCommandShell) { >+ /* >+ * Give each command in the nested shell a maximum of >+ * commandTimeOut to execute >+ */ >+ while (!nestedCommandShell.isComplete() >+ && (currentNestedCommand == null || lastNestedCommand != currentNestedCommand) >+ && !interruptProcess) { >+ try { >+ nestedCommandShell.wait(commandTimeOut); >+ lastNestedCommand = currentNestedCommand; >+ currentNestedCommand = nestedCommandShell >+ .getCommandBeingExecuted(); >+ } catch (InterruptedException e) { >+ /* Handled by next set of code */ >+ } >+ } >+ >+ /* Indicate an error if the nested shell never completed */ >+ if (!nestedCommandShell.isComplete()) { >+ synchronized (mutualGlobalLock) { >+ interruptProcess = true; >+ if (interruptedException == null) >+ interruptedException = new CoreException( >+ new Status( >+ IStatus.ERROR, >+ GuiPlugin.getID(), >+ 0, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_NEST_TOUT, >+ nestedCommandShell >+ .getMacroObjectIdentifier() >+ .getObjectIdentifier() >+ .toString()), >+ null)); >+ } >+ >+ continue; /* Interrupt the normal flow */ >+ } >+ // System.out.println("NESTED SHELL FINISH: " + >+ // nestedCommandShell.getId()); >+ } >+ } >+ >+ if (i < commandSize - 1) { >+ /* >+ * Ali M.: We need to iterate through all the shell commands and >+ * register listeners before it's too late. It's not sufficient >+ * to just register a listener with the next command >+ */ >+ int counter = 1; >+ IPlayable next = (IPlayable) commands.get(i + counter); >+ while (next instanceof MacroCommandShell) { >+ /* >+ * This command will open a new shell. Add a listener before >+ * it is too late >+ */ >+ MacroCommandShell nestedCommand = (MacroCommandShell) next; >+ >+ if (!nestedCommand.isListenerRegistered()) { >+ nestedShell = new NestedShell(display, nestedCommand, >+ new SubProgressMonitor(monitor, 1)); >+ final NestedShell fnestedShell = nestedShell; >+ >+ /* >+ * If this is a child of the previous shell, then it >+ * takes precedence. If it's a sibling, then it should >+ * go to the end of the queue. >+ */ >+ nestedCommand.setListenerRegistered(true); >+ if (nestedShellQueue.size() > 0 >+ && ((NestedShell) nestedShellQueue.get(0)) >+ .isParent(nestedCommand)) { >+ addNestedShell(0, fnestedShell); >+ lastNestedShellInx = 0; >+ } else { >+ if (nestedShellQueue.size() > 0) >+ addNestedShell(++lastNestedShellInx, >+ fnestedShell); >+ else >+ addNestedShell(fnestedShell); >+ } >+ >+ display.syncExec(new Runnable() { >+ >+ public void run() { >+ // System.out.println("ADDED"); >+ display.addFilter(SWT.Activate, fnestedShell); >+ } >+ }); >+ } >+ counter++; >+ next = (i + counter <= commandSize - 1 ? (IPlayable) commands >+ .get(i + counter) >+ : null); >+ } >+ } >+ if (playable instanceof AbstractMacroCommand) { >+ final boolean last = i == commandSize - 1; >+ >+ class WakeUpOperaion implements Runnable { >+ >+ private AbstractMacroCommand command; >+ private boolean invalidate; >+ >+ public WakeUpOperaion(AbstractMacroCommand command) { >+ this.command = command; >+ invalidate = false; >+ } >+ >+ public void run() { >+ if (!invalidate >+ && MacroCommandShell.lastCommandLineExecuted == command >+ .getStartLine()) { >+ /* >+ * Ali M.: A command just timed-out. We need to >+ * indicate the error and wakeup the thread >+ */ >+ synchronized (mutualGlobalLock) { >+ interruptProcess = true; >+ if (interruptedException == null) >+ interruptedException = new CoreException( >+ new Status( >+ IStatus.ERROR, >+ GuiPlugin.getID(), >+ 0, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, >+ command >+ .toString()), >+ null)); >+ } >+ >+ synchronized (mutualLock) { >+ mutualLock.notify(); >+ } >+ } >+ } >+ >+ public void invalidate() { >+ this.invalidate = true; >+ } >+ >+ } >+ WakeUpOperaion wakeupOpt = null; >+ if (i < commandSize - 1) { >+ wakeupOpt = new WakeUpOperaion( >+ (AbstractMacroCommand) playable); >+ final Runnable wakeupOperation = wakeupOpt; >+ display.asyncExec(new Runnable() { >+ >+ public void run() { >+ display.timerExec(commandTimeOut, wakeupOperation); >+ }; >+ >+ }); >+ } >+ >+ class RunCommandOperation implements Runnable { >+ >+ private boolean isComplete; >+ >+ public void run() { >+ try { >+ if (!macroCommandsBeingPlayed.contains(this)) >+ macroCommandsBeingPlayed.add(this); >+ >+ lastCommandLineExecuted = ((AbstractMacroCommand) playable) >+ .getStartLine(); >+ playInGUIThread(display, playable, last, monitor); >+ >+ macroCommandsBeingPlayed.remove(this); >+ isComplete = true; >+ synchronized (mutualLock) { >+ mutualLock.notify(); >+ } >+ } catch (Throwable e) { >+ macroCommandsBeingPlayed.remove(this); >+ synchronized (mutualGlobalLock) { >+ interruptProcess = true; >+ if (interruptedException == null) >+ interruptedException = e; >+ } >+ isComplete = true; >+ synchronized (mutualLock) { >+ mutualLock.notify(); >+ } >+ } >+ } >+ >+ public boolean isComplete() { >+ return isComplete; >+ } >+ >+ } >+ >+ RunCommandOperation runCommandOpt = new RunCommandOperation(); >+ >+ /* Run the command */ >+ synchronized (mutualLock) { >+ new Thread(runCommandOpt).start(); >+ long start = System.currentTimeMillis(); >+ long wakeUpTime = start; >+ long timeToSleep = commandTimeOut; >+ try { >+ while (!runCommandOpt.isComplete() && timeToSleep > 0 >+ && !interruptProcess) { >+ // System.out.println("WAITING on command: " + >+ // playable); >+ mutualLock.wait(timeToSleep); >+ wakeUpTime = System.currentTimeMillis(); >+ timeToSleep = timeToSleep - (wakeUpTime - start); >+ } >+ } catch (InterruptedException e) { >+ /* Doesn't need to be handled */ >+ } >+ >+ /* Indicate an error if command didn't complete */ >+ if (!runCommandOpt.isComplete()) { >+ synchronized (mutualGlobalLock) { >+ interruptProcess = true; >+ if (interruptedException == null) >+ interruptedException = new CoreException( >+ new Status( >+ IStatus.ERROR, >+ GuiPlugin.getID(), >+ 0, >+ NLS >+ .bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, >+ playable >+ .toString()), >+ null)); >+ } >+ } >+ /* >+ * Otherwise invalidate the wake up operation that was >+ * suppose to wake this command up >+ */ >+ else if (wakeupOpt != null) >+ wakeupOpt.invalidate(); >+ >+ // System.out.println("FINISHED WAITING on command: " + >+ // playable); >+ } >+ >+ monitor.worked(1); >+ } >+ } >+ >+ checkForInterruptions(); >+ shell = null; >+ >+ /* >+ * We made it out alive -- mark this as complete and wake any parents >+ * that are waiting upon our completion >+ */ >+ isComplete = true; >+ synchronized (this) { >+ this.notify(); >+ } >+ >+ macroCommandShellContainer.remove(this); >+ return true; >+ } >+ >+ private boolean isComplete() { >+ return isComplete; >+ } >+ >+ private Object getCommandBeingExecuted() { >+ if (commands == null || currentCommandInx >= commands.size()) >+ return null; >+ return commands.get(currentCommandInx); >+ } >+ >+ private void checkForInterruptions() throws CoreException { >+ if (interruptProcess) { >+ /* Wake up all threads in case they are asleep */ >+ if (!processTerminated) { >+ processTerminated = true; >+ interruptOperation(); >+ MacroCommandShell.macroStopped(); >+ MacroUtil.closeSecondaryShells(display); >+ } >+ >+ for (int i = 0; i < macroCommandShellContainer.size(); i++) { >+ synchronized (mutualLock) { >+ mutualLock.notify(); >+ } >+ >+ synchronized (macroCommandShellContainer.get(i)) { >+ macroCommandShellContainer.get(i).notify(); >+ } >+ } >+ >+ /* Try to close all nested shells */ >+ synchronized (mutualGlobalLock) { >+ if (interruptedException instanceof CoreException) >+ throw (CoreException) interruptedException; >+ throw new CoreException(new Status(IStatus.ERROR, GuiPlugin >+ .getID(), 0, >+ interruptedException.getLocalizedMessage(), >+ interruptedException)); >+ } >+ } >+ >+ } >+ >+ /** >+ * A helper method that walks through all macro command shells and >+ * interrupts their normal flow. >+ */ >+ private void interruptOperation() { >+ MacroCommandShell currentMacroShell = this; >+ while (currentMacroShell != null) { >+ Boolean lock = currentMacroShell.mutualLock; >+ synchronized (lock) { >+ lock.notify(); >+ } >+ >+ currentMacroShell = currentMacroShell.getParent(); >+ } >+ >+ } >+ >+ private boolean isLastCommand(int index) { >+ for (int i = index + 1; i < commands.size(); i++) { >+ if (commands.get(i) instanceof AbstractMacroCommand) >+ return false; >+ } >+ return true; >+ } >+ >+ private void playInGUIThread(final Display display, >+ final IPlayable playable, boolean last, >+ final IProgressMonitor monitor) throws CoreException { >+ final CoreException[] ex = new CoreException[1]; >+ >+ Runnable runnable = new Runnable() { >+ >+ public void run() { >+ try { >+ boolean status = playable.playback(display, >+ MacroCommandShell.this.shell, monitor); >+ >+ /* Something went wrong playing this item */ >+ if (!status) >+ ex[0] = createPlaybackException(playable, null); >+ else >+ MacroUtil.processDisplayEvents(display); >+ } catch (ClassCastException e) { >+ ex[0] = createPlaybackException(playable, e); >+ } catch (CoreException e) { >+ ex[0] = e; >+ } catch (SWTException e) { >+ /* Don't handle */ >+ } catch (Throwable error) { >+ ex[0] = createPlaybackException(playable, error); >+ } >+ } >+ }; >+ >+ if (playable instanceof WaitCommand) { >+ playable.playback(display, this.shell, monitor); >+ } else { >+ display.syncExec(runnable); >+ } >+ >+ try { >+ Thread.sleep(100); >+ } catch (InterruptedException e) { >+ } >+ >+ if (ex[0] != null) >+ throw ex[0]; >+ >+ } >+ >+ private CoreException createPlaybackException(IPlayable playable, >+ Throwable th) { >+ IStatus status = new Status(IStatus.ERROR, "org.eclipse.pde.ui.tests", >+ IStatus.OK, NLS.bind( >+ AutoGUIMessages.AUTO_GUI_ERROR_MACRO_COMMAND, playable >+ .toString()), th); >+ return new CoreException(status); >+ } >+ >+ public ArrayList getCommands() { >+ return commands; >+ } >+ >+ public boolean isListenerRegistered() { >+ return isListenerRegistered; >+ } >+ >+ public void setListenerRegistered(boolean isListenerRegistered) { >+ this.isListenerRegistered = isListenerRegistered; >+ } >+ >+ public static Vector getNestedShellQueue() { >+ return nestedShellQueue; >+ } >+ >+ public static void addNestedShell(int inx, NestedShell nestedShell) { >+ synchronized (nestedShellQueue) { >+ if (inx >= 0) >+ nestedShellQueue.add(inx, nestedShell); >+ else >+ nestedShellQueue.add(nestedShell); >+ } >+ } >+ >+ private static void addNestedShell(NestedShell fnestedShell) { >+ addNestedShell(-1, fnestedShell); >+ } >+ >+ public static void removeNestedShell(int inx) { >+ synchronized (nestedShellQueue) { >+ nestedShellQueue.remove(inx); >+ } >+ } >+ >+ public static void initializeForNewPlay() { >+ nestedShellQueue.clear(); >+ lastNestedShellInx = 0; >+ interruptProcess = false; >+ processTerminated = false; >+ interruptedException = null; >+ MouseEventCommand.init(); >+ macroCommandsBeingPlayed.clear(); >+ macroCommandShellContainer.clear(); >+ } >+ >+ public Shell getShell() { >+ return shell; >+ } >+ >+ public void writeStart(int indent, StringBuffer sb) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ public void writeFinish(int indent, StringBuffer sb) { >+ /* Doesn't need to be implemented */ >+ } >+ >+ public MacroCommandShell getParent() { >+ return parent; >+ } >+ >+ public void setParent(MacroCommandShell parent) { >+ this.parent = parent; >+ } >+ >+ public static void macroStopped() { >+ /* Walk through nested shell listeners and remove them if any exists */ >+ final Display display = GuiPlugin.getDefault().getWorkbench() >+ .getDisplay(); >+ display.syncExec(new Runnable() { >+ >+ public void run() { >+ for (int i = 0, nestedShellListenerSize = nestedShellQueue >+ .size(); i < nestedShellListenerSize; i++) { >+ display.removeFilter(SWT.Activate, >+ (NestedShell) nestedShellQueue.get(i)); >+ } >+ } >+ }); >+ } >+ >+ public static Vector getMacroCommandsBeingPlayed() { >+ return macroCommandsBeingPlayed; >+ } >+ >+ private static class NestedShell implements Listener, Runnable { >+ >+ private MacroCommandShell cshell; >+ >+ private Display display; >+ >+ private Shell nshell; >+ >+ private boolean released; >+ >+ private CoreException exception; >+ >+ private IProgressMonitor monitor; >+ >+ private boolean served; >+ >+ public NestedShell(Display display, MacroCommandShell cshell, >+ IProgressMonitor monitor) { >+ this.display = display; >+ this.cshell = cshell; >+ this.monitor = monitor; >+ } >+ >+ public void handleEvent(Event event) { >+ try { >+ if (event.widget instanceof Shell) { >+ // shell activated >+ Shell shell = (Shell) event.widget; >+ // ANY: CHANGED: IPath path = new >+ // Path(UIObjectResolverUtil.getShellId(shell,null).toString()); >+ // String sid = path.toString(); >+ String sid = MacroObjectResolver.resolve(shell, >+ new MacroObject(new UIObject(shell))) >+ .getObjectIdentifier().getWidgetId(); >+ >+ /* Debug */ >+ // System.out.println(); >+ // System.out.println(sid + " : " + cshell.getId()); >+ // if (MacroCommandShell.getNestedShellQueue() != null && >+ // MacroCommandShell.getNestedShellQueue().size() > 0) >+ // System.out.println("Is Served: " + >+ // ((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed()); >+ // System.out.println(this + " : " + >+ // MacroCommandShell.getNestedShellQueue().get(0)); >+ // System.out.println(); >+ if (sid.equals(cshell.getMacroObjectIdentifier() >+ .getObjectIdentifier().getWidgetId()) >+ && (MacroCommandShell.getNestedShellQueue() == null >+ || MacroCommandShell.getNestedShellQueue() >+ .size() <= 0 || (!((NestedShell) MacroCommandShell >+ .getNestedShellQueue().get(0)).isServed() && this >+ .equals(MacroCommandShell >+ .getNestedShellQueue().get(0))))) { >+ // System.out.println("REMOVED FILTER: " + >+ // cshell.getId()); >+ shell.getDisplay().removeFilter(SWT.Activate, this); >+ released = true; >+ this.nshell = shell; >+ >+ /* >+ * We need to start this in a separate thread. >+ * MacroCommandShells should not be played in UI threads >+ * (otherwise wait commands will not work properly) >+ */ >+ this.setServed(true); >+ new Thread(this).start(); >+ } >+ } >+ } catch (Throwable t) { >+ // System.out.println("REMOVED filter"); >+ /* Something unexpected has happened -- Remove this listener */ >+ event.display.removeFilter(SWT.Activate, this); >+ } >+ } >+ >+ public void setServed(boolean served) { >+ this.served = served; >+ } >+ >+ public boolean isServed() { >+ return served; >+ } >+ >+ public boolean getResult() { >+ return cshell.matchesReturnCode(); >+ } >+ >+ public boolean isReleased() { >+ return released; >+ } >+ >+ public void run() { >+ try { >+ cshell.playback(display, nshell, monitor); >+ } catch (CoreException e) { >+ synchronized (mutualGlobalLock) { >+ interruptProcess = true; >+ if (interruptedException == null) >+ interruptedException = e; >+ } >+ >+ synchronized (cshell.mutualLock) { >+ cshell.mutualLock.notify(); >+ } >+ } >+ } >+ >+ public CoreException getException() { >+ return exception; >+ } >+ >+ public boolean isParent(MacroCommandShell macroCommandShell) { >+ return macroCommandShell.getParent().equals(cshell); >+ } >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/IUIObjectDeprecatedDeresolvingFacade.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/IUIObjectDeprecatedDeresolvingFacade.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/IUIObjectDeprecatedDeresolvingFacade.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/IUIObjectDeprecatedDeresolvingFacade.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,38 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport; >+ >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+ >+ >+/** >+ * Used to migrate the old WidgetResolvers to the new IUIObjectResolverDelegate interface >+ * while preserving their implementation. >+ * @author ANy >+ * @version $Revision$ >+ * >+ */ >+public interface IUIObjectDeprecatedDeresolvingFacade { >+ >+ /** >+ * Given an object and an id, this method should return true if and only if the id of object as determined by this resolver equals the 'id' passed >+ * in. >+ * >+ * @param object >+ * An object >+ * @param objectId >+ * The being searched for >+ * @return true iff object's id is equalled to 'id' >+ */ >+ public boolean foundWidget(Widget object, IUIObjectIdentifier objectId); >+} >Index: schema/macroCommandFactory.exsd >=================================================================== >RCS file: schema/macroCommandFactory.exsd >diff -N schema/macroCommandFactory.exsd >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ schema/macroCommandFactory.exsd 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,111 @@ >+<?xml version='1.0' encoding='UTF-8'?> >+<!-- Schema file written by PDE --> >+<schema targetNamespace="org.eclipse.tptp.test.auto.gui"> >+<annotation> >+ <appInfo> >+ <meta.schema plugin="org.eclipse.tptp.test.auto.gui" id="macroCommandFactory" name="macroCommandFactory"/> >+ </appInfo> >+ <documentation> >+ Extension point to replace the macro command factory with a custom implementation. >+ </documentation> >+ </annotation> >+ >+ <element name="extension"> >+ <complexType> >+ <sequence> >+ <element ref="macroCommandFactory"/> >+ </sequence> >+ <attribute name="point" type="string" use="required"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="id" type="string"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="name" type="string"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ <appInfo> >+ <meta.attribute translatable="true"/> >+ </appInfo> >+ </annotation> >+ </attribute> >+ </complexType> >+ </element> >+ >+ <element name="macroCommandFactory"> >+ <complexType> >+ <attribute name="id" type="string" use="required"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ </annotation> >+ </attribute> >+ <attribute name="class" type="string" use="required"> >+ <annotation> >+ <documentation> >+ >+ </documentation> >+ <appInfo> >+ <meta.attribute kind="java" basedOn=":org.eclipse.tptp.test.auto.gui.commands.factory.IMacroCommandFactory"/> >+ </appInfo> >+ </annotation> >+ </attribute> >+ <attribute name="priority" type="string" use="required"> >+ <annotation> >+ <documentation> >+ The priority of the factory. The factory with the highest priority is loaded and used, all others are disregarded. >+ </documentation> >+ </annotation> >+ </attribute> >+ </complexType> >+ </element> >+ >+ <annotation> >+ <appInfo> >+ <meta.section type="since"/> >+ </appInfo> >+ <documentation> >+ [Enter the first release in which this extension point appears.] >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appInfo> >+ <meta.section type="examples"/> >+ </appInfo> >+ <documentation> >+ [Enter extension point usage example here.] >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appInfo> >+ <meta.section type="apiInfo"/> >+ </appInfo> >+ <documentation> >+ [Enter API information here.] >+ </documentation> >+ </annotation> >+ >+ <annotation> >+ <appInfo> >+ <meta.section type="implementation"/> >+ </appInfo> >+ <documentation> >+ [Enter information about supplied implementation of this extension point.] >+ </documentation> >+ </annotation> >+ >+ >+</schema> >Index: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,12 @@ >+package org.eclipse.tptp.test.auto.gui.internal.core; >+ >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader; >+ >+public class WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter extends UIObjectResolverDelegateLoader { >+ >+ public WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter(WidgetResolverLoader widgetResolverLoader) { >+ super(widgetResolverLoader.getId(), new WidgetResolverToUIObjectResolverDelegateAdapter(widgetResolverLoader.getWidgetResolver()), widgetResolverLoader.getPriority()); >+ } >+ >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/IPersistable.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/IPersistable.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/IPersistable.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/IPersistable.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,72 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+import java.util.Hashtable; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.w3c.dom.Node; >+ >+ >+ >+/** >+ * A writable object is capable of serializing itself to string and writing the string >+ * version to a PrintWriter that is passed to parameters to the methods that are described >+ * below. It is also capable of loading itself from a given node. >+ * <br/> >+ * The ideal order of the method invocations are: >+ * <ul> >+ * <li> writeStart(String indent, gPrintWriter writer) </li> >+ * <li> write(String indent, PrintWriter writer) </li> >+ * <li> writeFinish(String indent, PrintWriter writer) </li> >+ * </ul> >+ */ >+public interface IPersistable >+{ >+ /** >+ * Invoked at start of the write of a writable object >+ * >+ * @param indent The indents >+ * @param sb The buffer that the string serialization should be written to >+ */ >+ public void writeStart(int indent, StringBuffer sb); >+ >+ >+ /** >+ * Invoked after writeStart >+ * >+ * @param indent The indents >+ * @param sb The buffer that the string serialization should be written to >+ */ >+ public void write(int indent, StringBuffer sb); >+ >+ >+ /** >+ * Invoked in the end of the write of a writable object >+ * >+ * @param indent The indents >+ * @param sb The buffer that the string serialization should be written to >+ */ >+ public void writeFinish(int indent, StringBuffer sb); >+ >+ /** >+ * Invoked to load the macro instruction based on its corresponding XML node. >+ * >+ * @param node >+ * The XML node representing this macro instruction >+ * @param lineTable >+ * Contains line level information >+ * >+ * @throws CoreException >+ * In case of an unexpected error >+ */ >+ public void load(Node node, Hashtable lineTable) throws CoreException; >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/IMacroInstruction.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/IMacroInstruction.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/IMacroInstruction.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/IMacroInstruction.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,34 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+ >+/** >+ * Represents a macro instruction. The instruction is expected to both be writable and playable. >+ * >+ * @author Ali Mehregani >+ */ >+public interface IMacroInstruction extends IPersistable, IPlayable { >+ >+ /** >+ * Returns the starting line number of this macro instruction in the macro script that it belongs to. >+ * >+ * @return The starting line >+ */ >+ public int getStartLine(); >+ >+ /** >+ * Returns the last line number of this macro instruction in the macro script that it belongs to. >+ * >+ * @return The last line >+ */ >+ public int getStopLine(); >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/util/VerificationHookClassLoader.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/util/VerificationHookClassLoader.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/util/VerificationHookClassLoader.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/util/VerificationHookClassLoader.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,104 @@ >+/******************************************************************************* >+ * Copyright (c) 2005, 2006 IBM Corporation and others. >+ * 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 >+ * $Id: VerificationHookClassLoader.java,v 1.2 2006/07/14 23:17:02 amehregani Exp $ >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.util; >+ >+import java.net.URL; >+import java.net.URLClassLoader; >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+ >+/** >+ * A custom class loader that is used to resolve a class that the verificaiton hook is in along >+ * with any other classes that are imported by the verification class. >+ * >+ * @author Ali Mehregani >+ */ >+public class VerificationHookClassLoader extends URLClassLoader >+{ >+ /* The plugins that the verification plugin requires */ >+ private Vector reqPluginNames; >+ >+ public VerificationHookClassLoader (URL[] urls, ClassLoader parent, Vector requiredPluginNames) >+ { >+ super (urls, parent); >+ reqPluginNames = requiredPluginNames; >+ } >+ >+ >+ /** >+ * Invoked when a class can't be resolved by the upper level class loaders associated with >+ * this class. >+ */ >+ protected Class findClass(final String name) >+ throws ClassNotFoundException >+ { >+ >+ /* Try and walk through the required plugins of the plugin >+ * containing the test suite */ >+ try >+ { >+ Class classFile = loadFromReqPlugins(name, 0); >+ if (classFile != null) >+ return classFile; >+ } >+ catch (Throwable t) >+ { >+ /* Doesn't need to be handled */ >+ } >+ >+ >+ try >+ { >+ Class classFile = super.findClass(name); >+ if (classFile != null) >+ return classFile; >+ } >+ catch (Throwable t) >+ { >+ /* Doesn't need to be handled */ >+ } >+ >+ >+ >+ throw new ClassNotFoundException (NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_FS, name)); >+ } >+ >+ >+ /** >+ * Attempt to load the class from the required plugins. >+ * >+ * @param name >+ * @param inx >+ * @return >+ */ >+ private Class loadFromReqPlugins(String name, int inx) >+ { >+ try >+ { >+ if (reqPluginNames == null || inx >= reqPluginNames.size()) >+ return null; >+ >+ Class classFile = Platform.getBundle(((String)reqPluginNames.get(inx))).loadClass(name); >+ if (classFile != null) >+ return classFile; >+ } >+ catch (Throwable t) >+ { >+ /* Handled by next statement */ >+ } >+ >+ return loadFromReqPlugins(name, inx + 1); >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/AdaptiveUIObjectResolverDelegate.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/AdaptiveUIObjectResolverDelegate.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/AdaptiveUIObjectResolverDelegate.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/AdaptiveUIObjectResolverDelegate.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,650 @@ >+/******************************************************************************* >+ * Copyright (c) 2005, 2007 IBM Corporation and others. >+ * 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 >+ * $Id: AdaptiveUIObjectResolverDelegate.java,v 1.6 2007/04/26 20:03:22 paules Exp $ >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate; >+ >+import java.io.IOException; >+import java.io.InputStream; >+import java.lang.reflect.Method; >+import java.net.URL; >+import java.util.Hashtable; >+import java.util.Vector; >+ >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.hyades.test.common.util.XMLUtil; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages; >+import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil; >+import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager; >+import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants; >+import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.WeightedPropertyUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport; >+import org.osgi.framework.Bundle; >+import org.w3c.dom.Element; >+import org.w3c.dom.NodeList; >+ >+/** >+ * The following widget resolver attempts to resolve widgets using a static XML >+ * file stored under the auto-gui folder under this plugin. >+ * >+ * @since 4.1 >+ * @author Ali Mehregani >+ */ >+public class AdaptiveUIObjectResolverDelegate implements >+ IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade { >+ >+ /** >+ * The id of this resolver -- must be in sync with the id registered with >+ * the widgetResolver extension. >+ */ >+ private static final String ID = "org.eclipse.tptp.test.auto.gui.adaptive"; >+ >+ /** The assumed file name relative to this plugin */ >+ public final static String WIDGET_REG_FILE = "auto-gui/widgetReg.xml"; >+ >+ /** The widget registerations */ >+ private IWidgetRegistration widgetReg; >+ >+ public AdaptiveUIObjectResolverDelegate() { >+ widgetReg = new WidgetRegistration(this, WIDGET_REG_FILE); >+ } >+ >+ public IUIObjectIdentifier resolve(Object context, IUIObject object) >+ throws CoreException { >+ if (object.getObject() != null) >+ return null; >+ >+ widgetReg.load(); >+ IUIObjectIdentifier widgetId = widgetReg >+ .getWidgetId(object.getWidget()); >+ return widgetId; >+ } >+ >+ public IUIObject deresolve(Object context, >+ IUIObjectIdentifier uiObjectIdentifier) throws CoreException { >+ return UIObjectDeprecatedDeresolvingSupport.deresolve(context, >+ uiObjectIdentifier); >+ } >+ >+ /** >+ * Clients have the option of overwriting this in order to be able to locate >+ * the widget them self in the registeration entries that exist. >+ */ >+ public WidgetRegValue findWidget(Hashtable registerations, Widget widget) { >+ return null; >+ } >+ >+ public class WidgetRegistration implements IWidgetRegistration { >+ >+ /* The file name */ >+ private String fileName; >+ >+ /* The last size of the file when it was properly read */ >+ private long lastModifiedDate; >+ >+ /* >+ * The file size (stored in case there was an error last time reading >+ * the file >+ */ >+ private long lastModifiedDateDetected; >+ >+ /* Indicates if there was an error in parsing the file */ >+ private boolean errorOccurred; >+ >+ /* >+ * The data structures holding the registered widgets. Key = class name; >+ * Value = WidgetRegValue >+ */ >+ private Hashtable regWidgets; >+ >+ /* The global match threshold */ >+ private float globalMatchThreshold; >+ >+ /* The class name used for the default entry */ >+ public static final String DEFAULT_ENTYR = "0_DEFAULT_ENTRY"; >+ >+ /* The adaptive widget resolver used as the driver for resolving widgets */ >+ private AdaptiveUIObjectResolverDelegate adaptiveWidgetResolver; >+ >+ public WidgetRegistration( >+ AdaptiveUIObjectResolverDelegate adaptiveWidgetResolver, >+ String fileName) { >+ this.fileName = fileName; >+ this.lastModifiedDate = 0; >+ this.lastModifiedDateDetected = 0; >+ this.errorOccurred = false; >+ this.regWidgets = new Hashtable(); >+ this.adaptiveWidgetResolver = adaptiveWidgetResolver; >+ } >+ >+ public void load() { >+ InputStream regXMLInputStream = null; >+ try { >+ >+ Bundle guiBundle = GuiPlugin.getDefault().getBundle(); >+ long currentModifiedDate = guiBundle.getLastModified();// added >+ // for >+ // defect >+ // 169733 >+ // Liz >+ // Dancy >+ >+ /* >+ * Checking the file size doesn't guarantee to us that the file >+ * hasn't changed. This is the best we can do. Replace this with >+ * last modified date if API is available. >+ */ >+ if (currentModifiedDate > 0 >+ && (currentModifiedDate == lastModifiedDate || (errorOccurred && lastModifiedDateDetected == currentModifiedDate))) >+ return; >+ >+ URL regFileURL = GuiPlugin.getDefault().getBundle().getEntry( >+ fileName); >+ lastModifiedDateDetected = currentModifiedDate; >+ >+ /* Parse the XML file */ >+ regXMLInputStream = regFileURL.openStream(); >+ Element rootElement = XMLUtil.loadDom(regXMLInputStream, >+ "widgetResolverRule"); >+ if (rootElement == null) { >+ lastModifiedDate = 0; >+ errorOccurred = true; >+ >+ /* Display an error message if we are recording */ >+ if (MacroManager.getInstance().getGlobalState() == ModeConstants.RECORDING_MODE) { >+ AutoGUIUtil.showMessage( >+ AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, >+ MessageDialog.WARNING); >+ } >+ return; >+ } >+ this.regWidgets.clear(); >+ parseRegFile(rootElement); >+ lastModifiedDate = currentModifiedDate; >+ } catch (Throwable t) { >+ /* Set the file size to zero to invalidate this widget resolver */ >+ lastModifiedDate = 0; >+ errorOccurred = true; >+ >+ /* Display an error message if we are recording */ >+ if (MacroManager.getInstance().getGlobalState() == ModeConstants.RECORDING_MODE) { >+ AutoGUIUtil.showMessage( >+ AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, >+ AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, >+ MessageDialog.WARNING); >+ } >+ } finally { >+ if (regXMLInputStream != null) { >+ try { >+ regXMLInputStream.close(); >+ } catch (IOException e) { >+ /* Ignore the error */ >+ } >+ } >+ } >+ >+ } >+ >+ public float getGlobalThreshold() { >+ return globalMatchThreshold; >+ } >+ >+ /** >+ * parse the registation file that has already been loaded >+ */ >+ private void parseRegFile(Element rootElement) { >+ if (rootElement == null) >+ return; >+ >+ NodeList classList = XMLUtil >+ .getChildrenByName(rootElement, "class"); >+ parseClassElements(classList); >+ globalMatchThreshold = Float.parseFloat(XMLUtil.getValue( >+ rootElement, "globalMatchThreshold")); >+ NodeList defaultList = XMLUtil.getChildrenByName(rootElement, >+ "default"); >+ parseDefaultElements(defaultList); >+ } >+ >+ private void parseDefaultElements(NodeList defaultList) { >+ if (defaultList == null || defaultList.getLength() < 1) >+ return; >+ >+ /* We only expect one default element */ >+ if (defaultList.item(0) instanceof Element) { >+ Element defaultElement = (Element) defaultList.item(0); >+ NodeList methodList = XMLUtil.getChildrenByName(defaultElement, >+ "method"); >+ WidgetRegValue widgetReg = new WidgetRegValue(); >+ >+ parseMethod(methodList, widgetReg); >+ if (widgetReg != null) >+ regWidgets.put(DEFAULT_ENTYR, widgetReg); >+ >+ } >+ } >+ >+ /** >+ * Parse the class elements >+ */ >+ private void parseClassElements(NodeList classList) { >+ if (classList == null || classList.getLength() <= 0) >+ return; >+ >+ for (int i = 0; i < classList.getLength(); i++) { >+ if (classList.item(i) instanceof Element) { >+ >+ Element classElement = (Element) classList.item(i); >+ String className = XMLUtil.getValue(classElement, "name"); >+ NodeList methodList = XMLUtil.getChildrenByName( >+ classElement, "method"); >+ WidgetRegValue widgetReg = new WidgetRegValue(); >+ String matchThreshold = XMLUtil.getValue(classElement, >+ "matchThreshold"); >+ if (matchThreshold != null) >+ widgetReg.setClassMatchThreshold(Float >+ .parseFloat(matchThreshold)); >+ >+ parseMethod(methodList, widgetReg); >+ if (widgetReg != null) >+ regWidgets.put(className, widgetReg); >+ >+ } >+ } >+ } >+ >+ /** >+ * Parse the method element and return a widget registration entry >+ * >+ * @param methodList >+ * The method list >+ * @param widgetReg >+ * the widget registration entry that will be augmented >+ * @return A widget registeration entry >+ */ >+ private void parseMethod(NodeList methodList, WidgetRegValue widgetReg) { >+ if (methodList == null || methodList.getLength() <= 0) >+ return; >+ >+ for (int i = 0; i < methodList.getLength(); i++) { >+ if (methodList.item(i) instanceof Element) { >+ Element methodElement = (Element) methodList.item(i); >+ String methodName = XMLUtil.getValue(methodElement, "name"); >+ float weight = Float.parseFloat(XMLUtil.getValue( >+ methodElement, "weight")); >+ PropertyValue propertyVal = new PropertyValue(); >+ propertyVal.setWeight(weight); >+ >+ NodeList argumentList = XMLUtil.getChildrenByName( >+ methodElement, "argument"); >+ if (argumentList != null) >+ parseArguments(argumentList, propertyVal); >+ >+ widgetReg.addProperty(methodName, propertyVal); >+ } >+ } >+ } >+ >+ /** >+ * Parse the arguments >+ * >+ * @param argumentList >+ * The arugment list >+ * @param propertyVal >+ * The property value entry that will be augmented to. >+ */ >+ private void parseArguments(NodeList argumentList, >+ PropertyValue propertyVal) { >+ if (argumentList == null || argumentList.getLength() <= 0) >+ return; >+ >+ Vector arguments = new Vector(); >+ for (int i = 0; i < argumentList.getLength(); i++) { >+ if (argumentList.item(i) instanceof Element) { >+ Element argumentElement = (Element) argumentList.item(i); >+ String argumentValue = XMLUtil.getValue(argumentElement, >+ "value"); >+ arguments.add(argumentValue); >+ } >+ } >+ >+ propertyVal.setArguments(arguments); >+ } >+ >+ public IUIObjectIdentifier getWidgetId(Widget widget) { >+ /* >+ * Use this resolver if we were able to successfully resolve parse >+ * the XML file >+ */ >+ if (lastModifiedDate > 0) { >+ /* >+ * First attempt the widget itself. If that fails, then try its >+ * data attribute >+ */ >+ Object data = widget; >+ >+ WidgetRegValue widgetValue = (WidgetRegValue) regWidgets >+ .get(data.getClass().getName()); >+ if (widgetValue == null && widget.getData() != null) { >+ data = widget.getData(); >+ widgetValue = (WidgetRegValue) regWidgets.get(data >+ .getClass().getName()); >+ >+ /* >+ * If that fails, then walk throught the class heirarchy >+ * (the interafaces and superclasses >+ */ >+ if (widgetValue == null) { >+ widgetValue = walkThroughClassHeirarchy(data.getClass()); >+ >+ } >+ } >+ >+ /* >+ * As a final resolution, try and call the driver class to >+ * resolve the widget >+ */ >+ if (widgetValue == null) >+ widgetValue = adaptiveWidgetResolver.findWidget(regWidgets, >+ widget); >+ >+ Vector propertyWeightPair = new Vector(5); >+ >+ boolean specificValidEntry = false; >+ boolean defaultValidEntry = false; >+ >+ float threshold = 0; >+ if (widgetValue != null) { >+ threshold = widgetValue.getClassMatchThreshold(); >+ if (threshold == 0) >+ threshold = globalMatchThreshold; >+ >+ /* Specific properties associated with this type */ >+ specificValidEntry = appendProperties(data, >+ propertyWeightPair, widgetValue); >+ } >+ >+ /* Default properties */ >+ Vector defaultEntries = new Vector(); >+ defaultValidEntry = appendProperties(widget, defaultEntries, >+ (WidgetRegValue) regWidgets.get(DEFAULT_ENTYR), true); >+ if (defaultValidEntry) >+ propertyWeightPair.addAll(propertyWeightPair); >+ >+ /* >+ * Return null if we weren't able to get any of the widgets >+ * properties >+ */ >+ if (propertyWeightPair.size() <= 0) >+ return null; >+ >+ if (specificValidEntry || defaultValidEntry) { >+ WeightedPropertyUIObjectIdentifier adaptiveWidgetId = new WeightedPropertyUIObjectIdentifier( >+ propertyWeightPair.toArray(), threshold, ID); >+ return adaptiveWidgetId; >+ } >+ return null; >+ } >+ >+ return null; >+ } >+ >+ private WidgetRegValue walkThroughClassHeirarchy(Class widgetClass) { >+ WidgetRegValue widgetValue = null; >+ >+ widgetValue = (WidgetRegValue) regWidgets >+ .get(widgetClass.getName()); >+ if (widgetValue != null) >+ return widgetValue; >+ >+ Class[] interfaces = widgetClass.getInterfaces(); >+ >+ /* Try the interfaces first */ >+ for (int i = 0; i < interfaces.length; i++) { >+ widgetValue = (WidgetRegValue) regWidgets.get(interfaces[i] >+ .getName()); >+ widgetValue = (widgetValue == null ? walkThroughClassHeirarchy(interfaces[i]) >+ : widgetValue); >+ if (widgetValue != null) >+ return widgetValue; >+ } >+ >+ /* We failed with the interfaces, now try the super class */ >+ Class extendedClass = widgetClass.getSuperclass(); >+ if (extendedClass != null) >+ widgetValue = walkThroughClassHeirarchy(extendedClass); >+ >+ return widgetValue; >+ } >+ >+ private boolean appendProperties(Object data, >+ Vector propertyWeightPair, WidgetRegValue widgetValue) { >+ return appendProperties(data, propertyWeightPair, widgetValue, >+ false); >+ } >+ >+ private boolean appendProperties(Object data, >+ Vector propertyWeightPair, WidgetRegValue widgetValue, >+ boolean isDefault) { >+ boolean validEntry = false; >+ if (widgetValue == null) >+ return false; >+ >+ Vector properties = widgetValue.getProperties(); >+ for (int i = 0, propertySize = properties.size(); i < propertySize; i++) { >+ String property = (String) properties.get(i); >+ PropertyValue propertyValue = widgetValue >+ .getPropertyValue(property); >+ String retValue = invokeProperty(data, property, propertyValue); >+ >+ if ((retValue == null || retValue.length() <= 0) && isDefault) >+ retValue = invokeProperty(((Widget) data).getData(), >+ property, propertyValue); >+ >+ /* Don't add it if the return value is null or of zero length */ >+ if (retValue == null || retValue.length() <= 0) >+ retValue = "null"; /* >+ * Set the value to the literal string >+ * 'null' >+ */ >+ else >+ validEntry = true; >+ >+ propertyWeightPair.add(new Object[] { retValue, >+ String.valueOf(propertyValue.getWeight()) }); >+ } >+ return validEntry; >+ } >+ >+ /** >+ * Invoke the appropriate method to get the property value >+ * >+ * @param data >+ * The data corresponding to the widget or the data attribute >+ * of the widget >+ * @param theMethod >+ * The method corresponding to the property value >+ * @param propertyValue >+ * The property information container >+ * >+ * @return The returned value of the method corresponding to the >+ * argument >+ */ >+ private String invokeProperty(Object data, String theMethod, >+ PropertyValue propertyValue) { >+ try { >+ if (data == null) { >+ return null; >+ } >+ >+ Class theClass = data.getClass(); >+ int paramCount = 0; >+ Vector args = propertyValue.getArguments(); >+ if (args != null && args.size() > 0) >+ paramCount = args.size(); >+ >+ /* We only support method with string parameters */ >+ Class[] params = new Class[paramCount]; >+ for (int i = 0; i < params.length; i++) >+ params[i] = String.class; >+ >+ Method method = theClass.getMethod(theMethod, params); >+ >+ Object[] methodArgs = null; >+ if (paramCount > 0) >+ methodArgs = propertyValue.getArguments().toArray(); >+ >+ Object retValue = method.invoke(data, methodArgs); >+ if (retValue != null) { >+ return retValue.toString(); >+ } >+ return null; >+ } catch (Throwable t) { >+ /* Return null if in case we can retrieve the property value */ >+ return null; >+ } >+ >+ } >+ >+ public WidgetRegValue getDefaultWidgetReg() { >+ if (regWidgets == null) >+ return null; >+ return (WidgetRegValue) regWidgets.get(DEFAULT_ENTYR); >+ } >+ >+ } >+ >+ /** >+ * Can be used to provide any alternative implementation of how the widget >+ * registration file is loaded and queried. >+ * >+ * @author Ali Mehregani >+ */ >+ public interface IWidgetRegistration { >+ >+ /** >+ * Used to load the necessary file and store the data in a datastructure >+ * that will later be used to query the registrations. >+ */ >+ public void load(); >+ >+ /** >+ * Retrieve the widget id from the registrations >+ * >+ * @param widget >+ * The widget in question >+ * @return The persistent identifier for the widget >+ */ >+ public IUIObjectIdentifier getWidgetId(Widget widget); >+ } >+ >+ /** >+ * A container class for the registeration value of a widget >+ * >+ * @author Ali Mehregani >+ */ >+ private class WidgetRegValue { >+ >+ /* Key = method names, value = propertyValue */ >+ private Hashtable properties; >+ >+ /* Class match treshold */ >+ private float classMatchThreshold; >+ >+ /* >+ * This vector is used to preserve the ordering of the properties >+ * inserted in the hashtable >+ */ >+ private Vector hashKeys; >+ >+ public WidgetRegValue() { >+ properties = new Hashtable(); >+ classMatchThreshold = 0; >+ hashKeys = new Vector(); >+ } >+ >+ public Vector getProperties() { >+ return hashKeys; >+ } >+ >+ public PropertyValue getPropertyValue(String propertyValue) { >+ return (PropertyValue) properties.get(propertyValue); >+ } >+ >+ public PropertyValue getPropertyValue(int inx) { >+ if (inx >= hashKeys.size()) >+ return null; >+ return (PropertyValue) properties.get(hashKeys.get(inx)); >+ } >+ >+ public void addProperty(String methodName, PropertyValue propertyValue) { >+ hashKeys.add(methodName); >+ properties.put(methodName, propertyValue); >+ } >+ >+ public float getClassMatchThreshold() { >+ return classMatchThreshold; >+ } >+ >+ public void setClassMatchThreshold(float classMatchThreshold) { >+ this.classMatchThreshold = classMatchThreshold; >+ } >+ >+ } >+ >+ /** >+ * Container class for property values >+ * >+ * @author Ali Mehregani >+ */ >+ private class PropertyValue { >+ >+ private Vector arguments; >+ private float weight; >+ >+ public Vector getArguments() { >+ return arguments; >+ } >+ >+ public void setArguments(Vector arguments) { >+ this.arguments = arguments; >+ } >+ >+ public float getWeight() { >+ return weight; >+ } >+ >+ public void setWeight(float weight) { >+ this.weight = weight; >+ } >+ } >+ >+ public boolean foundWidget(Widget widget, IUIObjectIdentifier widgetId) { >+ try { >+ IUIObjectIdentifier id = UIObjectResolver.resolve(new MacroObject(new UIObject( >+ widget)).getContext(), new UIObject(widget)); >+ return id == null ? false : id == null ? false : id.getWidgetId() >+ .equals(widgetId.getWidgetId()); >+ } catch (CoreException e) { >+ e.printStackTrace(); >+ } >+ return false; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObject.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObject.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObject.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObject.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,216 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject; >+ >+import org.eclipse.jface.action.ContributionManager; >+import org.eclipse.jface.action.IMenuManager; >+import org.eclipse.jface.action.MenuManager; >+import org.eclipse.jface.wizard.IWizardPage; >+import org.eclipse.jface.wizard.WizardDialog; >+import org.eclipse.swt.custom.CTabItem; >+import org.eclipse.swt.widgets.Button; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Decorations; >+import org.eclipse.swt.widgets.Menu; >+import org.eclipse.swt.widgets.MenuItem; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.TabItem; >+import org.eclipse.swt.widgets.ToolItem; >+import org.eclipse.swt.widgets.Widget; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IViewPart; >+import org.eclipse.ui.IWorkbenchPage; >+import org.eclipse.ui.IWorkbenchPart; >+import org.eclipse.ui.IWorkbenchWindow; >+ >+/** >+ * >+ * @author Alexander Nyssen >+ * >+ */ >+public class MacroObject implements IMacroObject { >+ >+ private Object context; >+ private IUIObject uiObject; >+ >+ /** >+ * Constructor is used by MacroObjectResolver to instantiate a new >+ * MacroObject during deresolving of an IMacroObjectIdentifier >+ * >+ * @param context >+ * @param uiObject >+ */ >+ public MacroObject(Object context, IUIObject uiObject) { >+ this.uiObject = uiObject; >+ this.context = context; >+ } >+ >+ /** >+ * Constructor is used by clients when constructing a new MacroObject to >+ * pass it to the MacroObjectResolver to retrieve an IMacroObjectIdentifier. >+ * The context of the MacroObject is automatically detected based on the >+ * IUIObject passed in. >+ * >+ * >+ * @param uiObject >+ */ >+ public MacroObject(IUIObject uiObject) { >+ this.uiObject = uiObject; >+ this.context = retrieveContext(uiObject); >+ } >+ >+ private Object retrieveContext(IUIObject uiObject) { >+ Widget widget = uiObject.getWidget(); >+ if (widget instanceof MenuItem) { >+ MenuItem menuItem = (MenuItem) widget; >+ IViewPart view = null; >+ if (MacroUtil.onMenubar(menuItem)) { >+ // return the menu containing the item >+ return menuItem.getParent().getShell().getMenuBar(); >+ } else if ((view = MacroUtil.onWorkbenchPartToolbar(menuItem)) != null) { >+ // return the menu located on the action bar of the view >+ // Note: formerly, the ToolBarManager was returned here, >+ // however, this >+ // was never used during resolving -> instead the MenuManager of >+ // the action bar was used to find the menu. >+ IMenuManager menuManager = view.getViewSite().getActionBars() >+ .getMenuManager(); >+ if (menuManager != null && menuManager instanceof MenuManager) { >+ Menu menu = ((MenuManager) menuManager).getMenu(); >+ if (menu == null) { >+ // try to create menu >+ ((MenuManager) menuManager) >+ .createMenuBar((Decorations) view.getSite() >+ .getShell()); >+ } >+ return menu; >+ } else { >+ return null; >+ } >+ } else { >+ // popup menu item >+ return widget.getDisplay().getFocusControl(); >+ } >+ } else if (widget instanceof ToolItem) { >+ ToolItem toolItem = (ToolItem) widget; >+ ContributionManager contributionManager = null; >+ if ((contributionManager = MacroUtil.onToolbar(toolItem)) != null) { >+ // global toolbar >+ return contributionManager; >+ } else { >+ // local toolbar >+ return toolItem.getParent(); >+ } >+ } else if (widget instanceof TabItem) { >+ // ANy: Added to allow proper resolving of TabItems >+ return ((TabItem) widget).getParent(); >+ } else if (widget instanceof CTabItem) { >+ // ANy: Added to allow proper resolving of CTabItems >+ return ((CTabItem) widget).getParent(); >+ } >+ // else if (widget instanceof Shell) { >+ // return ((Shell)widget).getData(); >+ // } >+ else if (widget instanceof Control) { >+ return retrieveControlContext(uiObject); >+ } >+ // ANy: it seems that Menus are actually never used as macro objects, >+ // as the deresolver only has capability to deresolve menu items and not >+ // menus, >+ // so we will ignore this case here as well (the MacroObjectResolver >+ // throws a CoreException if called with a MacroObject denoting a menu) >+ >+ // else if (widget instanceof Menu) { >+ // return null; >+ // } >+ return null; >+ } >+ >+ /** >+ * @param uiObject >+ */ >+ private Object retrieveControlContext(IUIObject uiObject) { >+ if (uiObject.getWidget() instanceof Control) { >+ Control control = (Control) uiObject.getWidget(); >+ Shell shell = control.getShell(); >+ Object data = shell.getData(); >+ if (data instanceof WizardDialog) { >+ // in wizard >+ WizardDialog wd = (WizardDialog) data; >+ IWizardPage page = wd.getCurrentPage(); >+ if (page == null) >+ return null; >+ // check for wizard buttons >+ if (control instanceof Button >+ && MacroUtil.onWizardDialog(wd, (Button) control)) { >+ return wd; >+ } >+ // wizard page related >+ else { >+ return page; >+ } >+ } else if (data instanceof IWorkbenchWindow) { >+ IWorkbenchWindow window = (IWorkbenchWindow) data; >+ IWorkbenchPage page = window.getActivePage(); >+ >+ /** >+ * Ali M.: Under some situations, the part that is returned by >+ * the 'getActivePart' method is the old active part. Although >+ * the control object is coming from the newly active part, the >+ * part that is retrieved below will be from the old active >+ * part. This will cause MacroUtil.getControlIdentifier to >+ * return null when attempting to retrieve the widget id in the >+ * wrong context. One situation that this fails under is when: - >+ * Macro recorder start while the test suite editor is active - >+ * A hook is inserted - The package view is focused (not >+ * activated and focused but just focused) >+ * >+ * To resolve this issue, I have registered a part listener when >+ * the client starts recording. When there is a new active part >+ * detected, an event is created and fired to the usual onEvent >+ * handler in MacroManager. See MacroManager.hookPartListener. >+ */ >+ IWorkbenchPart part = page.getActivePart(); >+ if (part instanceof IViewPart || part instanceof IEditorPart) { >+ return part; >+ } else { >+ return null; >+ } >+ } else { >+ // an arbitrary control on a shell >+ return shell; >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject#getUIObject() >+ */ >+ public IUIObject getUIObject() { >+ return uiObject; >+ } >+ >+ /** >+ * {@inheritDoc} >+ * >+ * @see org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject#getContext() >+ */ >+ public Object getContext() { >+ return context; >+ } >+ >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macro/EventConstants.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macro/EventConstants.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macro/EventConstants.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macro/EventConstants.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,28 @@ >+/********************************************************************** >+ * Copyright (c) {2008} Alexander Nyssen and others. >+ * All rights reserved. This content is 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 >+ * $Id$ >+ * >+ * Contributors: >+ * Alexander Nyssen - Initial contribution >+ **********************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macro; >+ >+ >+/** >+ * @author Alexander Nyssen >+ */ >+public interface EventConstants { >+ >+ /* Custom event types */ >+ /* Indicates that a workbnech part has been closed */ >+ public static final int EVENT_TYPE__WORKBENCH_PART_CLOSED = -1; >+ >+ /* Custom event details */ >+ public static final int EVENT_DETAIL__POSITION_BASED_EVENT = Integer.MIN_VALUE; >+ >+ public static final int EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT = Integer.MIN_VALUE + 1; >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/util/XMLDefaultHandler.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/util/XMLDefaultHandler.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/util/XMLDefaultHandler.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/util/XMLDefaultHandler.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,166 @@ >+/******************************************************************************* >+ * Copyright (c) 2003, 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.util; >+ >+import java.util.Hashtable; >+import java.util.Stack; >+ >+import javax.xml.parsers.DocumentBuilderFactory; >+import javax.xml.parsers.ParserConfigurationException; >+ >+import org.w3c.dom.Element; >+import org.w3c.dom.Node; >+import org.w3c.dom.Text; >+import org.xml.sax.Attributes; >+import org.xml.sax.Locator; >+import org.xml.sax.helpers.DefaultHandler; >+ >+public class XMLDefaultHandler extends DefaultHandler >+{ >+ >+ private org.w3c.dom.Document fDocument; >+ >+ private Locator fLocator; >+ >+ private Hashtable fLineTable; >+ >+ private Element fRootElement; >+ >+ private Stack fElementStack = new Stack(); >+ >+ /* Indicates whether a CDATA section is reached */ >+ private boolean cdataStarted; >+ >+ public XMLDefaultHandler() >+ { >+ fLineTable = new Hashtable(); >+ } >+ >+ public void startElement(String uri, String localName, String qName, Attributes attributes) >+ { >+ Element element = fDocument.createElement(qName); >+ for (int i = 0; i < attributes.getLength(); i++) >+ { >+ element.setAttribute(attributes.getQName(i), attributes.getValue(i)); >+ } >+ >+ Integer lineNumber = new Integer(fLocator.getLineNumber()); >+ Integer[] range = new Integer[] { lineNumber, new Integer(-1) }; >+ fLineTable.put(element, range); >+ if (fRootElement == null) >+ fRootElement = element; >+ else >+ ((Element) fElementStack.peek()).appendChild(element); >+ fElementStack.push(element); >+ } >+ >+ public void endElement(String uri, String localName, String qName) >+ { >+ Integer[] range = (Integer[]) fLineTable.get(fElementStack.pop()); >+ range[1] = new Integer(fLocator.getLineNumber()); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator) >+ */ >+ public void setDocumentLocator(Locator locator) >+ { >+ fLocator = locator; >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.xml.sax.helpers.DefaultHandler#startDocument() >+ */ >+ public void startDocument() >+ { >+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); >+ try >+ { >+ fDocument = factory.newDocumentBuilder().newDocument(); >+ } >+ catch (ParserConfigurationException e) >+ { >+ } >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.xml.sax.helpers.DefaultHandler#endDocument() >+ */ >+ public void endDocument() >+ { >+ fDocument.appendChild(fRootElement); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, >+ * java.lang.String) >+ */ >+ public void processingInstruction(String target, String data) >+ { >+ fDocument.appendChild(fDocument.createProcessingInstruction(target, data)); >+ } >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) >+ */ >+ public void characters(char[] characters, int start, int length) >+ { >+ StringBuffer buff = new StringBuffer(); >+ for (int i = 0; i < length; i++) >+ { >+ buff.append(characters[start + i]); >+ } >+ >+ String buffValue = buff.toString(); >+ boolean isBufferJustWhiteSpace = buffValue.trim().equals(""); >+ boolean isBufferEmpty = buffValue.length() <= 0; >+ >+ if ((cdataStarted && isBufferEmpty) || (!cdataStarted && isBufferJustWhiteSpace)) >+ { >+ cdataStarted = false; >+ return; >+ } >+ >+ Text text = fDocument.createTextNode(buffValue); >+ cdataStarted = true; >+ if (fRootElement == null) >+ fDocument.appendChild(text); >+ else >+ ((Element) fElementStack.peek()).appendChild(text); >+ } >+ >+ public Node getDocumentElement() >+ { >+ fDocument.getDocumentElement().normalize(); >+ return fDocument.getDocumentElement(); >+ } >+ >+ public org.w3c.dom.Document getDocument() >+ { >+ fDocument.getDocumentElement().normalize(); >+ return fDocument; >+ } >+ >+ public Hashtable getLineTable() >+ { >+ return fLineTable; >+ } >+} >Index: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObjectIdentifier.java >=================================================================== >RCS file: src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObjectIdentifier.java >diff -N src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObjectIdentifier.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObjectIdentifier.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,150 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2006 IBM Corporation and others. >+ * 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.tptp.test.auto.gui.internal.macroobject; >+ >+import org.eclipse.core.runtime.Path; >+import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier; >+import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier; >+ >+/** >+ * Used as an identifier for Macro objects. >+ * >+ * @author Alexander Nyssen >+ */ >+public class MacroObjectIdentifier implements IMacroObjectIdentifier { >+ >+ /** The context id */ >+ private String contextId; >+ >+ /** The ui object id */ >+ private IUIObjectIdentifier uiObjectIdentifier; >+ >+ /** >+ * Constructor >+ * >+ * @param contextId >+ * The context id >+ * @param uiObjectId >+ * The widget id >+ */ >+ public MacroObjectIdentifier(String contextId, >+ IUIObjectIdentifier uiObjectIdentifier) { >+ this.contextId = contextId; >+ this.uiObjectIdentifier = uiObjectIdentifier; >+ } >+ >+ /** >+ * An object in question is equalled to this object iff the object is of the >+ * same type and the context and the widget ids are the same. >+ * >+ * @param object >+ * The object in question >+ * >+ * @return A boolean indicating whether object is equalled to this object or >+ * not. >+ */ >+ public boolean equals(Object object) { >+ if (object == null) >+ return false; >+ if (object == this) >+ return true; >+ if (object instanceof MacroObjectIdentifier) { >+ MacroObjectIdentifier wid = (MacroObjectIdentifier) object; >+ return wid.contextId.equals(contextId) >+ && uiObjectIdentifier.getWidgetId().equals( >+ wid.getObjectIdentifier().getWidgetId()); >+ } >+ return false; >+ } >+ >+ /** >+ * Returns the context id of this identifier >+ * >+ * @return The context id >+ */ >+ public String getContextIdentifier() { >+ return contextId.toString(); >+ } >+ >+ public IUIObjectIdentifier getObjectIdentifier() { >+ return uiObjectIdentifier; >+ } >+ >+ public static IMacroObjectIdentifier deserializeMacroObjectIdentifier( >+ String macroObjectIdentifierString) { >+ >+ // 1) retrieve the context, object and resolver id >+ // first retrieve the resolver id >+ String resolverId = null; >+ if (macroObjectIdentifierString >+ .indexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR) >= 0) { >+ resolverId = macroObjectIdentifierString >+ .substring(macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR) + 3); >+ macroObjectIdentifierString = macroObjectIdentifierString >+ .substring( >+ 0, >+ macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR)); >+ } >+ >+ // now the object id separator >+ String objectId = null; >+ if (macroObjectIdentifierString >+ .indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) >= 0) { >+ objectId = macroObjectIdentifierString >+ .substring(macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) + 3); >+ macroObjectIdentifierString = macroObjectIdentifierString >+ .substring( >+ 0, >+ macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR)); >+ } >+ >+ // now the widget id >+ String widgetId = macroObjectIdentifierString >+ .substring(macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR) + 3); >+ macroObjectIdentifierString = macroObjectIdentifierString >+ .substring(0, macroObjectIdentifierString >+ .lastIndexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR)); >+ >+ // now the context id >+ String contextId = new Path(macroObjectIdentifierString).removeTrailingSeparator().toString(); >+ >+ // 2) construct a new identifier and return it >+ IMacroObjectIdentifier macroObjectIdentifier = new MacroObjectIdentifier( >+ contextId, >+ new PrimitiveUIObjectIdentifier(widgetId, objectId, resolverId)); >+ return macroObjectIdentifier; >+ } >+ >+ public static String serializeMacroObjectIdentifier( >+ IMacroObjectIdentifier macroObjectIdentifier) { >+ return macroObjectIdentifier.getContextIdentifier() >+ // concat widet id >+ + MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR >+ + macroObjectIdentifier.getObjectIdentifier().getWidgetId() >+ // concat object id >+ + (macroObjectIdentifier.getObjectIdentifier().getObjectId() != null ? MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR >+ + macroObjectIdentifier.getObjectIdentifier() >+ .getObjectId() >+ : "") >+ // concat resolver id >+ + (macroObjectIdentifier.getObjectIdentifier().getResolverId() != null ? MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR >+ + macroObjectIdentifier.getObjectIdentifier() >+ .getResolverId() >+ : ""); >+ } >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
jcayne
:
iplog+
Actions:
View
|
Diff
Attachments on
bug 133099
:
80668
|
80669
|
84044
|
88247
|
88970
|
89819
|
90299
|
95022
|
95024
|
96551
|
108487
|
108488
|
108613
|
127394
|
127395
|
138251
|
138252
|
138255
|
138256