Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 133099 | Differences between
and this patch

Collapse All | Expand All

(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %plugin.name
3
Bundle-Name: %plugin.name
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto
5
Bundle-Version: 4.2.0.qualifier
5
Bundle-Version: 4.6.0.qualifier
6
Bundle-Vendor: %plugin.provider
6
Bundle-Vendor: %plugin.provider
7
Bundle-Localization: plugin
7
Bundle-Localization: plugin
8
Bundle-ActivationPolicy: lazy
8
Bundle-ActivationPolicy: lazy
(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: Tests Plug-in
3
Bundle-Name: Tests Plug-in
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui.tests
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui.tests
5
Bundle-Version: 1.0.0
5
Bundle-Version: 4.5.3.qualifier
6
Bundle-Activator: org.eclipse.tptp.test.auto.gui.tests.TestsPlugin
6
Bundle-Activator: org.eclipse.tptp.test.auto.gui.tests.TestsPlugin
7
Require-Bundle: org.eclipse.ui,
7
Require-Bundle: org.eclipse.ui,
8
 org.junit,
8
 org.junit,
(-)src/org/eclipse/tptp/test/auto/gui/tests/TestsPlugin.java (-54 lines)
Removed Link Here
1
package org.eclipse.tptp.test.auto.gui.tests;
2
3
import org.eclipse.ui.plugin.*;
4
import org.eclipse.jface.resource.ImageDescriptor;
5
import org.osgi.framework.BundleContext;
6
7
/**
8
 * The main plugin class to be used in the desktop.
9
 */
10
public class TestsPlugin extends AbstractUIPlugin {
11
12
	//The shared instance.
13
	private static TestsPlugin plugin;
14
	
15
	/**
16
	 * The constructor.
17
	 */
18
	public TestsPlugin() {
19
		plugin = this;
20
	}
21
22
	/**
23
	 * This method is called upon plug-in activation
24
	 */
25
	public void start(BundleContext context) throws Exception {
26
		super.start(context);
27
	}
28
29
	/**
30
	 * This method is called when the plug-in is stopped
31
	 */
32
	public void stop(BundleContext context) throws Exception {
33
		super.stop(context);
34
		plugin = null;
35
	}
36
37
	/**
38
	 * Returns the shared instance.
39
	 */
40
	public static TestsPlugin getDefault() {
41
		return plugin;
42
	}
43
44
	/**
45
	 * Returns an image descriptor for the image file at the given
46
	 * plug-in relative path.
47
	 *
48
	 * @param path the path
49
	 * @return the image descriptor
50
	 */
51
	public static ImageDescriptor getImageDescriptor(String path) {
52
		return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.tptp.test.auto.gui.tests", path);
53
	}
54
}
(-)src/org/eclipse/tptp/test/auto/gui/tests/common/stubs/AutoGUINodeList.java (-32 lines)
Removed Link Here
1
package org.eclipse.tptp.test.auto.gui.tests.common.stubs;
2
3
import java.util.List;
4
5
import org.w3c.dom.Node;
6
import org.w3c.dom.NodeList;
7
8
public class AutoGUINodeList implements NodeList
9
{
10
	private List children; 
11
	
12
	public AutoGUINodeList (List nodes)
13
	{
14
		this.children = nodes;
15
	}
16
		
17
	public int getLength()
18
	{
19
		return children.size();
20
	}
21
22
	public Node item(int index)
23
	{
24
		return (Node)children.get(index);
25
	}
26
	
27
	public AutoGUINode[] getNodes()
28
	{
29
		return children == null ? null : (AutoGUINode[])children.toArray(new AutoGUINode[children.size()]);
30
	}
31
32
}
(-)src/org/eclipse/tptp/test/auto/gui/tests/common/stubs/AutoGUINode.java (-406 lines)
Removed Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.tests.common.stubs;
12
13
import org.w3c.dom.Attr;
14
import org.w3c.dom.DOMException;
15
import org.w3c.dom.Document;
16
import org.w3c.dom.Element;
17
import org.w3c.dom.NamedNodeMap;
18
import org.w3c.dom.Node;
19
import org.w3c.dom.NodeList;
20
import org.w3c.dom.TypeInfo;
21
import org.w3c.dom.UserDataHandler;
22
23
public class AutoGUINode implements Node, Element
24
{
25
	private String name;
26
	private String value;
27
	private AutoGUINodeList children;
28
	private AutoGUINamedNodeMap attributes;	
29
30
	public AutoGUINode(String name, String value, AutoGUINodeList children, AutoGUINamedNodeMap attributes)
31
	{
32
		this.name = name;
33
		this.value = value;
34
		this.children = children;
35
		this.attributes = attributes;
36
	}
37
	
38
	
39
	public Node appendChild(Node newChild) throws DOMException
40
	{
41
		
42
		return null;
43
	}
44
45
	public Node cloneNode(boolean deep)
46
	{
47
		
48
		return null;
49
	}
50
51
	public NamedNodeMap getAttributes()
52
	{
53
		return attributes;
54
	}
55
56
	public NodeList getChildNodes()
57
	{
58
		return children;
59
	}
60
61
	public Node getFirstChild()
62
	{
63
		
64
		return null;
65
	}
66
67
	public Node getLastChild()
68
	{
69
		
70
		return null;
71
	}
72
73
	public String getLocalName()
74
	{
75
		
76
		return null;
77
	}
78
79
	public String getNamespaceURI()
80
	{
81
		
82
		return null;
83
	}
84
85
	public Node getNextSibling()
86
	{
87
		
88
		return null;
89
	}
90
91
	public String getNodeName()
92
	{		
93
		return name;
94
	}
95
96
	public short getNodeType()
97
	{
98
		
99
		return 0;
100
	}
101
102
	public String getNodeValue() throws DOMException
103
	{		
104
		return value;
105
	}
106
107
	public Document getOwnerDocument()
108
	{
109
		
110
		return null;
111
	}
112
113
	public Node getParentNode()
114
	{
115
		
116
		return null;
117
	}
118
119
	public String getPrefix()
120
	{
121
		
122
		return null;
123
	}
124
125
	public Node getPreviousSibling()
126
	{
127
		
128
		return null;
129
	}
130
131
	public boolean hasAttributes()
132
	{
133
		
134
		return false;
135
	}
136
137
	public boolean hasChildNodes()
138
	{
139
		
140
		return false;
141
	}
142
143
	public Node insertBefore(Node newChild, Node refChild) throws DOMException
144
	{
145
		
146
		return null;
147
	}
148
149
	public boolean isSupported(String feature, String version)
150
	{
151
		
152
		return false;
153
	}
154
155
	public void normalize()
156
	{
157
		
158
159
	}
160
161
	public Node removeChild(Node oldChild) throws DOMException
162
	{
163
		
164
		return null;
165
	}
166
167
	public Node replaceChild(Node newChild, Node oldChild) throws DOMException
168
	{
169
		
170
		return null;
171
	}
172
173
	public void setNodeValue(String nodeValue) throws DOMException
174
	{
175
		
176
177
	}
178
179
	public void setPrefix(String prefix) throws DOMException
180
	{
181
		
182
183
	}
184
185
186
	public String getAttribute(String name)
187
	{
188
		Node node = attributes.getNamedItem(name);
189
		return node == null ? null : node.getNodeValue();
190
	}
191
192
193
	public String getAttributeNS(String namespaceURI, String localName)
194
	{		
195
		return null;
196
	}
197
198
199
	public Attr getAttributeNode(String name)
200
	{
201
		return null;
202
	}
203
204
205
	public Attr getAttributeNodeNS(String namespaceURI, String localName)
206
	{
207
		return null;
208
	}
209
210
211
	public NodeList getElementsByTagName(String name)
212
	{
213
		
214
		return null;
215
	}
216
217
218
	public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
219
	{
220
		
221
		return null;
222
	}
223
224
225
	public String getTagName()
226
	{
227
		
228
		return null;
229
	}
230
231
232
	public boolean hasAttribute(String name)
233
	{
234
		
235
		return false;
236
	}
237
238
239
	public boolean hasAttributeNS(String namespaceURI, String localName)
240
	{
241
		
242
		return false;
243
	}
244
245
246
	public void removeAttribute(String name) throws DOMException
247
	{
248
		
249
		
250
	}
251
252
253
	public void removeAttributeNS(String namespaceURI, String localName) throws DOMException
254
	{
255
		
256
		
257
	}
258
259
260
	public Attr removeAttributeNode(Attr oldAttr) throws DOMException
261
	{
262
		
263
		return null;
264
	}
265
266
267
	public void setAttribute(String name, String value) throws DOMException
268
	{
269
		
270
		
271
	}
272
273
274
	public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException
275
	{
276
		
277
		
278
	}
279
280
281
	public Attr setAttributeNode(Attr newAttr) throws DOMException
282
	{
283
		
284
		return null;
285
	}
286
287
288
	public Attr setAttributeNodeNS(Attr newAttr) throws DOMException
289
	{
290
		
291
		return null;
292
	}
293
294
295
	public short compareDocumentPosition(Node other) throws DOMException
296
	{
297
		
298
		return 0;
299
	}
300
301
302
	public String getBaseURI()
303
	{
304
		
305
		return null;
306
	}
307
308
309
	public Object getFeature(String feature, String version)
310
	{
311
		
312
		return null;
313
	}
314
315
316
	public String getTextContent() throws DOMException
317
	{
318
		
319
		return null;
320
	}
321
322
323
	public Object getUserData(String key)
324
	{
325
		
326
		return null;
327
	}
328
329
330
	public boolean isDefaultNamespace(String namespaceURI)
331
	{
332
		
333
		return false;
334
	}
335
336
337
	public boolean isEqualNode(Node arg)
338
	{
339
		
340
		return false;
341
	}
342
343
344
	public boolean isSameNode(Node other)
345
	{
346
		
347
		return false;
348
	}
349
350
351
	public String lookupNamespaceURI(String prefix)
352
	{
353
		
354
		return null;
355
	}
356
357
358
	public String lookupPrefix(String namespaceURI)
359
	{
360
		
361
		return null;
362
	}
363
364
365
	public void setTextContent(String textContent) throws DOMException
366
	{
367
		
368
		
369
	}
370
371
372
	public Object setUserData(String key, Object data, UserDataHandler handler)
373
	{
374
		
375
		return null;
376
	}
377
378
379
	public TypeInfo getSchemaTypeInfo()
380
	{
381
		
382
		return null;
383
	}
384
385
386
	public void setIdAttribute(String name, boolean isId) throws DOMException
387
	{
388
		
389
		
390
	}
391
392
393
	public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException
394
	{
395
		
396
		
397
	}
398
399
400
	public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException
401
	{
402
		
403
		
404
	}
405
406
}
(-)src/org/eclipse/tptp/test/auto/gui/tests/common/stubs/AutoGUINamedNodeMap.java (-75 lines)
Removed Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.tests.common.stubs;
12
13
import java.util.Map;
14
15
import org.w3c.dom.DOMException;
16
import org.w3c.dom.NamedNodeMap;
17
import org.w3c.dom.Node;
18
19
public class AutoGUINamedNodeMap implements NamedNodeMap
20
{
21
	private Map attributes;
22
	
23
	public AutoGUINamedNodeMap(Map attributes)
24
	{
25
		this.attributes = attributes;
26
	}
27
	
28
	public int getLength()
29
	{
30
		return attributes.size();
31
	}
32
33
	public Node getNamedItem(String name)
34
	{
35
		return (Node)attributes.get(name);
36
	}
37
38
	public Node getNamedItemNS(String namespaceURI, String localName)
39
	{
40
		
41
		return null;
42
	}
43
44
	public Node item(int index)
45
	{
46
		
47
		return null;
48
	}
49
50
	public Node removeNamedItem(String name) throws DOMException
51
	{
52
		
53
		return null;
54
	}
55
56
	public Node removeNamedItemNS(String namespaceURI, String localName)
57
			throws DOMException
58
	{
59
		
60
		return null;
61
	}
62
63
	public Node setNamedItem(Node arg) throws DOMException
64
	{
65
		
66
		return null;
67
	}
68
69
	public Node setNamedItemNS(Node arg) throws DOMException
70
	{
71
		
72
		return null;
73
	}
74
75
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/junits/AllTests.java (-48 / +50 lines)
Lines 1-48 Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.junits;
1
package org.eclipse.tptp.test.auto.gui.internal.junits;
2
2
3
import junit.framework.Test;
3
import junit.framework.Test;
4
4
5
import org.eclipse.hyades.test.common.junit.DefaultTestArbiter;
5
import org.eclipse.hyades.test.common.junit.DefaultTestArbiter;
6
import org.eclipse.hyades.test.common.junit.HyadesTestCase;
6
import org.eclipse.hyades.test.common.junit.HyadesTestCase;
7
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
7
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
8
8
9
/**
9
/**
10
 * Generated code for the test suite <b>AllTests</b> located at
10
 * Generated code for the test suite <b>AllTests</b> located at
11
 * <i>/org.eclipse.tptp.test.auto.gui.tests/junit/AllTests.testsuite</i>.
11
 * <i>/org.eclipse.tptp.test.auto.gui.internal.tests/junit/AllTests.testsuite</i>.
12
 */
12
 */
13
public class AllTests extends HyadesTestCase
13
public class AllTests extends HyadesTestCase
14
{
14
{
15
	/**
15
	/**
16
	 * Constructor for AllTests.
16
	 * Constructor for AllTests.
17
	 * @param name
17
	 * @param name
18
	 */
18
	 */
19
	public AllTests(String name)
19
	public AllTests(String name)
20
	{
20
	{
21
		super(name);
21
		super(name);
22
	}
22
	}
23
23
24
	/**
24
	/**
25
	 * Returns the JUnit test suite that implements the <b>AllTests</b> definition.
25
	 * Returns the JUnit test suite that implements the <b>AllTests</b> definition.
26
	 */
26
	 */
27
	public static Test suite() {
27
	public static Test suite() {
28
		HyadesTestSuite allTests = new HyadesTestSuite("AllTests");
28
		HyadesTestSuite allTests = new HyadesTestSuite("AllTests");
29
		allTests.setArbiter(DefaultTestArbiter.INSTANCE).setId(
29
		allTests.setArbiter(DefaultTestArbiter.INSTANCE).setId(
30
				"DB15AFBA97E27DB4545A1C30429A11DB");
30
				"DB15AFBA97E27DB4545A1C30429A11DB");
31
		return allTests;
31
		allTests.addTest(((HyadesTestSuite) TestAutoGUIUtil.suite())
32
	}
32
				.setTestInvocationId("FDADA7BD7A22D9AB3CF97DB9C8BD11DC"));
33
33
		return allTests;
34
	/**
34
	}
35
	 * @see junit.framework.TestCase#setUp()
35
36
	 */
36
	/**
37
	protected void setUp() throws Exception
37
	 * @see junit.framework.TestCase#setUp()
38
	{
38
	 */
39
	}
39
	protected void setUp() throws Exception
40
40
	{
41
	/**
41
	}
42
	 * @see junit.framework.TestCase#tearDown()
42
43
	 */
43
	/**
44
	protected void tearDown() throws Exception
44
	 * @see junit.framework.TestCase#tearDown()
45
	{
45
	 */
46
	}
46
	protected void tearDown() throws Exception
47
47
	{
48
}
48
	}
49
50
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/junits/TestAutoGUIUtil.java (-126 / +148 lines)
Lines 1-126 Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.junits;
1
package org.eclipse.tptp.test.auto.gui.internal.junits;
2
2
3
import java.util.ArrayList;
3
import java.util.ArrayList;
4
import java.util.Hashtable;
4
import java.util.Hashtable;
5
import java.util.List;
5
import java.util.List;
6
import java.util.Map;
6
import java.util.Map;
7
7
8
import junit.framework.Test;
8
import junit.framework.Test;
9
9
10
import org.eclipse.hyades.test.common.junit.DefaultTestArbiter;
10
import org.eclipse.hyades.test.common.junit.DefaultTestArbiter;
11
import org.eclipse.hyades.test.common.junit.HyadesTestCase;
11
import org.eclipse.hyades.test.common.junit.HyadesTestCase;
12
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
12
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
13
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
13
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
14
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
14
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
15
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
15
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
16
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
16
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
17
import org.eclipse.tptp.test.auto.gui.tests.common.stubs.AutoGUINode;
17
import org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs.AutoGUINode;
18
import org.eclipse.tptp.test.auto.gui.tests.common.stubs.AutoGUINodeList;
18
import org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs.AutoGUINodeList;
19
import org.eclipse.tptp.test.auto.gui.tests.common.util.AutoGUINodeUtil;
19
import org.eclipse.tptp.test.auto.gui.internal.tests.common.util.AutoGUINodeUtil;
20
import org.w3c.dom.Element;
20
import org.w3c.dom.Element;
21
21
22
/**
22
/**
23
 * Generated code for the test suite <b>TestAutoGUIUtil</b> located at
23
 * Generated code for the test suite <b>TestAutoGUIUtil</b> located at
24
 * <i>/org.eclipse.tptp.test.auto.gui.tests/junit/TestAutoGUIUtil.testsuite</i>.
24
 * <i>/org.eclipse
25
 * 
25
 * .tptp.test.auto.gui.internal.tests/junit/TestAutoGUIUtil
26
 * Tests AutoGUIUtil
26
 * .testsuite</i>.
27
 */
27
 * 
28
public class TestAutoGUIUtil extends HyadesTestCase {
28
 * Tests AutoGUIUtil
29
	/**
29
 */
30
	 * Constructor for TestAutoGUIUtil.
30
public class TestAutoGUIUtil extends HyadesTestCase {
31
	 * 
31
	/**
32
	 * @param name
32
	 * Constructor for TestAutoGUIUtil.
33
	 */
33
	 * 
34
	public TestAutoGUIUtil(String name) {
34
	 * @param name
35
		super(name);
35
	 */
36
	}
36
	public TestAutoGUIUtil(String name) {
37
37
		super(name);
38
	/**
38
	}
39
	 * Returns the JUnit test suite that implements the <b>TestAutoGUIUtil</b>
39
40
	 * definition.
40
	/**
41
	 */
41
	 * Returns the JUnit test suite that implements the <b>TestAutoGUIUtil</b>
42
	public static Test suite() {
42
	 * definition.
43
		HyadesTestSuite testAutoGUIUtil = new HyadesTestSuite("TestAutoGUIUtil");
43
	 */
44
		testAutoGUIUtil.setArbiter(DefaultTestArbiter.INSTANCE).setId(
44
	public static Test suite() {
45
				"FB3DE203BEC63AE3983BDC00224111DB");
45
		HyadesTestSuite testAutoGUIUtil = new HyadesTestSuite("TestAutoGUIUtil");
46
46
		testAutoGUIUtil.setArbiter(DefaultTestArbiter.INSTANCE).setId(
47
		testAutoGUIUtil.addTest(new TestAutoGUIUtil("testWalkDomTree").setId(
47
				"FB3DE203BEC63AE3983BDC00224111DB");
48
				"FB3DE203BEC63AE39B6D93F0224111DB").setTestInvocationId(
48
49
				"FB3DE203BEC63AE3A8C3BB60224111DB"));
49
		testAutoGUIUtil.addTest(new TestAutoGUIUtil("testWalkDomTree").setId(
50
		return testAutoGUIUtil;
50
				"FB3DE203BEC63AE39B6D93F0224111DB").setTestInvocationId(
51
	}
51
				"FB3DE203BEC63AE3A8C3BB60224111DB"));
52
52
		return testAutoGUIUtil;
53
	/**
53
	}
54
	 * @see junit.framework.TestCase#setUp()
54
55
	 */
55
	/**
56
	protected void setUp() throws Exception 
56
	 * @see junit.framework.TestCase#setUp()
57
	{
57
	 */
58
	}
58
	protected void setUp() throws Exception {
59
59
	}
60
	/**
60
61
	 * @see junit.framework.TestCase#tearDown()
61
	/**
62
	 */
62
	 * @see junit.framework.TestCase#tearDown()
63
	protected void tearDown() throws Exception 
63
	 */
64
	{
64
	protected void tearDown() throws Exception {
65
	}
65
	}
66
66
67
	/**
67
	/**
68
	 * testWalkDomTree
68
	 * testWalkDomTree
69
	 * 
69
	 * 
70
	 * @throws Exception
70
	 * @throws Exception
71
	 */
71
	 */
72
	public void testWalkDomTree() throws Exception 
72
	public void testWalkDomTree() throws Exception {
73
	{
73
		Map modifiableFields = new Hashtable();
74
		Map modifiableFields = new Hashtable();
74
		List orderedModifiableFields = new ArrayList();
75
		List orderedModifiableFields = new ArrayList();
75
76
		
76
		final AutoGUINode WAIT_WITHOUT_TIME_TO_WAIT = AutoGUINodeUtil
77
		final AutoGUINode WAIT_WITHOUT_TIME_TO_WAIT = AutoGUINodeUtil.constructNode(MacroConstants.COMMAND_ELEMENT, null, new String[][] {new String[] {MacroConstants.TYPE_ATTRIBUTE, WaitCommand.TYPE}});
77
				.constructNode(
78
		final AutoGUINode WAIT_WITH_TIME_TO_WAIT = AutoGUINodeUtil.constructNode(MacroConstants.COMMAND_ELEMENT, null, new String[][] {new String[] {MacroConstants.TYPE_ATTRIBUTE, WaitCommand.TYPE}, new String[] {MacroConstants.TIME_TO_WAIT_ATTRIBUTE, "1000"}});
78
						MacroConstants.COMMAND_ELEMENT,
79
		final AutoGUINode MODIFY_NODE = AutoGUINodeUtil.constructNode(MacroConstants.COMMAND_ELEMENT, null, new String[][] {new String[] {MacroConstants.TYPE_ATTRIBUTE, ModifyCommand.TYPE}});
79
						null,
80
		
80
						new String[][] { new String[] {
81
		/* Empty list */
81
								MacroConstants.TYPE_ATTRIBUTE, WaitCommand.TYPE } });
82
		AutoGUINodeList nodeList = AutoGUINodeUtil.constructNodeList (new AutoGUINode[0]);		
82
		final AutoGUINode WAIT_WITH_TIME_TO_WAIT = AutoGUINodeUtil
83
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields, orderedModifiableFields);
83
				.constructNode(MacroConstants.COMMAND_ELEMENT, null,
84
		assertEquals("The map and the ordered list must have the same size", modifiableFields.size(), orderedModifiableFields.size());
84
						new String[][] {
85
		assertEquals("The map size is expected to be zero", 0, modifiableFields.size());
85
								new String[] { MacroConstants.TYPE_ATTRIBUTE,
86
		
86
										WaitCommand.TYPE },
87
		/* One wait command without the time-to-wait attribute */
87
								new String[] {
88
		nodeList = AutoGUINodeUtil.constructNodeList (new AutoGUINode[]{WAIT_WITHOUT_TIME_TO_WAIT});		
88
										MacroConstants.TIME_TO_WAIT_ATTRIBUTE,
89
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields, orderedModifiableFields);
89
										"1000" } });
90
		assertEquals("The map and the ordered list must have the same size", modifiableFields.size(), orderedModifiableFields.size());
90
		final AutoGUINode MODIFY_NODE = AutoGUINodeUtil.constructNode(
91
		assertEquals("The map size is expected to be zero", 0, modifiableFields.size());
91
				MacroConstants.COMMAND_ELEMENT, null,
92
		
92
				new String[][] { new String[] { MacroConstants.TYPE_ATTRIBUTE,
93
		/* Modify
93
						ModifyCommand.TYPE } });
94
		 * |  |___ Wait with time to wait
94
95
		 * |  |___ Wait without time to wait
95
		/* Empty list */
96
		 * Modify
96
		AutoGUINodeList nodeList = AutoGUINodeUtil
97
		 */
97
				.constructNodeList(new AutoGUINode[0]);
98
		reset(modifiableFields, orderedModifiableFields);
98
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields,
99
		nodeList = AutoGUINodeUtil.constructNodeList
99
				orderedModifiableFields);
100
		(
100
		assertEquals("The map and the ordered list must have the same size",
101
			new AutoGUINode[]
101
				modifiableFields.size(), orderedModifiableFields.size());
102
			{
102
		assertEquals("The map size is expected to be zero", 0, modifiableFields
103
				AutoGUINodeUtil.constructNode(MacroConstants.COMMAND_ELEMENT,  
103
				.size());
104
						new AutoGUINode[] {WAIT_WITHOUT_TIME_TO_WAIT, WAIT_WITH_TIME_TO_WAIT},
104
105
						new String[][] {new String[] {MacroConstants.TYPE_ATTRIBUTE, ModifyCommand.TYPE}}),
105
		/* One wait command without the time-to-wait attribute */
106
				MODIFY_NODE
106
		nodeList = AutoGUINodeUtil
107
			}
107
				.constructNodeList(new AutoGUINode[] { WAIT_WITHOUT_TIME_TO_WAIT });
108
		);		
108
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields,
109
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields, orderedModifiableFields);	
109
				orderedModifiableFields);
110
		assertEquals("The map size is expected to be zero", 2, modifiableFields.size());
110
		assertEquals("The map and the ordered list must have the same size",
111
		assertEquals("The map size is expected to be zero", 3, orderedModifiableFields.size());
111
				modifiableFields.size(), orderedModifiableFields.size());
112
		final String[] EXPECTED_ORDER = new String[] {ModifyCommand.TYPE, WaitCommand.TYPE, ModifyCommand.TYPE};
112
		assertEquals("The map size is expected to be zero", 0, modifiableFields
113
		for (int i = 0; i < EXPECTED_ORDER.length; i++)
113
				.size());
114
		{
114
115
			Element element = (Element)orderedModifiableFields.get(i);
115
		/*
116
			assertEquals("The command ordering is incorrect", EXPECTED_ORDER[i], element.getAttribute(MacroConstants.TYPE_ATTRIBUTE));			
116
		 * Modify | |___ Wait with time to wait | |___ Wait without time to wait
117
		}
117
		 * Modify
118
	}
118
		 */
119
119
		reset(modifiableFields, orderedModifiableFields);
120
	private void reset(Map modifiableFields, List orderedModifiableFields)
120
		nodeList = AutoGUINodeUtil.constructNodeList(new AutoGUINode[] {
121
	{
121
				AutoGUINodeUtil.constructNode(MacroConstants.COMMAND_ELEMENT,
122
		modifiableFields.clear();
122
						new AutoGUINode[] { WAIT_WITHOUT_TIME_TO_WAIT,
123
		orderedModifiableFields.clear();		
123
								WAIT_WITH_TIME_TO_WAIT },
124
	}
124
						new String[][] { new String[] {
125
125
								MacroConstants.TYPE_ATTRIBUTE,
126
}
126
								ModifyCommand.TYPE } }), MODIFY_NODE });
127
		AutoGUIUtil.walkDomTree(nodeList, modifiableFields,
128
				orderedModifiableFields);
129
		assertEquals("The map size is expected to be zero", 2, modifiableFields
130
				.size());
131
		assertEquals("The map size is expected to be zero", 3,
132
				orderedModifiableFields.size());
133
		final String[] EXPECTED_ORDER = new String[] { ModifyCommand.TYPE,
134
				WaitCommand.TYPE, ModifyCommand.TYPE };
135
		for (int i = 0; i < EXPECTED_ORDER.length; i++) {
136
			Element element = (Element) orderedModifiableFields.get(i);
137
			assertEquals("The command ordering is incorrect",
138
					EXPECTED_ORDER[i], element
139
							.getAttribute(MacroConstants.TYPE_ATTRIBUTE));
140
		}
141
	}
142
143
	private void reset(Map modifiableFields, List orderedModifiableFields) {
144
		modifiableFields.clear();
145
		orderedModifiableFields.clear();
146
	}
147
148
}
(-)src/org/eclipse/tptp/test/auto/gui/tests/common/util/AutoGUINodeUtil.java (-74 lines)
Removed Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.tests.common.util;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Map;
16
17
import org.eclipse.tptp.test.auto.gui.tests.common.stubs.AutoGUINamedNodeMap;
18
import org.eclipse.tptp.test.auto.gui.tests.common.stubs.AutoGUINode;
19
import org.eclipse.tptp.test.auto.gui.tests.common.stubs.AutoGUINodeList;
20
21
public class AutoGUINodeUtil
22
{
23
24
	public static AutoGUINodeList constructNodeList(AutoGUINode[] nodeData)
25
	{
26
		ArrayList list = new ArrayList();
27
		for (int i = 0; i < nodeData.length; i++)
28
		{
29
			list.add(nodeData[i]);
30
		}
31
		return new AutoGUINodeList(list);
32
	}
33
34
//	private static void constructNodeList(AutoGUINode[] nodeData, ArrayList list)
35
//	{
36
//		for (int i = 0; i < nodeData.length; i++)
37
//		{
38
//			AutoGUINodeList children = null;
39
//			if (nodeData[i].getChildNodes() != null)
40
//			{
41
//				children = constructNodeList(((AutoGUINodeList)nodeData[i].getChildNodes()).getNodes());
42
//			}
43
//			String[][] atts = null;
44
//			Map attributeMap = null;
45
//			if ((atts = nodeData[i].getAttributes()) != null)
46
//			{
47
//				attributeMap = new Hashtable();
48
//				for (int j = 0; j < atts.length; j++)
49
//				{
50
//					String[] currentAttribute = atts[j];
51
//					attributeMap.put(currentAttribute[0], currentAttribute[1]);
52
//				}
53
//			}
54
//			
55
//			list.add(new AutoGUINode(children, attributeMap == null ? null : new AutoGUINamedNodeMap(attributeMap)));
56
//		}
57
//	}
58
	
59
	public static AutoGUINode constructNode (String name, AutoGUINode[] children, String[][] attributes)
60
	{
61
		Map attributeMap = new Hashtable();
62
		if (attributes != null)
63
		{
64
			for (int i = 0; i < attributes.length; i++)
65
			{
66
				String[] attribute = attributes[i];
67
				attributeMap.put(attribute[0], new AutoGUINode(attribute[0], attribute[1], null, null));
68
			}
69
		}
70
		
71
		return new AutoGUINode(name, null, children == null ? null : constructNodeList(children), new AutoGUINamedNodeMap(attributeMap));
72
	}
73
74
}
(-)build.properties (-4 / +10 lines)
Lines 1-4 Link Here
1
source.. = src/
1
source.. = src/
2
output.. = bin/
2
output.. = bin/
3
bin.includes = META-INF/,\
3
bin.includes = META-INF/,\
4
               .
4
               .,\
5
               gui/,\
6
               junit/,\
7
               junit-plugin/,\
8
               manual/,\
9
               src/,\
10
               bin/
(-).settings/org.eclipse.core.resources.prefs (-3 / +4 lines)
Lines 1-3 Link Here
1
#Wed Aug 02 12:11:46 EDT 2006
1
#Tue Jan 22 09:18:20 CET 2008
2
eclipse.preferences.version=1
2
eclipse.preferences.version=1
3
encoding//src/org/eclipse/tptp/test/auto/gui/internal/junits/TestAutoGUIUtil.java=UTF-8
3
encoding//src/org/eclipse/tptp/test/auto/gui/internal/junit_plugins/TestCommandsByMacroPlayback.java=UTF-8
4
encoding//src/org/eclipse/tptp/test/auto/gui/internal/junits/TestAutoGUIUtil.java=UTF-8
(-)src/org/eclipse/tptp/test/auto/gui/internal/tests/TestsPlugin.java (+54 lines)
Added Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.tests;
2
3
import org.eclipse.ui.plugin.*;
4
import org.eclipse.jface.resource.ImageDescriptor;
5
import org.osgi.framework.BundleContext;
6
7
/**
8
 * The main plugin class to be used in the desktop.
9
 */
10
public class TestsPlugin extends AbstractUIPlugin {
11
12
	//The shared instance.
13
	private static TestsPlugin plugin;
14
	
15
	/**
16
	 * The constructor.
17
	 */
18
	public TestsPlugin() {
19
		plugin = this;
20
	}
21
22
	/**
23
	 * This method is called upon plug-in activation
24
	 */
25
	public void start(BundleContext context) throws Exception {
26
		super.start(context);
27
	}
28
29
	/**
30
	 * This method is called when the plug-in is stopped
31
	 */
32
	public void stop(BundleContext context) throws Exception {
33
		super.stop(context);
34
		plugin = null;
35
	}
36
37
	/**
38
	 * Returns the shared instance.
39
	 */
40
	public static TestsPlugin getDefault() {
41
		return plugin;
42
	}
43
44
	/**
45
	 * Returns an image descriptor for the image file at the given
46
	 * plug-in relative path.
47
	 *
48
	 * @param path the path
49
	 * @return the image descriptor
50
	 */
51
	public static ImageDescriptor getImageDescriptor(String path) {
52
		return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.tptp.test.auto.gui.tests", path);
53
	}
54
}
(-)junit-plugin/TestLocateEditorControl.xml (+64 lines)
Added Link Here
1
<macro version="1.1">
2
	<shell descriptive="Plug-in Development - TestPluginProject/src/Test.t..." resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.ui.internal.WorkbenchWindow" return-code="-1">
3
		<command descriptive="Project..." type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="menus" widgetId="{{File-New&amp;#x9;Alt+Shift+N-Project...}}-{{1.0}}"/>
4
		<shell descriptive="New Project" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.jface.wizard.WizardDialog" return-code="0">
5
			<command descriptive="General" type="item-expand" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newWizardSelectionPage" widgetId="org.eclipse.swt.widgets.Tree#1" value="true">
6
				<item widgetId="{{org.eclipse.ui.Basic}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
7
			</command>
8
			<command descriptive="Project" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newWizardSelectionPage" widgetId="org.eclipse.swt.widgets.Tree#1">
9
				<item widgetId="{{org.eclipse.ui.wizards.new.project}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
10
			</command>
11
			<command descriptive="Next &amp;gt;" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{15}}-{{1.0}}"/>
12
			<command descriptive="TestProject" type="modify" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/basicNewProjectPage" widgetId="Project name:">
13
			<![CDATA[TestProject]]>
14
			</command>
15
			<command descriptive="Finish" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{16}}-{{1.0}}"/>
16
		</shell>
17
		<command type="wait"/>
18
		<command descriptive="TestProject" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}">
19
			<item widgetId="{{/TestProject}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
20
		</command>
21
		<command descriptive="Folder" type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="popup/view/org.eclipse.jdt.ui.PackageExplorer/{{/}}-{{1.0}}@@@org.eclipse.tptp.test.auto.gui.adaptive" widgetId="{{New-Folder}}-{{1.0}}"/>
22
		<shell descriptive="New Folder" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.jface.wizard.WizardDialog" return-code="0">
23
			<command descriptive="folder" type="modify" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newFolderPage1" widgetId="Folder name:">
24
			<![CDATA[folder]]>
25
			</command>
26
			<command descriptive="Finish" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{16}}-{{1.0}}"/>
27
		</shell>
28
		<command descriptive="TestProject" type="item-expand" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}" value="true">
29
			<item widgetId="{{/TestProject}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
30
		</command>
31
		<command type="wait"/>
32
		<command descriptive="File" type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="popup/view/org.eclipse.jdt.ui.PackageExplorer/{{/}}-{{1.0}}@@@org.eclipse.tptp.test.auto.gui.adaptive" widgetId="{{New-File}}-{{1.0}}"/>
33
		<shell descriptive="New File" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.jface.wizard.WizardDialog" return-code="0">
34
			<command descriptive="test.txt" type="modify" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newFilePage1" widgetId="File name:">
35
			<![CDATA[test.txt]]>
36
			</command>
37
			<command descriptive="Finish" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{16}}-{{1.0}}"/>
38
		</shell>
39
		<command descriptive="folder" type="item-expand" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}" value="true">
40
			<item widgetId="{{/TestProject/folder}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
41
		</command>
42
		<command descriptive="TestProject" type="item-expand" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}" value="true">
43
			<item widgetId="{{/TestProject}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
44
		</command>
45
		<command descriptive="test.txt" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}">
46
			<item widgetId="{{/TestProject/folder/test.txt}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
47
		</command>
48
		<command type="wait"/>
49
		<command descriptive="Test" type="modify" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="editor/org.eclipse.ui.DefaultTextEditor/test.txt" widgetId="org.eclipse.swt.custom.StyledText#1">
50
		<![CDATA[Test]]>
51
		</command>
52
		<command type="wait"/>
53
		<command descriptive="Test" type="focus" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="editor/org.eclipse.ui.DefaultTextEditor/test.txt" widgetId="org.eclipse.swt.custom.StyledText#1"/>
54
		<command descriptive="TestProject" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}">
55
			<item widgetId="{{/TestProject}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
56
		</command>
57
		<command type="focus" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="org.eclipse.swt.widgets.Composite#1"/>
58
		<command descriptive="Delete Delete" type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="popup/view/org.eclipse.jdt.ui.PackageExplorer/{{/}}-{{1.0}}" widgetId="{{Delete&amp;#x9;Delete}}-{{1.0}}"/>
59
		<shell descriptive="Delete Resources" widgetId="org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2" return-code="0">
60
			<command descriptive="Delete project contents on disk (cannot be undone..." type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="shell" widgetId="{{Delete project contents on disk (cannot be undone)}}-{{0.3}}{{null}}-{{0.3}}{{1}}-{{0.3}}{{(484,16)}}-{{0.2}}{{(5,5)}}-{{0.1}}{{0}}-{{0.2}}" selection="true"/>
61
			<command descriptive="OK" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="shell" widgetId="{{0}}-{{1.0}}"/>
62
		</shell>		
63
	</shell>
64
</macro>
(-)src/org/eclipse/tptp/test/auto/gui/internal/tests/common/stubs/AutoGUINode.java (+406 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs;
12
13
import org.w3c.dom.Attr;
14
import org.w3c.dom.DOMException;
15
import org.w3c.dom.Document;
16
import org.w3c.dom.Element;
17
import org.w3c.dom.NamedNodeMap;
18
import org.w3c.dom.Node;
19
import org.w3c.dom.NodeList;
20
import org.w3c.dom.TypeInfo;
21
import org.w3c.dom.UserDataHandler;
22
23
public class AutoGUINode implements Node, Element
24
{
25
	private String name;
26
	private String value;
27
	private AutoGUINodeList children;
28
	private AutoGUINamedNodeMap attributes;	
29
30
	public AutoGUINode(String name, String value, AutoGUINodeList children, AutoGUINamedNodeMap attributes)
31
	{
32
		this.name = name;
33
		this.value = value;
34
		this.children = children;
35
		this.attributes = attributes;
36
	}
37
	
38
	
39
	public Node appendChild(Node newChild) throws DOMException
40
	{
41
		
42
		return null;
43
	}
44
45
	public Node cloneNode(boolean deep)
46
	{
47
		
48
		return null;
49
	}
50
51
	public NamedNodeMap getAttributes()
52
	{
53
		return attributes;
54
	}
55
56
	public NodeList getChildNodes()
57
	{
58
		return children;
59
	}
60
61
	public Node getFirstChild()
62
	{
63
		
64
		return null;
65
	}
66
67
	public Node getLastChild()
68
	{
69
		
70
		return null;
71
	}
72
73
	public String getLocalName()
74
	{
75
		
76
		return null;
77
	}
78
79
	public String getNamespaceURI()
80
	{
81
		
82
		return null;
83
	}
84
85
	public Node getNextSibling()
86
	{
87
		
88
		return null;
89
	}
90
91
	public String getNodeName()
92
	{		
93
		return name;
94
	}
95
96
	public short getNodeType()
97
	{
98
		
99
		return 0;
100
	}
101
102
	public String getNodeValue() throws DOMException
103
	{		
104
		return value;
105
	}
106
107
	public Document getOwnerDocument()
108
	{
109
		
110
		return null;
111
	}
112
113
	public Node getParentNode()
114
	{
115
		
116
		return null;
117
	}
118
119
	public String getPrefix()
120
	{
121
		
122
		return null;
123
	}
124
125
	public Node getPreviousSibling()
126
	{
127
		
128
		return null;
129
	}
130
131
	public boolean hasAttributes()
132
	{
133
		
134
		return false;
135
	}
136
137
	public boolean hasChildNodes()
138
	{
139
		
140
		return false;
141
	}
142
143
	public Node insertBefore(Node newChild, Node refChild) throws DOMException
144
	{
145
		
146
		return null;
147
	}
148
149
	public boolean isSupported(String feature, String version)
150
	{
151
		
152
		return false;
153
	}
154
155
	public void normalize()
156
	{
157
		
158
159
	}
160
161
	public Node removeChild(Node oldChild) throws DOMException
162
	{
163
		
164
		return null;
165
	}
166
167
	public Node replaceChild(Node newChild, Node oldChild) throws DOMException
168
	{
169
		
170
		return null;
171
	}
172
173
	public void setNodeValue(String nodeValue) throws DOMException
174
	{
175
		
176
177
	}
178
179
	public void setPrefix(String prefix) throws DOMException
180
	{
181
		
182
183
	}
184
185
186
	public String getAttribute(String name)
187
	{
188
		Node node = attributes.getNamedItem(name);
189
		return node == null ? null : node.getNodeValue();
190
	}
191
192
193
	public String getAttributeNS(String namespaceURI, String localName)
194
	{		
195
		return null;
196
	}
197
198
199
	public Attr getAttributeNode(String name)
200
	{
201
		return null;
202
	}
203
204
205
	public Attr getAttributeNodeNS(String namespaceURI, String localName)
206
	{
207
		return null;
208
	}
209
210
211
	public NodeList getElementsByTagName(String name)
212
	{
213
		
214
		return null;
215
	}
216
217
218
	public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
219
	{
220
		
221
		return null;
222
	}
223
224
225
	public String getTagName()
226
	{
227
		
228
		return null;
229
	}
230
231
232
	public boolean hasAttribute(String name)
233
	{
234
		
235
		return false;
236
	}
237
238
239
	public boolean hasAttributeNS(String namespaceURI, String localName)
240
	{
241
		
242
		return false;
243
	}
244
245
246
	public void removeAttribute(String name) throws DOMException
247
	{
248
		
249
		
250
	}
251
252
253
	public void removeAttributeNS(String namespaceURI, String localName) throws DOMException
254
	{
255
		
256
		
257
	}
258
259
260
	public Attr removeAttributeNode(Attr oldAttr) throws DOMException
261
	{
262
		
263
		return null;
264
	}
265
266
267
	public void setAttribute(String name, String value) throws DOMException
268
	{
269
		
270
		
271
	}
272
273
274
	public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException
275
	{
276
		
277
		
278
	}
279
280
281
	public Attr setAttributeNode(Attr newAttr) throws DOMException
282
	{
283
		
284
		return null;
285
	}
286
287
288
	public Attr setAttributeNodeNS(Attr newAttr) throws DOMException
289
	{
290
		
291
		return null;
292
	}
293
294
295
	public short compareDocumentPosition(Node other) throws DOMException
296
	{
297
		
298
		return 0;
299
	}
300
301
302
	public String getBaseURI()
303
	{
304
		
305
		return null;
306
	}
307
308
309
	public Object getFeature(String feature, String version)
310
	{
311
		
312
		return null;
313
	}
314
315
316
	public String getTextContent() throws DOMException
317
	{
318
		
319
		return null;
320
	}
321
322
323
	public Object getUserData(String key)
324
	{
325
		
326
		return null;
327
	}
328
329
330
	public boolean isDefaultNamespace(String namespaceURI)
331
	{
332
		
333
		return false;
334
	}
335
336
337
	public boolean isEqualNode(Node arg)
338
	{
339
		
340
		return false;
341
	}
342
343
344
	public boolean isSameNode(Node other)
345
	{
346
		
347
		return false;
348
	}
349
350
351
	public String lookupNamespaceURI(String prefix)
352
	{
353
		
354
		return null;
355
	}
356
357
358
	public String lookupPrefix(String namespaceURI)
359
	{
360
		
361
		return null;
362
	}
363
364
365
	public void setTextContent(String textContent) throws DOMException
366
	{
367
		
368
		
369
	}
370
371
372
	public Object setUserData(String key, Object data, UserDataHandler handler)
373
	{
374
		
375
		return null;
376
	}
377
378
379
	public TypeInfo getSchemaTypeInfo()
380
	{
381
		
382
		return null;
383
	}
384
385
386
	public void setIdAttribute(String name, boolean isId) throws DOMException
387
	{
388
		
389
		
390
	}
391
392
393
	public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException
394
	{
395
		
396
		
397
	}
398
399
400
	public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException
401
	{
402
		
403
		
404
	}
405
406
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/tests/common/stubs/AutoGUINodeList.java (+32 lines)
Added Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs;
2
3
import java.util.List;
4
5
import org.w3c.dom.Node;
6
import org.w3c.dom.NodeList;
7
8
public class AutoGUINodeList implements NodeList
9
{
10
	private List children; 
11
	
12
	public AutoGUINodeList (List nodes)
13
	{
14
		this.children = nodes;
15
	}
16
		
17
	public int getLength()
18
	{
19
		return children.size();
20
	}
21
22
	public Node item(int index)
23
	{
24
		return (Node)children.get(index);
25
	}
26
	
27
	public AutoGUINode[] getNodes()
28
	{
29
		return children == null ? null : (AutoGUINode[])children.toArray(new AutoGUINode[children.size()]);
30
	}
31
32
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/hook/TestUIObjectIdentifierDisambiguation.java (+75 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.hook;
13
14
import org.eclipse.swt.widgets.TreeItem;
15
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIVerificationHook;
16
17
/**
18
 * Generated code for the test suite <b>TestUIObjectIdentifierDisambiguation</b>
19
 * located at
20
 * <i>/TestProject/src/TestUIObjectIdentifierDisambiguation.testsuite</i>.
21
 */
22
public class TestUIObjectIdentifierDisambiguation extends
23
		AutoGUIVerificationHook {
24
25
	/**
26
	 * Constructor for TestUIObjectIdentifierDisambiguation. An instance of this
27
	 * class is created to test a test method.
28
	 * 
29
	 * @param testMethodName
30
	 *            The test method to be tested.
31
	 * @param paramTypes
32
	 *            The parameter types of the test method
33
	 * @param args
34
	 *            The arguments of the test method
35
	 */
36
	public TestUIObjectIdentifierDisambiguation(String testMethodName,
37
			Class[] paramTypes, Object[] args) {
38
		super(testMethodName, paramTypes, args);
39
	}
40
41
	/**
42
	 * @see junit.framework.TestCase#setUp()
43
	 */
44
	protected void setUp() throws Exception {
45
	}
46
47
	/**
48
	 * @see junit.framework.TestCase#tearDown()
49
	 */
50
	protected void tearDown() throws Exception {
51
	}
52
53
	/**
54
	 * Verify item was selected
55
	 * 
56
	 * @throws Exception
57
	 */
58
	public void verifyItemWasSelected(org.eclipse.ui.IEditorPart arg0,
59
			org.eclipse.swt.widgets.Tree arg1) throws Exception {
60
		TreeItem manifestItem = arg1.getItem(3);
61
		assertTrue(manifestItem.getChecked());
62
	}
63
64
	/**
65
	 * Verfiy item was deselected
66
	 * 
67
	 * @throws Exception
68
	 */
69
	public void verifyItemWasDeselected(org.eclipse.ui.IEditorPart arg0,
70
			org.eclipse.swt.widgets.Tree arg1) throws Exception {
71
		TreeItem manifestItem = arg1.getItem(3);
72
		assertFalse(manifestItem.getChecked());
73
	}
74
75
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/tests/common/util/AutoGUINodeUtil.java (+74 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.tests.common.util;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Map;
16
17
import org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs.AutoGUINamedNodeMap;
18
import org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs.AutoGUINode;
19
import org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs.AutoGUINodeList;
20
21
public class AutoGUINodeUtil
22
{
23
24
	public static AutoGUINodeList constructNodeList(AutoGUINode[] nodeData)
25
	{
26
		ArrayList list = new ArrayList();
27
		for (int i = 0; i < nodeData.length; i++)
28
		{
29
			list.add(nodeData[i]);
30
		}
31
		return new AutoGUINodeList(list);
32
	}
33
34
//	private static void constructNodeList(AutoGUINode[] nodeData, ArrayList list)
35
//	{
36
//		for (int i = 0; i < nodeData.length; i++)
37
//		{
38
//			AutoGUINodeList children = null;
39
//			if (nodeData[i].getChildNodes() != null)
40
//			{
41
//				children = constructNodeList(((AutoGUINodeList)nodeData[i].getChildNodes()).getNodes());
42
//			}
43
//			String[][] atts = null;
44
//			Map attributeMap = null;
45
//			if ((atts = nodeData[i].getAttributes()) != null)
46
//			{
47
//				attributeMap = new Hashtable();
48
//				for (int j = 0; j < atts.length; j++)
49
//				{
50
//					String[] currentAttribute = atts[j];
51
//					attributeMap.put(currentAttribute[0], currentAttribute[1]);
52
//				}
53
//			}
54
//			
55
//			list.add(new AutoGUINode(children, attributeMap == null ? null : new AutoGUINamedNodeMap(attributeMap)));
56
//		}
57
//	}
58
	
59
	public static AutoGUINode constructNode (String name, AutoGUINode[] children, String[][] attributes)
60
	{
61
		Map attributeMap = new Hashtable();
62
		if (attributes != null)
63
		{
64
			for (int i = 0; i < attributes.length; i++)
65
			{
66
				String[] attribute = attributes[i];
67
				attributeMap.put(attribute[0], new AutoGUINode(attribute[0], attribute[1], null, null));
68
			}
69
		}
70
		
71
		return new AutoGUINode(name, null, children == null ? null : constructNodeList(children), new AutoGUINamedNodeMap(attributeMap));
72
	}
73
74
}
(-)junit-plugin/TestSelectToolbarItem.xml (+10 lines)
Added Link Here
1
<macro version="1.1">
2
	<shell descriptive="Plug-in Development - TestPluginProject/src/Test.t..." resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.ui.internal.WorkbenchWindow" return-code="-1">
3
		<command type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="toolbar" widgetId="{{External Tools}}-{{0.7}}{{contribid/org.eclipse.ui.externaltools.ExternalToolMenuDelegateToolbar}}-{{0.7}}{{4}}-{{0.3}}" x-coord="152" y-coord="22" detail="4">
4
			<selected-item widgetId="{{External Tools Configurations...}}-{{1.0}}"/>
5
		</command>
6
		<shell descriptive="External Tools" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog" return-code="1">
7
			<command descriptive="Close" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="shell" widgetId="{{1026}}-{{1.0}}"/>
8
		</shell>
9
	</shell>
10
</macro>
(-)deployment/eclipse-ganymede-tptp-all-in-one-AGR.location (+5 lines)
Added Link Here
1
PK@ ú8ResourceContents­–Ûn›@†ï+õV{Ä®bË4rG‘š*ŠR5‘ª
2
ŒaÛ=i±ýö]Bb'؍Rá+`Ùù¿ùgF³³5gè´¡R$xž`¢%U‚Ü,‚Ÿ}ùøa–JÎ¥ø•J±¤•ÓÄúýÓtq~IŠš
3
ðëÆjB…EkN§[Áa#èÂLýz‚kkÕ4ŠV«U(yJ]E·—Ï[A^Å@Á¨2ðWoH	&â²f¢â1Ô_^„†‰-œÆó8žŒòá8χ‹4Å£a>žÒ,ŸYŠ‘ ü¤TDl8”XeU@¨¤€`~~Q-m÷3YÖ<b_#„fJKÚnεtʼ…îÐÞE¡©jÍÞÔÔ ª	Z¿ƒRD[Z8F4¢¾ÒD€äò6eôSê?÷¾u5’Â4I…϶vï®Ú)Œ^%{‘%ØWu[áÆxhÁ‹X)™	;Am¨˜«¨hÍîìzµ·¬~úG•¿ùâ5¦1z Ìùõlzçó«4áhA˜»÷µ£ÉX©œàèÿRuSóÚru
4
ÎÀ6«%aÍSʸK)Ý4Å(R@Fõa§]Øê
5
/ºé¥ÿ¹«_)}³Ì=Ä{mQŠÑvZ¾û…-êåÄ:ÒÂÕó¬÷Ê`ÒÍÀћZ{§[´Õ®ŸÉyáÃJWØÖ`á¯Ç­=T;kéié!›ueKXÇlkáBÐã5!?ЄæšëÊqv7Õ½0‹.æá!¸åCŽüÝúóiÌû0ç'{#l kyõxŒ›£•q¾ÿ!][Ђ°.ée½þl6¿Ñ»ÿ7üî¿PK•êkÅPK@ ú8•êkÅResourceContentsPK>©
(-)junit-plugin/TestStructuredSelectionCommands.xml (+29 lines)
Added Link Here
1
<macro version="1.1">
2
	<shell descriptive="Plug-in Development - TestPluginProject/src/Test.t..." widgetId="org.eclipse.ui.internal.WorkbenchWindow" return-code="-1">
3
		<command descriptive="Project..." type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="menus" widgetId="{{File-New&amp;#x9;Alt+Shift+N-Project...}}-{{1.0}}"/>
4
		<shell descriptive="New Project" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.jface.wizard.WizardDialog" return-code="0">
5
			<command descriptive="General" type="item-expand" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newWizardSelectionPage" widgetId="org.eclipse.swt.widgets.Tree#1" value="true">
6
				<item widgetId="{{org.eclipse.ui.Basic}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
7
			</command>
8
			<command descriptive="Project" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newWizardSelectionPage" widgetId="org.eclipse.swt.widgets.Tree#1">
9
				<item widgetId="{{org.eclipse.ui.wizards.new.project}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
10
			</command>
11
			<command type="focus" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/newWizardSelectionPage" widgetId="org.eclipse.swt.widgets.Tree#1"/>
12
			<command descriptive="Next &amp;gt;" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{15}}-{{1.0}}"/>
13
			<command descriptive="TestProject" type="modify" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="wizard-page/basicNewProjectPage" widgetId="Project name:">
14
			<![CDATA[TestProject]]>
15
			</command>
16
			<command descriptive="Finish" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="wizard" widgetId="{{16}}-{{1.0}}"/>
17
		</shell>
18
		<command type="wait"/>
19
		<command descriptive="TestProject" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="{{/}}-{{1.0}}">
20
			<item widgetId="{{/TestProject}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
21
		</command>
22
		<command type="focus" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="view/org.eclipse.jdt.ui.PackageExplorer" widgetId="org.eclipse.swt.widgets.Composite#1"/>
23
		<command descriptive="Delete Delete" type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="popup/view/org.eclipse.jdt.ui.PackageExplorer%%%{{/}}-{{1.0}}@@@org.eclipse.tptp.test.auto.gui.adaptive" widgetId="{{Delete&amp;#x9;Delete}}-{{1.0}}"/>
24
		<shell descriptive="Delete Resources" widgetId="org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2" return-code="0">
25
			<command descriptive="Delete project contents on disk (cannot be undone..." type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="shell" widgetId="{{Delete project contents on disk (cannot be undone)}}-{{0.3}}{{null}}-{{0.3}}{{1}}-{{0.3}}{{(484,16)}}-{{0.2}}{{(5,5)}}-{{0.1}}{{0}}-{{0.2}}" selection="true"/>
26
			<command descriptive="OK" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="shell" widgetId="{{0}}-{{1.0}}"/>
27
		</shell>			
28
	</shell>
29
</macro>
(-)junit-plugin/TestSingleSelectionCommandsOldFormat.xml (+12 lines)
Added Link Here
1
<macro version="1.1">
2
	<shell descriptive="Plug-in Development - TestPluginProject/src/Test.t..." resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.ui.internal.WorkbenchWindow" return-code="-1">
3
		<command descriptive="Preferences" type="select" contextId="menus" widgetId="{{Window-Preferences}}-{{1.0}}"/>
4
		<shell descriptive="Preferences" widgetId="org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog" return-code="1">
5
			<command descriptive="Team" type="item-select" contextId="shell" widgetId="org.eclipse.swt.widgets.Tree#1">
6
				<item widgetId="{{org.eclipse.team.ui.TeamPreferences}}-{{1.0}}"/>
7
			</command>
8
			<command descriptive="Resource" type="choice-select" contextId="shell" widgetId="org.eclipse.swt.widgets.Combo#1" choiceId="item#8"/>
9
			<command descriptive="Cancel" type="select" contextId="shell" widgetId="{{1}}-{{1.0}}"/>
10
		</shell>
11
	</shell>
12
</macro>
(-)gui/TestUiObjectIdentifierDisambiguation.artifact (+5 lines)
Added Link Here
1
PKאö8ResourceContentsŔ]o›0†ï'í? ﺘ†
2
«„.R§EK*í.rà$ñ6²MÓüûÚХ͚nÝÕ$$ËÖ{Þó¼þ`|ußÔÖI9Kk;ÈVòвm‚n—ÅEˆ®>½7ÎxÓp¶Ê8ÛÐm'ˆÒú8+®S¡è†”ʺoh|ôñŒvf2Öë	Ú)ÕÆï÷{›7[›‹-þþev”ÈSÉÞïžã¸Zv³(wАʤ"¬„_UçˆNl ¬i+¡÷ÚH7¼‚Zâ²/ÕóR[ƒþf½©ZÁ7´†3VO…ƒ-­”ºy>
3
Ð+¦£ÈKiè¸×}?¸ôG~„,FÝÈt½¥_×? T³
4
˜Þ_
5
"§’4kMÛÃ"}$–5Ö=Zêp-x×Ê]&ÑäL—“¢Yž ãiˆc›öéöÇƒ¶‰R‚®;-(ž8(œep_KšÝ¤‹Å<]~FÖ©;½’Çx.¸I.ñ7@D¹ÃªUíŠtН¶]í¹ø)[R~Îm4µÚZˆ×”!ËpÅE‚„߆ëýÜ~&_ƒãÓ£+hk~ ëfoCZú-ÅêÐܗ8^Î3]tTég´°Imcý½	Îìj;g¾ƒÜ4ùE—Áôc1²I]¦EŒr'¿ôC×ͳ>ßÿíï¢EPKùŠôªPKאö8ùŠôªResourceContentsPK>2
(-)deployment/eclipse-ganymede-tptp-all-in-one-AGR.deploy (+4 lines)
Added Link Here
1
PK¡>÷8ResourceContentsåV]o›0}Ÿ´ÿ€è3lCœ(YEÀT•-šÒioȇ¸ƒ°³4ÿ~MÚ®­ÖmjªM“xáâsÏǕ¯ŸÞԕõwJ4rbûÀ³-.󦲜ؗ‹Ô!öé‡÷ïÆqS׍Ì\é¶k–¢â£Å<Mx[5ۚKmÝÔbt×îú˜ÎRL}b¯´nG®»Ùl@S— éJ÷Ëìüpäiï<¯D«xZmYÁ•[7¯”›÷@W߁¡³-QLì4E0!ØDŸú„b2Qxq2ľŸÄ¶%Ymˆöݝ’Ic¤àŽnuë°ªr„tɝèì“m°¬qǗM䱨¬•y›ØôåSJäx†³Å|1Ï0€7àÚCNbDS#*ÄûIB¦q§áÀÉ4í¹ÿ	
2
‘&;£é¾Lgiî«fˆ!¦0 ¦qŒ	†4úqB‡¿&à§3ÿ}"Öi±d¹¾cëËæÃ¡Ó1Ùðïip¯×Rh§­Ö¥îîzín“…šng,ïšyŶW,ÿ
3
ГȌ2 ƒˆzÔ÷`ln‹§!„
4
ÃààÕ}Þì_˜A¹½õKññêšçú¼0ÛJ,ï¡X}%ÊuOò8ÀÔpÀÈ£Äó§>"…høgpþ8ƒÏ‚Ý–fBò§ 4†!Nÿ8u¯Á<fß-óW°[܀­uŒBPtl‹¾¨Ž8¶WÔöÚq>#íMsxKcGÚMc÷¥?sè;PKßT›§0öPK¡>÷8ßT›§0öResourceContentsPK>n
(-)src/org/eclipse/tptp/test/auto/gui/internal/junit_plugins/TestCommandsByMacroPlayback.java (+216 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.junit_plugins;
13
14
import java.io.BufferedReader;
15
import java.io.ByteArrayInputStream;
16
import java.io.IOException;
17
import java.io.InputStream;
18
import java.io.InputStreamReader;
19
20
import junit.framework.Test;
21
import junit.framework.TestSuite;
22
23
import org.eclipse.core.runtime.FileLocator;
24
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.core.runtime.Path;
26
import org.eclipse.hyades.test.common.junit.HyadesTestCase;
27
import org.eclipse.jface.operation.IRunnableWithProgress;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants;
31
import org.eclipse.tptp.test.auto.gui.internal.tests.TestsPlugin;
32
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
33
import org.eclipse.ui.PlatformUI;
34
35
/**
36
 * Generated code for the test suite <b>TestCommandsByMacroPlayback</b> located
37
 * at <i>/org.eclipse.tptp.test.auto.gui.internal.tests/junit-plugin/
38
 * MacroPlaybackTests.testsuite</i>.
39
 */
40
public class TestCommandsByMacroPlayback extends HyadesTestCase {
41
42
	public static final String ENCODING = "UTF-8";
43
44
	/**
45
	 * Constructor for TestCommandsByMacroPlayback.
46
	 * 
47
	 * @param name
48
	 */
49
	public TestCommandsByMacroPlayback(String name) {
50
		super(name);
51
	}
52
53
	/**
54
	 * Returns the JUnit test suite that implements the
55
	 * <b>TestCommandsByMacroPlayback</b> definition.
56
	 */
57
	public static Test suite() {
58
		TestSuite testCommandsByMacroPlayback = new TestSuite(
59
				TestCommandsByMacroPlayback.class);
60
		return testCommandsByMacroPlayback;
61
	}
62
63
	/**
64
	 * @see junit.framework.TestCase#setUp()
65
	 */
66
	protected void setUp() throws Exception {
67
	}
68
69
	/**
70
	 * @see junit.framework.TestCase#tearDown()
71
	 */
72
	protected void tearDown() throws Exception {
73
	}
74
75
	/**
76
	 * testSingleSelectionCommands
77
	 * 
78
	 * Tests selection of boolean selection (type "select") for MenuItem and
79
	 * Button, as well as choice selection (type "choice-select") for button
80
	 * 
81
	 * @throws Exception
82
	 */
83
	public void testSingleSelectionCommands() {
84
		// StringBuffer s = new StringBuffer();
85
		// s.append("<macro version=\"1.0\">");
86
		// s.append("<shell descriptive=\"Plug-in Development -
87
		// TestPluginProject/src/TestUIObjectIdentifierDisambiguation.t...\"
88
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.nontrivial\"
89
		// id=\"org.eclipse.ui.internal.WorkbenchWindow\" return-code=\"-1\">");
90
		// s.append("<command descriptive=\"Preferences...\" type=\"select\"
91
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.nontrivial\"
92
		// contextId=\"menus\"
93
		// widgetId=\"{{Window-Preferences...}}-{{1.0}}\"/>");
94
		// s.append("<shell descriptive=\"Preferences\"
95
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.nontrivial\"
96
		// id=\"org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog\"
97
		// return-code=\"1\">");
98
		// s.append("<command descriptive=\"Team\" type=\"item-select\"
99
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.nontrivial\"
100
		// contextId=\"shell\" widgetId=\"org.eclipse.swt.widgets.Tree#1\">");
101
		// s.append("<item
102
		// path=\"{{org.eclipse.team.ui.TeamPreferences}}-{{1.0}}\"
103
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.adaptive\"/>");
104
		// s.append("</command>");
105
		// s.append("<command descriptive=\"Resource\" type=\"choice-select\"
106
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.nontrivial\"
107
		// contextId=\"shell\"
108
		// widgetId=\"org.eclipse.swt.widgets.Combo#1/item#8\"/>");
109
		// s.append("<command descriptive=\"Cancel\" type=\"select\"
110
		// resolverId=\"org.eclipse.tptp.test.auto.gui.internal.adaptive\"
111
		// contextId=\"shell\" widgetId=\"{{1}}-{{1.0}}\"/>");
112
		// s.append("</shell>");
113
		// s.append("</shell>");
114
		// s.append("</macro>");
115
		// playbackMacro(s.toString());
116
		String macro = readMacro("TestSingleSelectionCommands.xml");
117
		assertNotNull(macro);
118
		playbackMacro(macro);
119
	}
120
121
	/**
122
	 * testSingleSelectionCommandsBackwardsCompatibility Tests the same as
123
	 * testSingleSelectionCommands, only that the macro has the old format using
124
	 * a separate choiceId for ChoiceSelectionCommand and does not provide
125
	 * resolver ids.
126
	 */
127
	public void testSingleSelectionCommandsBackwardsCompatibility() {
128
		playbackMacro(readMacro("TestSingleSelectionCommandsOldFormat.xml"));
129
	}
130
131
	/**
132
	 * testStructuredSelectionCommands TestUIObjectIdentifierDisambiguation
133
	 * structured selection (item expansion and item selection), menu selection,
134
	 * and popup menu item selection commands by creating a new SimpleProject
135
	 * and deleting it again via the context menu.
136
	 */
137
	public void testStructuredSelectionCommands() {
138
		playbackMacro(readMacro("TestStructuredSelectionCommands.xml"));
139
	}
140
141
	/**
142
	 * testToolbarItemSelectionCommand
143
	 * 
144
	 * @throws Exception
145
	 */
146
	public void testToolbarItemSelectionCommand() throws Exception {
147
		playbackMacro(readMacro("TestSelectToolbarItem.xml"));
148
	}
149
150
	protected String readMacro(String macroFileName) {
151
		StringBuffer sb = new StringBuffer();
152
		try {
153
			InputStream is = FileLocator.openStream(TestsPlugin.getDefault()
154
					.getBundle(), new Path("junit-plugin/" + macroFileName),
155
					false);
156
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
157
158
			String currentLine = null;
159
			do {
160
				currentLine = br.readLine();
161
				if (currentLine != null) {
162
					sb.append(currentLine);
163
				}
164
			} while (currentLine != null);
165
		} catch (IOException e) {
166
			e.printStackTrace();
167
			return null;
168
		}
169
		return sb.toString();
170
	}
171
172
	protected final void playbackMacro(final String macroString) {
173
		// just to ensure that we can see something during playback
174
		PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
175
			public void run() {
176
				MacroUtil.closeWelcomePage();
177
			}
178
		});
179
180
		// playback the current macro
181
		try {
182
			PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(true,
183
					false, new IRunnableWithProgress() {
184
						public void run(IProgressMonitor monitor) {
185
							try {
186
								XMLDefaultHandler handler = MacroManager
187
										.getInstance()
188
										.createMacroDocument(
189
												new ByteArrayInputStream(
190
														macroString
191
																.getBytes(ENCODING)));
192
193
								MacroManager.getInstance()
194
										.setCommandTimeoutThreshold(3000);
195
								MacroManager.getInstance().setGlobalState(
196
										ModeConstants.EXECUTION_RUN_MODE);
197
								MacroManager.getInstance().play(
198
										PlatformUI.getWorkbench().getDisplay(),
199
										null, "TestMacro", handler,
200
										Boolean.TRUE);
201
							} catch (Exception e) {
202
								e.printStackTrace();
203
								fail(e.getMessage());
204
							}
205
						}
206
					});
207
		} catch (Exception e) {
208
			e.printStackTrace();
209
			if (e.getCause() != null) {
210
				e.printStackTrace();
211
			}
212
			fail(e.getMessage());
213
		}
214
	}
215
216
}
(-)junit-plugin/TestSingleSelectionCommands.xml (+12 lines)
Added Link Here
1
<macro version="1.1">
2
	<shell descriptive="Plug-in Development - TestPluginProject/src/Test.t..." resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.ui.internal.WorkbenchWindow" return-code="-1">
3
				<command descriptive="Preferences" type="select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="menus" widgetId="{{Window-Preferences}}-{{1.0}}"/>
4
		<shell descriptive="Preferences" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" widgetId="org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog" return-code="1">
5
			<command descriptive="Team" type="item-select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="shell" widgetId="org.eclipse.swt.widgets.Tree#1">
6
				<item widgetId="{{org.eclipse.team.ui.TeamPreferences}}-{{1.0}}" resolverId="org.eclipse.tptp.test.auto.gui.adaptive"/>
7
			</command>
8
			<command descriptive="Resource" type="choice-select" resolverId="org.eclipse.tptp.test.auto.gui.nontrivial" contextId="shell" widgetId="org.eclipse.swt.widgets.Combo#1" objectId="item#8"/>
9
			<command descriptive="Cancel" type="select" resolverId="org.eclipse.tptp.test.auto.gui.adaptive" contextId="shell" widgetId="{{1}}-{{1.0}}"/>
10
		</shell>
11
	</shell>
12
</macro>
(-)gui/TestUIObjectIdentifierViaObjectMine.artifact (+5 lines)
Added Link Here
1
PKçö8ResourceContents½”Qo›0Çß'í; ï¹BH)
2
«„.R«EK:í-ràÞÀF¶išo?;tiÓ¤jö2	ÉòéÿûÝÙf|ýØÔÖI9‹k;Ȗó‚²2B÷‹ì"@ן?~'¼i8[&œ­iÙ	¢´>L²›X(º&¹²î}ÆG;3êx„*¥ÚãÍfcó¦´¹(ñÏ»é^"%o§8Ž«e·ó¼‚†\P&a9üÍ:Et`yM[	;¯jK
3
¸áÔç»T½¼Hµ5è+ëHÕ
4
¾¦5ü›±zNìmi¡ØMS?p/K£aæLÇýâzç†žï]!‹‘F2Uï§ßV¿ WӘž/ñƒ’>tG }"–5Ö%Zj{#x×ÊSEÜã"IÓ4Bº‹}G}7¶á·§CžÎÙ&J	ºê´¤§xæ pÌ$ˍ&·ñ|>‹_‘õ@êNGÒÏ7]Jü$‘WXµª]’NñeÙÑ冋߲%9à—ÜFÓS¡­…xE²Q\D(Bø<Ü#û¸»|zŒºÐÖ|KV5LŸž†´ôS
5
Õ¶5¸Gw8\Ì2³wTéWT	XGȶ±þ΂3S=ãröjSãÓÄ÷²Ì½Šýxä»Y–dÃør88ǹnšìÚã÷þ-ZôPKôR@»ñ¨PKçö8ôR@»ñ¨ResourceContentsPK>/
(-)src/org/eclipse/tptp/test/auto/gui/internal/tests/common/stubs/AutoGUINamedNodeMap.java (+75 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM - Initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.tests.common.stubs;
12
13
import java.util.Map;
14
15
import org.w3c.dom.DOMException;
16
import org.w3c.dom.NamedNodeMap;
17
import org.w3c.dom.Node;
18
19
public class AutoGUINamedNodeMap implements NamedNodeMap
20
{
21
	private Map attributes;
22
	
23
	public AutoGUINamedNodeMap(Map attributes)
24
	{
25
		this.attributes = attributes;
26
	}
27
	
28
	public int getLength()
29
	{
30
		return attributes.size();
31
	}
32
33
	public Node getNamedItem(String name)
34
	{
35
		return (Node)attributes.get(name);
36
	}
37
38
	public Node getNamedItemNS(String namespaceURI, String localName)
39
	{
40
		
41
		return null;
42
	}
43
44
	public Node item(int index)
45
	{
46
		
47
		return null;
48
	}
49
50
	public Node removeNamedItem(String name) throws DOMException
51
	{
52
		
53
		return null;
54
	}
55
56
	public Node removeNamedItemNS(String namespaceURI, String localName)
57
			throws DOMException
58
	{
59
		
60
		return null;
61
	}
62
63
	public Node setNamedItem(Node arg) throws DOMException
64
	{
65
		
66
		return null;
67
	}
68
69
	public Node setNamedItemNS(Node arg) throws DOMException
70
	{
71
		
72
		return null;
73
	}
74
75
}
(-).settings/org.eclipse.jdt.core.prefs (+12 lines)
Added Link Here
1
#Mon Jan 28 23:44:11 CET 2008
2
eclipse.preferences.version=1
3
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6
org.eclipse.jdt.core.compiler.compliance=1.4
7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8
org.eclipse.jdt.core.compiler.debug.localVariable=generate
9
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
11
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
12
org.eclipse.jdt.core.compiler.source=1.3
(-)junit-plugin/TestCommandsByMacroPlayback.artifact (+4 lines)
Added Link Here
1
PK÷=÷8ResourceContentsœKOã0…÷#ñ"³&ÎCí (ÊT©š‰]å:nâ!±-Û!äߏ@!P汚Uä«sŽ¿›ë_<5µóH¤¢œ%Àw=à†yAY™€»Íâì\|;ùg¼i8ÛfœíiÙJ¤>ÊשÔt°vžr›c’™ŠL=•Ö"‚°ë:—7¥Ëe	ïo—‰šJºpPžçÙÍW¤Ag”)&/®cD“‚k*²ªDÁ†¤VVóycu
2
è»è
3
QZH¾§5ù·`ýjci‘€ÔÏóÙù×ôÊ»ò½ ó²Ü.ƒ0góY8ŸÏ€ÃPc.²·ZÄ
4
uÙß",ùªFýá`&á8±‰DêþZòV¨cáþÇð‰i™'ÀÐ:»p-·;ý+èy¾.ÒZÒ]k$#Å+%G‚ÏÌnÒõz•n¾çÕ­©ä\Iþ“`­à¢’¸‚Zh±E­æÛ²¥ÛŽË%&ð-·ÕŒÔVè!ÜQ˅4—	Hü;Üð¿à'õt§£‹5ïÑ®&Ëç•PŽY¡H÷Ââ~x»Ñfµ°ÇuKµÙžJ’ýo_ÙÈdŧîÃ?m¿ýPKn2L©ÄJPK÷=÷8n2L©ÄJResourceContentsPK>
(-)feature.properties (-122 lines)
Removed Link Here
1
###############################################################################
2
# Copyright (c) 2005, 2008 IBM Corporation and others.
3
# All rights reserved. This program and the accompanying materials 
4
# are made available under the terms of the Eclipse Public License v1.0
5
# which accompanies this distribution, and is available at
6
# http://www.eclipse.org/legal/epl-v10.html
7
# $Id: feature.properties,v 1.6 2008/04/10 01:18:10 paules Exp $
8
# 
9
# Contributors:
10
#     IBM Corporation - initial API and implementation
11
###############################################################################
12
13
# feature.properties
14
# contains externalized strings for feature.xml
15
# "%foo" in feature.xml corresponds to the key "foo" in this file
16
# java.io.Properties file (ISO 8859-1 with "\" escapes)
17
# This file should be translated.
18
19
# NLS_MESSAGEFORMAT_NONE
20
# NLS_ENCODING=UTF-8
21
22
# "featureName" property - name of the feature
23
featureName=TPTP Automated GUI Recorder (AGR)
24
25
# "licenseURL" property - URL of the "Feature License"
26
# do not translate value - just change to point to a locale-specific HTML page
27
licenseURL=license.html
28
29
# "description" property - description of the feature
30
description=TPTP Automated GUI Recorder (AGR) used to record and playback user interactions with an Eclipse application. 
31
32
# "providerName" property - name of the company that provides the feature
33
providerName=Eclipse.org
34
35
# "license" property - text of the "Feature Update License"
36
# should be plain text version of license agreement pointed to be "licenseURL"
37
license=\
38
Eclipse Foundation Software User Agreement\n\
39
January 28, 2005\n\
40
\n\
41
Usage Of Content\n\
42
THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION \n\
43
AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE \n\
44
OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR \n\
45
THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR \n\
46
REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT \n\
47
IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE \n\
48
LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT \n\
49
AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND \n\
50
CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR \n\
51
REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
52
\n\
53
Applicable Licenses\n\
54
Unless otherwise indicated, all Content made available by the Eclipse \n\
55
Foundation is provided to you under the terms and conditions of the Eclipse \n\
56
Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this \n\
57
Content and is also available at http://www.eclipse.org/legal/epl-v10.html. For \n\
58
purposes of the EPL, "Program" will mean the Content.\n\
59
\n\
60
Content includes, but is not limited to, source code, object code, \n\
61
documentation and other files maintained in the Eclipse.org CVS repository \n\
62
("Repository") in CVS modules ("Modules") and made available as downloadable \n\
63
archives ("Downloads").\n\
64
\n\
65
Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments \n\
66
("Fragments"), and features ("Features"). A Feature is a bundle of one or more \n\
67
Plug-ins and/or Fragments and associated material. Files named "feature.xml" \n\
68
may contain a list of the names and version numbers of the Plug-ins and/or \n\
69
Fragments associated with a Feature. Plug-ins and Fragments are located in \n\
70
directories named "plugins" and Features are located in directories named \n\
71
"features".\n\
72
\n\
73
Features may also include other Features ("Included Features"). Files named \n\
74
"feature.xml" may contain a list of the names and version numbers of Included \n\
75
Features.\n\
76
\n\
77
The terms and conditions governing Plug-ins and Fragments should be contained \n\
78
in files named "about.html" ("Abouts"). The terms and conditions governing \n\
79
Features and Included Features should be contained in files named \n\
80
"license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located \n\
81
in any directory of a Download or Module including, but not limited to the \n\
82
following locations:\n\
83
\n\
84
The top-level (root) directory \n\
85
Plug-in and Fragment directories \n\
86
Subdirectories of the directory named "src" of certain Plug-ins \n\
87
Feature directories \n\
88
Note: if a Feature made available by the Eclipse Foundation is installed using \n\
89
the Eclipse Update Manager, you must agree to a license ("Feature Update \n\
90
License") during the installation process. If the Feature contains Included \n\
91
Features, the Feature Update License should either provide you with the terms \n\
92
and conditions governing the Included Features or inform you where you can \n\
93
locate them. Feature Update Licenses may be found in the "license" property of \n\
94
files named "feature.properties". Such Abouts, Feature Licenses and Feature \n\
95
Update Licenses contain the terms and conditions (or references to such terms \n\
96
and conditions) that govern your use of the associated Content in that \n\
97
directory.\n\
98
\n\
99
THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL \n\
100
OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE \n\
101
OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
102
\n\
103
Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html) \n\
104
Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE) \n\
105
Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0) \n\
106
IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html) \n\
107
Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html) \n\
108
Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html) \n\
109
\n\
110
IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO \n\
111
USE OF THE CONTENT. If no About, Feature License or Feature Update License is \n\
112
provided, please contact the Eclipse Foundation to determine what terms and \n\
113
conditions govern that particular Content.\n\
114
\n\
115
Cryptography\n\
116
Content may contain encryption software. The country in which you are currently \n\
117
may have restrictions on the import, possession, and use, and/or re-export to \n\
118
another country, of encryption software. BEFORE using any encryption software, \n\
119
please check the country's laws, regulations and policies concerning the \n\
120
import, possession, or use, and re-export of encryption software, to see if \n\
121
this is permitted.\n
122
########### end of license property ##########################################
(-)feature.xml (-1 / +1 lines)
Lines 15-21 Link Here
15
<feature
15
<feature
16
      id="org.eclipse.tptp.test.auto"
16
      id="org.eclipse.tptp.test.auto"
17
      label="%featureName"
17
      label="%featureName"
18
      version="4.2.0.qualifier"
18
      version="4.6.0.qualifier"
19
      provider-name="%providerName">
19
      provider-name="%providerName">
20
20
21
   <description>
21
   <description>
(-)build.properties (-4 / +3 lines)
Lines 1-4 Link Here
1
bin.includes = feature.xml,\
1
bin.includes = feature.xml,\
2
               epl-v10.html,\
2
               epl-v10.html,\
3
               feature.properties,\
3
               license.html
4
               license.html
(-).project (+22 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<projectDescription>
3
	<name>org.eclipse.tptp.test.auto-feature</name>
4
	<comment></comment>
5
	<projects>
6
	</projects>
7
	<buildSpec>
8
		<buildCommand>
9
			<name>org.eclipse.pde.ManifestBuilder</name>
10
			<arguments>
11
			</arguments>
12
		</buildCommand>
13
		<buildCommand>
14
			<name>org.eclipse.pde.SchemaBuilder</name>
15
			<arguments>
16
			</arguments>
17
		</buildCommand>
18
	</buildSpec>
19
	<natures>
20
		<nature>org.eclipse.pde.PluginNature</nature>
21
	</natures>
22
</projectDescription>
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/VerificationCommand.java (-398 / +574 lines)
Lines 1-398 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: VerificationCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
7
 * $Id: VerificationCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
13
14
import java.io.File;
14
import java.io.File;
15
import java.lang.reflect.Constructor;
15
import java.lang.reflect.Constructor;
16
import java.net.URL;
16
import java.net.MalformedURLException;
17
import java.util.Hashtable;
17
import java.net.URL;
18
import java.util.StringTokenizer;
18
import java.util.Hashtable;
19
import java.util.Vector;
19
import java.util.StringTokenizer;
20
20
import java.util.Vector;
21
import org.eclipse.core.runtime.CoreException;
21
22
import org.eclipse.core.runtime.IProgressMonitor;
22
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.Path;
23
import org.eclipse.core.runtime.IProgressMonitor;
24
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
24
import org.eclipse.core.runtime.Path;
25
import org.eclipse.jdt.core.IJavaProject;
25
import org.eclipse.hyades.test.common.junit.HyadesTestSuite;
26
import org.eclipse.jface.dialogs.MessageDialog;
26
import org.eclipse.jdt.core.IJavaProject;
27
import org.eclipse.osgi.util.NLS;
27
import org.eclipse.jface.dialogs.MessageDialog;
28
import org.eclipse.swt.SWT;
28
import org.eclipse.osgi.util.NLS;
29
import org.eclipse.swt.widgets.Composite;
29
import org.eclipse.swt.widgets.Display;
30
import org.eclipse.swt.widgets.Display;
30
import org.eclipse.swt.widgets.Event;
31
import org.eclipse.swt.widgets.Event;
31
import org.eclipse.swt.widgets.Shell;
32
import org.eclipse.swt.widgets.Shell;
32
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
33
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
33
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
34
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
35
import org.eclipse.tptp.test.auto.gui.internal.core.VerifHookClassLoader;
35
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
36
import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData;
36
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
37
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
39
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
40
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
41
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIVerificationHook;
42
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIVerificationHook;
42
import org.eclipse.tptp.test.auto.gui.internal.util.VerificationHookClassLoader;
43
import org.eclipse.ui.IEditorPart;
43
import org.eclipse.ui.IEditorPart;
44
import org.eclipse.ui.IViewPart;
44
import org.eclipse.ui.IViewPart;
45
import org.w3c.dom.Node;
45
import org.w3c.dom.Node;
46
46
47
47
/**
48
/**
48
 * The following command is inserted for every verification hook that the user
49
 * The following command is inserted for every verification hook that the 
49
 * inserts for a particular test case. An instance of this class can only be
50
 * user inserts for a particular test case.  An instance of this class can
50
 * created through constructInstance(Event). <br/> In order for clients to be
51
 * only be created through constructInstance(Event). <br/>
51
 * able to write or playback this command they must meet the following
52
 * In order for clients to be able to write or playback this command they must
52
 * pre-conditions.
53
 * meet the following pre-conditions.
53
 * 
54
 * 
54
 * <ul>
55
 * <ul>
55
 * <li> test suite must be set using setTestSuite </li>
56
 * 	<li> test suite must be set using setTestSuite </li>
56
 * <li> verification hook must be set using setVerificationHook </li>
57
 * 	<li> verification hook must be set using setVerificationHook </li>
57
 * </ul>
58
 * </ul>
58
 * 
59
 * 
59
 * @author Ali Mehregani
60
 * @author Ali Mehregani
60
 * @author Alexander Nyssen (refactored to be a normal object based command and
61
 */
61
 *         use the new resolving mechanism)
62
public class VerificationCommand extends AbstractMacroCommand
62
 */
63
{	
63
public class VerificationCommand extends ObjectBasedCommand {
64
	/* The type of this command */
64
65
	public static final String TYPE = "verification";
65
	/* The type of this command */
66
66
	public static final String TYPE = IMacroCommand.VERIFICATION;
67
	/* This instance variable is updated if at any point there is an error 
67
68
	 * creating an instance of this class through constructInstance.  This can
68
	/* The possible types */
69
	 * be null if no errors are to be reported */
69
	public static final byte EDITOR = 0x01;
70
	private static String error;
70
	public static final byte VIEW = 0x02;
71
	
71
	public static final byte SHELL = 0x03;
72
	/* The meta data required by this verification command */
72
73
	private VerificationMetaData metaData;
73
	/* The location is the plugin that contains the hook source code */
74
	
74
	private String location;
75
	/* To be acknowledged events */
75
76
	private static WidgetIdentifier toBeAck;
76
	/* The resource is the class name containing the hook */
77
	
77
	private String resource;
78
	/**
78
79
	 * The constructor 
79
	/* The hook is the method name representing the verification point */
80
	 * 
80
	private String hook;
81
	 * @param metaData The meta data that this verification command uses to write
81
82
	 * or play back itself.
82
	/* The focus type indicates whether the type of context being retrieved */
83
	 */
83
	private byte focusType;
84
	public VerificationCommand (MacroCommandShell parent, VerificationMetaData metaData)
84
85
	{
85
	private Class contextClass;
86
		super(parent, WidgetIdentifier.NULL_IDENTIFIER);			/* The widget id is irrelevant in the verification command.  This is just a dummy command */
86
87
		this.metaData = metaData;
87
	private Class widgetClass;
88
	}
88
89
89
	private Class objectClass;
90
	public String getType()
90
91
	{
91
	/*
92
		return TYPE;
92
	 * flag to indicate if additionally to the context id, an object id should
93
	}
93
	 * be used as verification hook target
94
94
	 */
95
	public void processEvent(Event e)
95
	private boolean extendedScope = false;
96
	{
96
97
	}
97
	/**
98
98
	 * The constructor
99
	/**
99
	 * 
100
	 * A chance to build the meta-data of this verification command
100
	 * @param metaData
101
	 */
101
	 *            The meta data that this verification command uses to write or
102
	public void load(Node node, Hashtable lineTable) 
102
	 *            play back itself.
103
	{
103
	 */
104
		/* Bind the source location */
104
	public VerificationCommand(MacroCommandShell parent) {
105
		super.bindSourceLocation(node, lineTable);
105
		super(parent);
106
		
106
	}
107
		/* Construct the meta data here */
107
108
		VerificationMetaData metaData = getMetaData();
108
	public String getType() {
109
		
109
		return TYPE;
110
		String contextId = MacroUtil.getAttribute(node, "contextId");
110
	}
111
		metaData.setContextId(contextId);
111
112
		metaData.setFocusType(MacroUtil.findFocusType(contextId));
112
	/**
113
		metaData.setLocation(MacroUtil.getAttribute(node, "location"));
113
	 * {@inheritDoc}
114
		metaData.setResource(MacroUtil.getAttribute(node, "resource"));
114
	 * 
115
		metaData.setHook(MacroUtil.getAttribute(node, "hook"));
115
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand#processEvent(org.eclipse.swt.widgets.Event)
116
	}
116
	 */
117
	
117
	public void doProcessEvent(Event event) {
118
	
118
		focusType = findFocusType(getMacroObjectIdentifier()
119
	/**
119
				.getContextIdentifier());
120
	 * Invoked when this writable object is ready to be written to
120
		contextClass = findContextClass(getMacroObjectIdentifier()
121
	 * a print writer.
121
				.getContextIdentifier());
122
	 */
122
		widgetClass = macroObject.getUIObject().getWidget().getClass();
123
	public void write(int indent, StringBuffer sb)
123
		if (macroObject.getUIObject().getObject() != null) {
124
	{
124
			objectClass = macroObject.getUIObject().getObject().getClass();
125
		if (!metaData.isComplete())
125
		}
126
			return;
126
	}
127
		
127
128
		/* If the default package is selected for a verification hook class, 
128
	/**
129
		 * it is often prefixed with a '.'  This needs to be taken out before
129
	 * A chance to build the meta-data of this verification command
130
		 * written as part of the macro
130
	 */
131
		 */
131
	public void load(Node node, Hashtable lineTable) throws CoreException {
132
		String resource = metaData.getResource();
132
		super.load(node, lineTable);
133
		if (resource != null && resource.length() > 0 && resource.charAt(0) == '.')
133
134
			resource = resource.substring(1);
134
		// String contextId = MacroUtil.getAttribute(node,
135
		
135
		// "contextId");
136
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false);
136
		focusType = findFocusType(getMacroObjectIdentifier()
137
		MacroUtil.addAttribute(sb, 
137
				.getContextIdentifier());
138
				new String[] {MacroConstants.TYPE_ATTRIBUTE,
138
		contextClass = findContextClass(getMacroObjectIdentifier()
139
							  MacroConstants.CONTEXT_ID_ATTRIBUTE,
139
				.getContextIdentifier());
140
							  MacroConstants.LOCATION_ATTRIBUTE,
140
		location = MacroUtil.getAttribute(node, "location");
141
							  MacroConstants.RESOURCE_ATTRIBUTE,
141
		resource = MacroUtil.getAttribute(node, "resource");
142
							  MacroConstants.HOOK_ATTRIBUTE},
142
		hook = MacroUtil.getAttribute(node, "hook");
143
				new String[] {getType(),
143
		// if the hook has more than one parameter, we are in extended scope
144
							  metaData.getContextId(),
144
		// mode
145
							  metaData.getLocation(),
145
		setExtendedScope(hook.indexOf(';') != hook.lastIndexOf(";"));
146
							  resource,
146
		// if we are in extended mode, we have to load the object class.
147
							  metaData.getHook()}, true, true);		
147
		if (isExtendedScope()) {
148
	}
148
			widgetClass = findWidgetClass(hook);
149
149
			objectClass = findObjectClass(hook);
150
	
150
		}
151
	/**
151
	}
152
	 * This doesn't involve any UI actions.  Playing back the verification command will
152
153
	 * simply run the verification hook.
153
	/**
154
	 * @throws CoreException 
154
	 * {@inheritDoc}
155
	 */
155
	 * 
156
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
156
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#loadMacroObjectIdentifier(org.w3c.dom.Node,
157
	{
157
	 *      java.util.Hashtable)
158
		/* Phases:
158
	 */
159
		 * 	1. Load the necessary class
159
	protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable)
160
		 * 	2. Do the method look up on the hook entry
160
			throws CoreException {
161
		 * 	3. If valid:
161
		// let the super implementation try (in case we are in extended mode,
162
		 * 		4. Load its context (i.e. View/Editor/etc...)
162
		// this should build a valid descriptor)
163
		 * 		5. Invoke the hook with the context  		
163
		super.loadMacroObjectIdentifier(node, lineTable);
164
		 */
164
165
			
165
		// if we are not in extended mode, just set the context id
166
		String classPath = System.getProperty("java.class.path");
166
		if (getMacroObjectIdentifier() == null) {
167
		try
167
			String cid = MacroUtil.getAttribute(node,
168
		{			
168
					MacroConstants.CONTEXT_ID_ATTRIBUTE);
169
			Vector reqPlugins = null;
169
			setMacroObjectIdentifier(new MacroObjectIdentifier(cid, null));
170
						
170
		}
171
			
171
	}
172
			/* If we happen to run in the quick run mode, then we need to explicitly modify the
172
173
			 * class path ourself. */
173
	/**
174
			if (MacroManager.getInstance().getGlobalState() == MacroManager.QUICK_RUN_MODE)
174
	 * {@inheritDoc}
175
			{
175
	 * 
176
				/* The project is expected to be a java project */
176
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#writeMacroObjectIdentifier(int,
177
				IJavaProject javaProject = AutoGUIUtil.findJavaProject(metaData.getLocation());
177
	 *      java.lang.StringBuffer, boolean, boolean)
178
178
	 */
179
				/* We need to add the output folder of all the java projects in our workspace to the classpath */
179
	protected void writeMacroObjectIdentifier(int indent, StringBuffer sb,
180
				classPath += AutoGUIUtil.appendWSProjOutputFolder(classPath);
180
			boolean close, boolean end) {
181
				
181
		if (isExtendedScope()) {
182
				if (javaProject != null && javaProject.exists())
182
			// write the normal triple (contextID, objectID, resolverID)
183
				{					
183
			super.writeMacroObjectIdentifier(indent, sb, close, end);
184
					/* Add the classpath entries of the project */										
184
		} else {
185
					reqPlugins = new Vector(5);					
185
			// only write the context id
186
					classPath += AutoGUIUtil.findDependencies (javaProject, reqPlugins, true);
186
			MacroUtil.addAttribute(sb,
187
				}
187
					new String[] { MacroConstants.CONTEXT_ID_ATTRIBUTE },
188
			}
188
					new String[] { getMacroObjectIdentifier()
189
			
189
							.getContextIdentifier() }, close, end);
190
			/* Otherwise we're running in execution mode.  We'll still need to resolve the dependencies of the plugin
190
		}
191
			 * containing the test suite.  If any exists, then it would have been registerd with the MacroManager. */
191
	}
192
			else
192
193
			{
193
	/**
194
				reqPlugins = MacroManager.getInstance().getDependecies();
194
	 * Invoked when this writable object is ready to be written to a print
195
			}
195
	 * writer.
196
			
196
	 */
197
			StringTokenizer st = new StringTokenizer (classPath, File.pathSeparator);
197
	public void write(int indent, StringBuffer sb) {
198
			Vector urlsVec = new Vector(10);
198
		// let the super implementation write the element, we will just add our
199
			
199
		// attributes
200
			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=136157 */
200
		super.write(indent, sb);
201
			final String PREFIX = "file:";
201
		/*
202
			
202
		 * If the default package is selected for a verification hook class, it
203
			while (st.hasMoreTokens())
203
		 * is often prefixed with a '.' This needs to be taken out before
204
			{
204
		 * written as part of the macro
205
				String curURL = st.nextToken();
205
		 */
206
				
206
		if (resource != null && resource.length() > 0
207
				/* The URL class loader will require all directories to end with a forward slash */
207
				&& resource.charAt(0) == '.')
208
				if (!curURL.endsWith(".jar") && !curURL.endsWith("/"))
208
			resource = resource.substring(1);
209
					curURL += "/";								
209
210
				
210
		MacroUtil.addAttribute(sb, new String[] {
211
				urlsVec.add(new URL(PREFIX + curURL));
211
		/*
212
			}
212
		 * MacroConstants.TYPE_ATTRIBUTE, MacroConstants.CONTEXT_ID_ATTRIBUTE,
213
			
213
		 */
214
			/* Construct the urls */
214
		MacroConstants.LOCATION_ATTRIBUTE, MacroConstants.RESOURCE_ATTRIBUTE,
215
			URL[] urls = new URL[urlsVec.size()];
215
				MacroConstants.HOOK_ATTRIBUTE }, new String[] {/*
216
			for (int i = 0; i < urls.length; i++)
216
																 * getType(),
217
			{
217
																 * metaData.getContextId(),
218
				urls[i] = (URL) urlsVec.get(i);
218
																 */
219
			}
219
		location, resource, hook }, true, true);
220
		
220
221
			
221
	}
222
			ClassLoader customClassLoader = new VerifHookClassLoader (urls, this.getClass().getClassLoader(), reqPlugins);
222
223
			Class verifyHookClass = Class.forName(metaData.getResource(), true, customClassLoader);
223
	/**
224
224
	 * {@inheritDoc}
225
			Object[] args = new Object[1];
225
	 * 
226
			String contextId = new Path(metaData.getContextId()).segment(1);
226
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand#useObjectMine()
227
			
227
	 */
228
			if (metaData.getFocusType() == VerificationMetaData.VIEW)
228
	protected boolean useObjectMine() {
229
			{
229
		// verification commands do never use the object mine (why?)
230
				IViewPart view = MacroObjectLocator.locateView(display.getActiveShell(), contextId, getStartLine());
230
		return false;
231
				args[0] = view;
231
	}
232
			}
232
233
			else if (metaData.getFocusType() == VerificationMetaData.EDITOR)
233
	private Class findWidgetClass(String hook) {
234
			{
234
		// parse the hook signature to retrieve the class name of the widget
235
				IEditorPart editor = MacroObjectLocator.locateEditor(display.getActiveShell(), contextId, getStartLine(), null);
235
		// class
236
				args[0] = editor;
236
		String className = hook.substring(hook.indexOf(";Q") + 2, hook.indexOf(
237
			}
237
				";", hook.indexOf(";Q") + 2));
238
			else if (metaData.getFocusType() == VerificationMetaData.SHELL)
238
		try {
239
			{
239
			return loadClass(className);
240
				Shell shell = getParent().getShell();
240
		} catch (Exception e) {
241
				args[0] = shell;
241
			return null;
242
			}
242
		}
243
			
243
	}
244
			/* Construct the test case */
244
245
			HyadesTestSuite testSuite = new HyadesTestSuite();
245
	private Class findObjectClass(String hook) {
246
			Constructor constructor = verifyHookClass.getConstructor(new Class[] {String.class, Class[].class, Object[].class});
246
		// see if we have also an object parameter
247
			
247
		String className = hook.substring(hook.indexOf(";Q",
248
			String testMethodName = MacroUtil.findMethodName(metaData);
248
				hook.indexOf(";Q") + 2) + 2, hook.lastIndexOf(";"));
249
			Class[] testMethodParams = MacroUtil.findParameterType(metaData);
249
		try {
250
			AutoGUIVerificationHook verificationHook = (AutoGUIVerificationHook) constructor.newInstance(new Object[] {testMethodName,testMethodParams , args});
250
			return loadClass(className);
251
			verificationHook.setTestInvocationId("invocation-id-" + System.currentTimeMillis());
251
		} catch (Exception e) {
252
			testSuite.addTest(verificationHook);
252
			return null;
253
			
253
		}
254
			/* If we are running in quick mode, then report verification test methods that are missing */
254
	}
255
			if (MacroManager.getInstance().getGlobalState() == MacroManager.QUICK_RUN_MODE)
255
256
			{
256
	private Class loadClass(String className) throws MalformedURLException,
257
				try
257
			CoreException, ClassNotFoundException {
258
				{
258
		String classPath = System.getProperty("java.class.path");
259
					verificationHook.getClass().getMethod(testMethodName, testMethodParams);
259
		Vector reqPlugins = null;
260
				}
260
261
				catch (NoSuchMethodException e)
261
		/*
262
				{
262
		 * If we happen to run in the quick run mode, then we need to explicitly
263
					AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF_T,
263
		 * modify the class path ourself.
264
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF, new String[] {testMethodName, String.valueOf(getStartLine())}),
264
		 */
265
											MessageDialog.WARNING);
265
		if (MacroManager.getInstance().getGlobalState() == ModeConstants.QUICK_RUN_MODE) {
266
				}
266
			/* The project is expected to be a java project */
267
			}
267
			IJavaProject javaProject = AutoGUIUtil.findJavaProject(location);
268
			MacroManager.getInstance().getRunner().runVerificaitonHook(testSuite);
268
269
			
269
			/*
270
			return true;
270
			 * We need to add the output folder of all the java projects in our
271
			
271
			 * workspace to the classpath
272
		}
272
			 */
273
		catch (ClassNotFoundException e)
273
			classPath += AutoGUIUtil.appendWSProjOutputFolder(classPath);
274
		{
274
275
			/* The class was not found.  The classpath should have been set by the deployment adapter 
275
			if (javaProject != null && javaProject.exists()) {
276
			 * (JavaExecutionDeploymentAdapter) and the file should have been transferred to the
276
				/* Add the classpath entries of the project */
277
			 * system's temporary directory.  This is an internal error */			
277
				reqPlugins = new Vector(5);
278
			String[] args = {metaData.getResource(), metaData.getHook(), classPath};
278
				classPath += AutoGUIUtil.findDependencies(javaProject,
279
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_F, args), super.getStartLine(), e);
279
						reqPlugins, true);
280
		}
280
			}
281
		catch (InstantiationException e)
281
		}
282
		{
282
283
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_INSTANTIATE, metaData.getResource()), super.getStartLine(), e);
283
		/*
284
		}
284
		 * Otherwise we're running in execution mode. We'll still need to
285
		catch (CoreException e)
285
		 * resolve the dependencies of the plugin containing the test suite. If
286
		{
286
		 * any exists, then it would have been registerd with the MacroManager.
287
			String[] args = {metaData.getContextId(), metaData.getHook()}; 
287
		 */
288
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CONTEXT, args), super.getStartLine());
288
		else {
289
		}
289
			reqPlugins = MacroManager.getInstance().getDependecies();
290
		catch (IllegalArgumentException e)
290
		}
291
		{
291
292
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_VER_ARG_EXCEPT, super.getStartLine());
292
		StringTokenizer st = new StringTokenizer(classPath, File.pathSeparator);
293
		}
293
		Vector urlsVec = new Vector(10);
294
		catch (Exception e)
294
295
		{ 
295
		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=136157 */
296
			AutoGUIUtil.throwCoreException(AutoGUIUtil.getOriginOfException(e), super.getStartLine(), e);
296
		final String PREFIX = "file:";
297
		}
297
298
		
298
		while (st.hasMoreTokens()) {
299
		return false;
299
			String curURL = st.nextToken();
300
	}
300
301
301
			/*
302
302
			 * The URL class loader will require all directories to end with a
303
303
			 * forward slash
304
304
			 */
305
	/**
305
			if (!curURL.endsWith(".jar") && !curURL.endsWith("/"))
306
	 * Returns an instance of this class based an event.  The returned value is null
306
				curURL += "/";
307
	 * if an error occurs while constructing the instance.  Check the value returned
307
308
	 * by getError to determine the error that has occurred.
308
			urlsVec.add(new URL(PREFIX + curURL));
309
	 * 
309
		}
310
	 * @param event The event
310
311
	 * @return An instance of this class
311
		/* Construct the urls */
312
	 */
312
		URL[] urls = new URL[urlsVec.size()];
313
	public synchronized static VerificationCommand constructInstance (MacroCommandShell parent, Event event)
313
		for (int i = 0; i < urls.length; i++) {
314
	{
314
			urls[i] = (URL) urlsVec.get(i);
315
		VerificationCommand instance = null;
315
		}
316
		
316
317
		error = ""; 
317
		ClassLoader customClassLoader = new VerificationHookClassLoader(urls,
318
		if (MacroUtil.isIgnorableEvent(event))
318
				this.getClass().getClassLoader(), reqPlugins);
319
		{
319
		return Class.forName(className, true, customClassLoader);
320
			error = "";			/* We don't want to report anything */
320
	}
321
			return null;
321
322
		}
322
	/**
323
		
323
	 * This doesn't involve any UI actions. Playing back the verification
324
		try
324
	 * command will simply run the verification hook.
325
		{
325
	 * 
326
			/* Ignore all command except for a focus in command */
326
	 * @throws CoreException
327
			switch (event.type)
327
	 */
328
			{				
328
	public boolean playback(Display display, Shell parent,
329
				case SWT.Activate:
329
			IProgressMonitor monitor) throws CoreException {
330
				case SWT.Selection:
330
		/*
331
				case SWT.FocusIn:
331
		 * Phases: 1. Load the necessary class 2. Do the method look up on the
332
					
332
		 * hook entry 3. If valid: 4. Load its context (i.e. View/Editor/etc...)
333
					WidgetIdentifier widgetID = MacroUtil.getVerificationContextIdentifier(event);
333
		 * 5. Invoke the hook with the context
334
					String path = (widgetID == null ? "" : widgetID.getFullyQualifiedPath().toString());
334
		 */
335
					
335
		try {
336
					if (MacroUtil.findFocusType(path) == -1)
336
			Class verifyHookClass = loadClass(resource);
337
					{
337
338
						error = AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON;
338
			if (isExtendedScope()) {
339
						break;
339
				macroObject = MacroObjectResolver.deresolve(getParent()
340
					}
340
						.getShell(), getMacroObjectIdentifier());
341
										
341
			}
342
					/* We only acknowledge after there is a mouse up event */
342
343
					toBeAck = widgetID;
343
			Object[] args = isExtendedScope() ? (macroObject.getUIObject()
344
					break;
344
					.getObject() != null ? new Object[3] : new Object[2])
345
					
345
					: new Object[1];
346
				case SWT.MouseUp:					
346
			String contextId = new Path(getMacroObjectIdentifier()
347
347
					.getContextIdentifier()).segment(1);
348
					if (toBeAck == null)
348
349
						break;
349
			if (focusType == VIEW) {
350
					
350
				IViewPart view = MacroUtil.locateView(display.getActiveShell(),
351
					/* Build the verification meta data -- we only know the context id and the focus type at this point */
351
						contextId);
352
					VerificationMetaData metaData = new VerificationMetaData();
352
				args[0] = view;
353
					String contextId = toBeAck.getContextId().toString();
353
			} else if (focusType == EDITOR) {
354
					metaData.setContextId(contextId);
354
				IEditorPart editor = MacroUtil.locateEditor(display
355
					metaData.setFocusType(MacroUtil.findFocusType(contextId));
355
						.getActiveShell(), contextId, null);
356
					
356
				args[0] = editor;
357
					/* Create the verification command instance */
357
			} else if (focusType == SHELL) {
358
					instance = new VerificationCommand (parent, metaData);
358
				Shell shell = getParent().getShell();
359
					break;
359
				args[0] = shell;
360
					
360
			}
361
				default:
361
362
					toBeAck = null;
362
			if (isExtendedScope()) {
363
					error = AutoGUIMessages.AUTO_GUI_ERROR_VER_WRONG_EVENT;
363
				args[1] = macroObject.getUIObject().getWidget();
364
			}
364
				if (macroObject.getUIObject().getObject() != null) {
365
			
365
					args[2] = macroObject.getUIObject().getObject();
366
			return instance;
366
				}
367
		} 
367
			}
368
		catch (Exception e)
368
369
		{
369
			/* Construct the test case */
370
			error = e.getMessage();
370
			HyadesTestSuite testSuite = new HyadesTestSuite();
371
			e.printStackTrace();
371
			Constructor constructor = verifyHookClass
372
			return null;
372
					.getConstructor(new Class[] { String.class, Class[].class,
373
		}
373
							Object[].class });
374
	}
374
375
375
			String testMethodName = findMethodName(hook);
376
	
376
377
	public static String getError()
377
			Class[] testMethodParams = isExtendedScope() ? (macroObject
378
	{
378
					.getUIObject().getObject() != null ? new Class[] {
379
		return error;
379
					getContextClass(), getWidgetClass(), getObjectClass() }
380
	}
380
					: new Class[] { getContextClass(), getWidgetClass() })
381
381
					: new Class[] { getContextClass() };
382
	public static void setError(String error)
382
			AutoGUIVerificationHook verificationHook = (AutoGUIVerificationHook) constructor
383
	{
383
					.newInstance(new Object[] { testMethodName,
384
		VerificationCommand.error = error;
384
							testMethodParams, args });
385
	}
385
			verificationHook.setTestInvocationId("invocation-id-"
386
386
					+ System.currentTimeMillis());
387
	public VerificationMetaData getMetaData()
387
			testSuite.addTest(verificationHook);
388
	{
388
389
		return metaData;
389
			/*
390
	}
390
			 * If we are running in quick mode, then report verification test
391
391
			 * methods that are missing
392
	public void setMetaData(VerificationMetaData metaData)
392
			 */
393
	{
393
			if (MacroManager.getInstance().getGlobalState() == ModeConstants.QUICK_RUN_MODE) {
394
		this.metaData = metaData;
394
				try {
395
	}
395
					verificationHook.getClass().getMethod(testMethodName,
396
	
396
							testMethodParams);
397
}
397
				} catch (NoSuchMethodException e) {
398
398
					AutoGUIUtil
399
							.showMessage(
400
									AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF_T,
401
									NLS
402
											.bind(
403
													AutoGUIMessages.AUTO_GUI_ERROR_VER_METHOD_NF,
404
													new String[] {
405
															testMethodName,
406
															String
407
																	.valueOf(getStartLine()) }),
408
									MessageDialog.WARNING);
409
				}
410
			}
411
			MacroManager.getInstance().getRunner().runVerificationHook(
412
					testSuite);
413
414
			return true;
415
416
		} catch (ClassNotFoundException e) {
417
			e.printStackTrace();
418
			/*
419
			 * The class was not found. The classpath should have been set by
420
			 * the deployment adapter (JavaExecutionDeploymentAdapter) and the
421
			 * file should have been transferred to the system's temporary
422
			 * directory. This is an internal error
423
			 */
424
			String[] args = { resource, hook };
425
			AutoGUIUtil.throwCoreException(NLS.bind(
426
					AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_F, args),
427
					super.getStartLine(), e);			
428
		} catch (CoreException e) {
429
			e.printStackTrace();
430
			String[] args = {
431
					getMacroObjectIdentifier().getContextIdentifier(), hook };
432
			AutoGUIUtil.throwCoreException(NLS.bind(
433
					AutoGUIMessages.AUTO_GUI_ERROR_VER_CONTEXT, args), super
434
					.getStartLine());
435
		} catch (InstantiationException e) {
436
			e.printStackTrace();
437
			AutoGUIUtil.throwCoreException(NLS.bind(
438
					AutoGUIMessages.AUTO_GUI_ERROR_VER_INSTANTIATE, resource),
439
					super.getStartLine(), e);
440
		} catch (IllegalArgumentException e) {
441
			e.printStackTrace();
442
			AutoGUIUtil.throwCoreException(
443
					AutoGUIMessages.AUTO_GUI_ERROR_VER_ARG_EXCEPT, super
444
							.getStartLine());
445
		} catch (Exception e) {
446
			e.printStackTrace();
447
			AutoGUIUtil.throwCoreException(AutoGUIUtil.getOriginOfException(e),
448
					super.getStartLine(), e);
449
		}
450
451
		return false;
452
	}
453
454
	/**
455
	 * Given a context id, return the focus type.
456
	 * 
457
	 * @param contextId
458
	 *            The id of the context
459
	 * @return The type of the context (i.e. focus type). -1 is returned if the
460
	 *         focus type is not recognized.
461
	 */
462
	public static byte findFocusType(String contextId) {
463
		if (contextId.startsWith(MacroConstants.VIEW_VALUE + "/"))
464
			return VIEW;
465
		else if (contextId.startsWith(MacroConstants.EDITOR_VALUE + "/"))
466
			return EDITOR;
467
		else if (contextId.startsWith(MacroConstants.SHELL_VALUE + "/"))
468
			return SHELL;
469
470
		return -1;
471
	}
472
473
	/**
474
	 * Find the method name corresponding the verification hook
475
	 * 
476
	 * @param metaData
477
	 * @return
478
	 */
479
	public static String findMethodName(String hook) {
480
		String methodName = hook;
481
482
		if (methodName == null || methodName.length() <= 0)
483
			return null;
484
485
		int index = methodName.indexOf(':');
486
		if (index != -1)
487
			return methodName.substring(0, index);
488
489
		return methodName;
490
	}
491
492
	/**
493
	 * Find the parameter types of the verificaiton hook
494
	 * 
495
	 * @param metaData
496
	 * @return
497
	 */
498
	private Class findContextClass(String contextId) {
499
		Class param = null;
500
		byte focusType = findFocusType(contextId);
501
		if (focusType == EDITOR)
502
			param = IEditorPart.class;
503
		else if (focusType == VIEW)
504
			param = IViewPart.class;
505
		else if (focusType == SHELL)
506
			param = Shell.class;
507
508
		return param;
509
	}
510
511
	/**
512
	 * Return the class name containing the verification point that this meta
513
	 * data points to.
514
	 * 
515
	 * @param metaData
516
	 *            The verification point's meta data
517
	 * @return The class name. null is returned if it can't be determined
518
	 */
519
	public static String getClassName(String resource) {
520
		String className = resource;
521
522
		if (className == null || className.length() <= 0)
523
			return null;
524
525
		int index = className.lastIndexOf('.');
526
		if (index != -1)
527
			return className.substring(index + 1, className.length());
528
		return className;
529
	}
530
531
	public void setLocation(String location) {
532
		this.location = location;
533
	}
534
535
	public void setResource(String resource) {
536
		this.resource = resource;
537
	}
538
539
	public void setHook(String hook) {
540
		this.hook = hook;
541
	}
542
543
	public Class getObjectClass() {
544
		return objectClass;
545
	}
546
547
	public Class getWidgetClass() {
548
		return widgetClass;
549
	}
550
551
	public Class getContextClass() {
552
		return contextClass;
553
	}
554
555
	public String getLocation() {
556
		return location;
557
	}
558
559
	public String getResource() {
560
		return resource;
561
	}
562
563
	public String getHook() {
564
		return hook;
565
	}
566
567
	public boolean isExtendedScope() {
568
		return extendedScope;
569
	}
570
571
	public void setExtendedScope(boolean extendedScope) {
572
		this.extendedScope = extendedScope;
573
	}
574
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/WaitCommand.java (-277 / +257 lines)
Lines 1-278 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
15
16
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.Platform;
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
19
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
20
import org.eclipse.core.runtime.jobs.IJobManager;
20
import org.eclipse.core.runtime.jobs.IJobManager;
21
import org.eclipse.core.runtime.jobs.Job;
21
import org.eclipse.core.runtime.jobs.Job;
22
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
22
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
23
import org.eclipse.swt.widgets.Composite;
23
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.swt.widgets.Event;
25
import org.eclipse.swt.widgets.Event;
25
import org.eclipse.swt.widgets.Shell;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
27
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
27
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.w3c.dom.Node;
30
import org.w3c.dom.Node;
31
31
32
/**
32
/**
33
 * <p>
33
 * <p>
34
 * The purpose of this command is to provide a waiting mechanism so as to avoid
34
 * The purpose of this command is to provide a waiting mechanism so as to avoid
35
 * racing conditions that may cause a test case to fail when the underlying functionality
35
 * racing conditions that may cause a test case to fail when the underlying
36
 * works as expected.
36
 * functionality works as expected.
37
 * </p>
37
 * </p>
38
 * 
38
 * 
39
 * <p>
39
 * <p>
40
 * The command has a dual behaviour depending on whether the waitTime field is set or not.  If
40
 * The command has a dual behaviour depending on whether the waitTime field is
41
 * this field is set, then this command will cause the caller thread to wait 'waitTime' milliseconds.  
41
 * set or not. If this field is set, then this command will cause the caller
42
 * If the field is not set, then the command will cause the caller thread to wait until all 
42
 * thread to wait 'waitTime' milliseconds. If the field is not set, then the
43
 * non-system Eclipse jobs are completed.
43
 * command will cause the caller thread to wait until all non-system Eclipse
44
 * </p>  
44
 * jobs are completed.
45
 */
45
 * </p>
46
public class WaitCommand extends AbstractMacroCommand
46
 */
47
{
47
public class WaitCommand extends AbstractMacroCommand {
48
	public static final String TYPE = "wait";	
48
49
49
	public static final String TYPE = IMacroCommand.WAIT;
50
	/* The amount of waiting time.  If this field is set, then this command behaves differently */
50
51
	private long waitTime;
51
	/*
52
	
52
	 * The amount of waiting time. If this field is set, then this command
53
	private static class JobListener extends JobChangeAdapter
53
	 * behaves differently
54
	{
54
	 */
55
		private int counter = 0;
55
	private long waitTime;
56
56
57
		private IProgressMonitor monitor;
57
	private static class JobListener extends JobChangeAdapter {
58
58
59
		private Thread t;
59
		private int counter = 0;
60
60
61
		public JobListener(IProgressMonitor monitor, Thread t, int number)
61
		private IProgressMonitor monitor;
62
		{
62
63
			this.counter = number;
63
		private Thread t;
64
			this.monitor = monitor;
64
65
			this.t = t;
65
		public JobListener(IProgressMonitor monitor, Thread t, int number) {
66
		}
66
			this.counter = number;
67
67
			this.monitor = monitor;
68
		private synchronized void change(int increment)
68
			this.t = t;
69
		{
69
		}
70
			this.counter += increment;
70
71
			if (counter == 0)
71
		private synchronized void change(int increment) {
72
			{
72
			this.counter += increment;
73
				monitor.subTask("");
73
			if (counter == 0) {
74
				synchronized (t)
74
				monitor.subTask("");
75
				{
75
				synchronized (t) {
76
					t.interrupt();
76
					t.interrupt();
77
				}
77
				}
78
			}
78
			}
79
		}
79
		}
80
80
81
		public void running(IJobChangeEvent event)
81
		public void running(IJobChangeEvent event) {
82
		{
82
			Job job = event.getJob();
83
			Job job = event.getJob();
83
			if (!job.isSystem())
84
			if (!job.isSystem())
84
				change(1);
85
				change(1);
85
		}
86
		}
86
87
87
		public void done(IJobChangeEvent event) {
88
		public void done(IJobChangeEvent event)
88
			Job job = event.getJob();
89
		{
89
			if (!job.isSystem())
90
			Job job = event.getJob();
90
				change(-1);
91
			if (!job.isSystem())
91
		}
92
				change(-1);
92
	}
93
		}
93
94
	}
94
	/**
95
95
	 * A chance to build the meta-data of this verification command
96
96
	 */
97
	/**
97
	public void load(Node node, Hashtable lineTable) throws CoreException {
98
	 * A chance to build the meta-data of this verification command
98
		super.load(node, lineTable);
99
	 */
99
100
	public void load(Node node, Hashtable lineTable) throws CoreException 
100
		String waitTime = MacroUtil.getAttribute(node,
101
	{
101
				MacroConstants.TIME_TO_WAIT_ATTRIBUTE);
102
		super.load(node, lineTable);
102
103
				
103
		if (waitTime != null && waitTime.length() > 0) {
104
		String waitTime = MacroUtil.getAttribute(node, MacroConstants.TIME_TO_WAIT_ATTRIBUTE);
104
			try {
105
		
105
				long timeToWait = Long.parseLong(waitTime);
106
		if (waitTime != null && waitTime.length() > 0)
106
				if (timeToWait > 0)
107
		{
107
					this.waitTime = timeToWait;
108
			try
108
			} catch (NumberFormatException nfe) {
109
			{
109
				nfe.printStackTrace();
110
				long timeToWait = Long.parseLong(waitTime);
110
			}
111
				if (timeToWait > 0)
111
		}
112
					this.waitTime = timeToWait;
112
	}
113
			}
113
114
			catch (NumberFormatException nfe)
114
	public WaitCommand(MacroCommandShell parent) {
115
			{
115
		super(parent);
116
				nfe.printStackTrace();
116
	}
117
			}
117
118
		}
118
	/*
119
	}
119
	 * (non-Javadoc)
120
	
120
	 * 
121
121
	 * @see org.eclipse.ui.macro.MacroCommand#getType()
122
	public WaitCommand(MacroCommandShell parent)
122
	 */
123
	{
123
	public String getType() {
124
		super(parent, WidgetIdentifier.NULL_IDENTIFIER);
124
		return TYPE;
125
	}
125
	}
126
126
127
	/*
127
	/*
128
	 * (non-Javadoc)
128
	 * (non-Javadoc)
129
	 * 
129
	 * 
130
	 * @see org.eclipse.ui.macro.MacroCommand#getType()
130
	 * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event)
131
	 */
131
	 */
132
	public String getType()
132
	public void processEvent(Event e) {
133
	{
133
	}
134
		return TYPE;
134
135
	}
135
	/*
136
136
	 * (non-Javadoc)
137
	/*
137
	 * 
138
	 * (non-Javadoc)
138
	 * @see org.eclipse.ui.macro.IWritable#write(java.lang.String,
139
	 * 
139
	 *      java.io.PrintWriter)
140
	 * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event)
140
	 */
141
	 */
141
	public void write(int indent, StringBuffer sb) {
142
	public void processEvent(Event e)
142
		/*
143
	{
143
		 * Don't print out this wait command if it happens to be the last
144
	}
144
		 * command in the macro shell OR the next command following it is a
145
145
		 * macro command shell
146
	/*
146
		 */
147
	 * (non-Javadoc)
147
		ArrayList commands = getParent().getCommands();
148
	 * 
148
		int commandSize = commands.size();
149
	 * @see org.eclipse.ui.macro.IWritable#write(java.lang.String,
149
		if ((commandSize > 0 && this == commands.get(commandSize - 1))
150
	 *      java.io.PrintWriter)
150
				|| isNextCommandShell(commands))
151
	 */
151
			return;
152
	public void write(int indent, StringBuffer sb)
152
153
	{		
153
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false,
154
		/* Don't print out this wait command if it happens to be the last command in the macro shell OR
154
				false);
155
		 * the next command following it is a macro command shell */
155
		MacroUtil.addAttribute(sb, new String[] {
156
		ArrayList commands = getParent().getCommands();
156
				MacroConstants.DESCRIPTIVE_ATTRIBUTE,
157
		int commandSize = commands.size();
157
				MacroConstants.TYPE_ATTRIBUTE,
158
		if ((commandSize > 0 && this == commands.get(commandSize - 1)) || isNextCommandShell(commands))
158
				MacroConstants.TIME_TO_WAIT_ATTRIBUTE }, new String[] {
159
			return;
159
				MacroUtil.boundSize(getDescriptiveField(),
160
		
160
						AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND),
161
		
161
				getType(), waitTime > 0 ? String.valueOf(waitTime) : null },
162
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false);
162
				true, true);
163
		MacroUtil.addAttribute(sb, 
163
	}
164
				new String[] {MacroConstants.DESCRIPTIVE_ATTRIBUTE,
164
165
							  MacroConstants.TYPE_ATTRIBUTE,
165
	private boolean isNextCommandShell(ArrayList commands) {
166
							  MacroConstants.TIME_TO_WAIT_ATTRIBUTE}, 
166
		int index = -1;
167
				new String[] {MacroUtil.boundSize(getDescriptiveField(), AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND),
167
168
							  getType(),
168
		int commandCount = commands.size();
169
							  waitTime > 0 ? String.valueOf(waitTime) : null}, true, true);		
169
		for (int i = 0; i < commandCount; i++) {
170
	}
170
			if (this == commands.get(i)) {
171
171
				index = i;
172
	private boolean isNextCommandShell(ArrayList commands) 
172
				break;
173
	{
173
			}
174
		int index = -1;
174
		}
175
		
175
176
		int commandCount = commands.size();
176
		if (index + 1 < commandCount)
177
		for (int i = 0; i < commandCount; i++) 
177
			return commands.get(index + 1) instanceof MacroCommandShell;
178
		{
178
		return false;
179
			if (this == commands.get(i))
179
	}
180
			{
180
181
				index = i;
181
	/*
182
				break;
182
	 * (non-Javadoc)
183
			}			
183
	 * 
184
		}
184
	 * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite)
185
		
185
	 */
186
		if (index + 1 < commandCount)
186
	public boolean playback(Display display, Shell parent,
187
			return commands.get(index + 1) instanceof MacroCommandShell;
187
			IProgressMonitor monitor) throws CoreException {
188
		return false;
188
189
	}
189
		if (waitTime > 0) {
190
190
			try {
191
191
				Thread.sleep(waitTime);
192
	/*
192
			} catch (InterruptedException e) {
193
	 * (non-Javadoc)
193
				/* Doesn't need to be handled */
194
	 * 
194
			}
195
	 * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite)
195
			return true;
196
	 */
196
		}
197
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
197
198
	{
198
		IJobManager jobManager = Platform.getJobManager();
199
		
199
		int nrunning = getNumberOfRunningJobs(jobManager);
200
		if (waitTime > 0)
200
		if (nrunning == 0) {
201
		{
201
			return true;
202
			try
202
		}
203
			{
203
		String message = AutoGUIMessages.AUTO_GUI_MACRO_WAITING;
204
				Thread.sleep(waitTime);
204
		JobListener listener = new JobListener(monitor, Thread.currentThread(),
205
			}
205
				nrunning);
206
			catch (InterruptedException e)
206
		jobManager.addJobChangeListener(listener);
207
			{
207
		monitor.subTask(message);
208
				/* Doesn't need to be handled */
208
209
			}
209
		final long INCREMENT_WAIT = 2000;
210
			return true;
210
		final int MAX_INCREMENT_NUM = 5;
211
		}
211
		try {
212
		
212
			int counter = 0;
213
		
213
214
		IJobManager jobManager = Platform.getJobManager();
214
			/*
215
		int nrunning = getNumberOfRunningJobs(jobManager);
215
			 * Let's wait in increments of INCREMENT_WAIT milliseconds for a
216
		if (nrunning == 0)
216
			 * maximum of INCREMENT_WAIT * MAX_INCREMENT_NUM milliseconds
217
		{
217
			 */
218
			return true;
218
			while (counter < MAX_INCREMENT_NUM) {
219
		}
219
				Thread.sleep(INCREMENT_WAIT);
220
		String message = AutoGUIMessages.AUTO_GUI_MACRO_WAITING;
220
				if (getNumberOfRunningJobs(jobManager) == 0)
221
		JobListener listener = new JobListener(monitor, Thread.currentThread(), nrunning);
221
					break;
222
		jobManager.addJobChangeListener(listener);
222
				counter++;
223
		monitor.subTask(message);
223
			}
224
		
224
225
		final long INCREMENT_WAIT = 2000;
225
		} catch (InterruptedException e) {
226
		final int MAX_INCREMENT_NUM = 5;
226
		}
227
		try
227
		jobManager.removeJobChangeListener(listener);
228
		{
228
		return true;
229
			int counter = 0;
229
	}
230
			
230
231
			/* Let's wait in increments of INCREMENT_WAIT milliseconds for a maximum of INCREMENT_WAIT * MAX_INCREMENT_NUM  milliseconds*/
231
	private int getNumberOfRunningJobs(IJobManager manager) {
232
			while (counter < MAX_INCREMENT_NUM)
232
		int count = 0;
233
			{
233
		Job[] jobs = manager.find(null);
234
				Thread.sleep(INCREMENT_WAIT);						
234
		for (int i = 0; i < jobs.length; i++) {
235
				if (getNumberOfRunningJobs(jobManager) == 0)
235
			if (!jobs[i].isSystem() && jobs[i].getState() == Job.RUNNING)
236
					break;				
236
				count++;
237
				counter++;
237
		}
238
			}
238
		return count;
239
			
239
	}
240
		}
240
241
		catch (InterruptedException e)
241
	public void setWaitTime(long difference) {
242
		{
242
		this.waitTime = difference;
243
		}
243
	}
244
		jobManager.removeJobChangeListener(listener);
244
245
		return true;
245
	/**
246
	}
246
	 * Overwrite this method so that a custom descriptive field can be
247
247
	 * specified. The format of the descriptive field is "<WAIT_TIME> seconds"
248
	private int getNumberOfRunningJobs(IJobManager manager)
248
	 * 
249
	{
249
	 * @return The descriptive field.
250
		int count = 0;
250
	 */
251
		Job[] jobs = manager.find(null);
251
	public String getDescriptiveField() {
252
		for (int i = 0; i < jobs.length; i++)
252
		if (waitTime > 0)
253
		{
253
			return (((double) waitTime) / 1000.0) + " "
254
			if (!jobs[i].isSystem() && jobs[i].getState() == Job.RUNNING)
254
					+ AutoGUIMessages.TST_SUITE_AUTO_MACRO_SECONDS;
255
				count++;
255
256
		}
256
		return null;
257
		return count;
257
	}
258
	}
259
260
	public void setWaitTime(long difference) 
261
	{
262
		this.waitTime = difference;
263
	}
264
	
265
	/**
266
	 * Overwrite this method so that a custom descriptive field can be specified.
267
	 * The format of the descriptive field is "<WAIT_TIME> seconds"
268
	 * 
269
	 * @return The descriptive field.
270
	 */
271
	public String getDescriptiveField()
272
	{
273
		if (waitTime > 0)
274
			return (((double)waitTime) / 1000.0)  + " " + AutoGUIMessages.TST_SUITE_AUTO_MACRO_SECONDS;
275
		
276
		return null;
277
	}
278
}
258
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ViewCommandTarget.java (-34 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import org.eclipse.swt.widgets.Widget;
14
import org.eclipse.ui.IViewPart;
15
import org.eclipse.ui.IWorkbenchPage;
16
17
public class ViewCommandTarget extends CommandTarget {
18
	public ViewCommandTarget(Widget widget, IViewPart view) {
19
		super(widget, view);
20
	}
21
	
22
	public IViewPart getView() {
23
		return (IViewPart)getContext();
24
	}
25
26
	/* (non-Javadoc)
27
	 * @see org.eclipse.ui.macro.CommandTarget#ensureVisible()
28
	 */
29
	public void ensureVisible() {
30
		IViewPart view = getView();
31
		IWorkbenchPage page = view.getViewSite().getPage();
32
		page.activate(view);
33
	}
34
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/FocusCommand.java (-82 / +73 lines)
Lines 1-83 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import org.eclipse.core.runtime.CoreException;
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.core.runtime.IProgressMonitor;
14
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.swt.widgets.Composite;
15
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.swt.widgets.Event;
17
import org.eclipse.swt.widgets.Event;
17
import org.eclipse.swt.widgets.Shell;
18
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
18
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
19
20
20
public class FocusCommand extends ObjectBasedCommand {
21
public class FocusCommand extends AbstractMacroCommand
21
22
{
22
	public static final String TYPE = IMacroCommand.FOCUS;
23
	public static final String TYPE = "focus";
23
24
24
	public FocusCommand(MacroCommandShell parent) {
25
	public FocusCommand(MacroCommandShell parent, WidgetIdentifier wid)
25
		super(parent);
26
	{
26
	}
27
		super(parent, wid);
27
28
	}
28
	/**
29
29
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event)
30
	/**
30
	 */
31
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event)
31
	public boolean mergeEvent(Event e) throws Exception {
32
	 */
32
		/* we can directly merge repeated focus requests on the same widget */
33
	public boolean mergeEvent(Event e)
33
		return true;
34
	{
34
	}
35
		/* we can directly merge repeated focus requests on the same widget */
35
36
		return true;
36
	/**
37
	}
37
	 * @see org.eclipse.ui.macro.MacroCommand#getType()
38
38
	 */
39
	
39
	public String getType() {
40
	/** 
40
		return TYPE;
41
	 * @see org.eclipse.ui.macro.MacroCommand#getType()
41
	}
42
	 */
42
43
	public String getType()
43
	/**
44
	{
44
	 * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event)
45
		return TYPE;
45
	 */
46
	}
46
	public void doProcessEvent(Event e) {
47
47
		findDescriptiveField(e.widget);
48
	
48
	}
49
	/** 
49
50
	 * @see org.eclipse.ui.macro.MacroCommand#processEvent(org.eclipse.swt.widgets.Event)
50
	/**
51
	 */
51
	 * @see org.eclipse.ui.macro.IPersistable#write(java.lang.String,
52
	public void processEvent(Event e)
52
	 *      java.io.PrintWriter)
53
	{
53
	 */
54
		findDescriptiveField(e.widget);
54
	public void write(int indent, StringBuffer sb) {
55
	}
55
		/* Don't bother with the focus command if the id is invalid */
56
56
		if (getMacroObjectIdentifier() == null)
57
	
57
			return;
58
	/** 
58
59
	 * @see org.eclipse.ui.macro.IWritable#write(java.lang.String, java.io.PrintWriter)
59
		super.write(indent, sb, true, true);
60
	 */
60
	}
61
	public void write(int indent, StringBuffer sb)
61
62
	{
62
	/**
63
		/* Don't bother with the focus command if the id is invalid */
63
	 * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite)
64
		if (getWidgetId() == null)
64
	 */
65
			return;
65
	public boolean doPlayback(Display display, Shell parent,
66
66
			IProgressMonitor monitor) throws CoreException {
67
		super.write(indent, sb, true, true);
67
		if (parent.isDisposed())
68
	}
68
			return false;
69
69
		if (macroObject != null)
70
	
70
			setFocus(macroObject);
71
	/**
71
		return true;
72
	 * @see org.eclipse.ui.macro.IPlayable#playback(org.eclipse.swt.widgets.Composite)
72
	}
73
	 */
73
74
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
75
	{
76
		if (parent.isDisposed())
77
			return false;
78
		CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent,getWidgetId(), getStartLine());
79
		if (targets !=null && targets.length > 0)
80
			targets[0].setFocus();
81
		return true;
82
	}
83
}
74
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractStructuredCommand.java (-626 / +644 lines)
Lines 1-627 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
import java.util.Map;
15
import java.util.Map;
16
16
17
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.hyades.test.common.util.XMLUtil;
19
import org.eclipse.hyades.test.common.util.XMLUtil;
20
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.Display;
21
import org.eclipse.swt.widgets.Display;
21
import org.eclipse.swt.widgets.Event;
22
import org.eclipse.swt.widgets.Event;
22
import org.eclipse.swt.widgets.Item;
23
import org.eclipse.swt.widgets.Item;
23
import org.eclipse.swt.widgets.List;
24
import org.eclipse.swt.widgets.List;
24
import org.eclipse.swt.widgets.Shell;
25
import org.eclipse.swt.widgets.Table;
25
import org.eclipse.swt.widgets.Table;
26
import org.eclipse.swt.widgets.TableItem;
26
import org.eclipse.swt.widgets.TableItem;
27
import org.eclipse.swt.widgets.Tree;
27
import org.eclipse.swt.widgets.Tree;
28
import org.eclipse.swt.widgets.TreeItem;
28
import org.eclipse.swt.widgets.TreeItem;
29
import org.eclipse.swt.widgets.Widget;
29
import org.eclipse.swt.widgets.Widget;
30
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
30
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
31
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
31
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
32
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
32
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
33
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
33
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
34
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
34
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
35
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
35
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
36
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
36
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
37
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
38
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
39
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
40
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject;
41
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
42
import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId;
42
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver;
43
import org.w3c.dom.Node;
43
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport;
44
import org.w3c.dom.NodeList;
44
import org.w3c.dom.Node;
45
45
import org.w3c.dom.NodeList;
46
/**
46
47
 * An abstract structured command that other commands can optionally
47
/**
48
 * extend.
48
 * An abstract structured command that other commands can optionally extend.
49
 * 
49
 * 
50
 * @author Ali Mehregani
50
 * @author Ali Mehregani
51
 */
51
 * @author Alexander Nyssen
52
public abstract class AbstractStructuredCommand extends AbstractMacroCommand
52
 */
53
{
53
public abstract class AbstractStructuredCommand extends ObjectBasedCommand {
54
	/** 
54
55
	 * The items that are associated with the structured selection.  The list contains 
55
	/**
56
	 * Hashtable entries with the following content:
56
	 * The items that are associated with the structured selection. The list
57
	 * KEY = XML attribute of the item
57
	 * contains Hashtable entries with the following content: KEY = XML
58
	 * VALUE = The value of the attribute
58
	 * attribute of the item VALUE = The value of the attribute
59
	 */
59
	 */
60
	protected ArrayList items;
60
	protected ArrayList items;
61
	
61
62
	
62
	/**
63
	/**
63
	 * The constructor
64
	 * The constructor
64
	 * 
65
	 * 
65
	 * @param parent
66
	 * @param parent The parent macro command shell owning this command
66
	 *            The parent macro command shell owning this command
67
	 * @param wid The widget identifier
67
	 * @param wid
68
	 */
68
	 *            The widget identifier
69
	public AbstractStructuredCommand(MacroCommandShell parent, WidgetIdentifier wid)
69
	 */
70
	{
70
	public AbstractStructuredCommand(MacroCommandShell parent) {
71
		super(parent, wid);
71
		super(parent);
72
		items = new ArrayList();
72
		items = new ArrayList();
73
	}
73
	}
74
74
75
	/**
75
	/**
76
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event)
76
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#mergeEvent(org.eclipse.swt.widgets.Event)
77
	 */
77
	 */
78
	public boolean mergeEvent(Event e)
78
	public boolean mergeEvent(Event e) throws Exception {
79
	{
79
		items.clear();
80
		items.clear();
80
		doProcessEvent(e);
81
		processEvent(e);
81
		return true;
82
		return true;
82
	}
83
	}
83
84
84
	/**
85
	
85
	 * Returns the items that are embedded in the event passed in
86
	/**
86
	 * 
87
	 * Returns the items that are embedded in the event passed in
87
	 * @param event
88
	 * 
88
	 *            The event
89
	 * @param event The event
89
	 * @return The items of the event
90
	 * @return The items of the event
90
	 */
91
	 */
91
	protected Object[] getItemsForEvent(Event event) {
92
	protected Object[] getItemsForEvent(Event event)
92
		Widget item = null;
93
	{
93
		if (event.item != null)
94
		Widget item = null;
94
			item = event.item;
95
		if (event.item != null)
95
		else if (event.widget instanceof Item)
96
			item = event.item;
96
			item = event.widget;
97
		else if (event.widget instanceof Item)
97
		if (item != null)
98
			item = event.widget;
98
			return new Widget[] { item };
99
		if (item != null)
99
		return null;
100
			return new Widget[] { item };
100
	}
101
		return null;
101
102
	}
102
	/**
103
103
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#processEvent(org.eclipse.swt.widgets.Event)
104
	
104
	 */
105
	/**
105
	public void doProcessEvent(Event event) {
106
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#processEvent(org.eclipse.swt.widgets.Event)
106
		Object[] eventItems = getItemsForEvent(event);
107
	 */
107
		boolean isWidget = eventItems instanceof Widget[];
108
	public void processEvent(Event event)
108
		boolean isString = false;
109
	{
109
110
		Object[] eventItems = getItemsForEvent(event);
110
		if (!isWidget)
111
		boolean isWidget = eventItems instanceof Widget[];
111
			isString = eventItems instanceof String[];
112
		boolean isString = false;
112
113
		
113
		/*
114
		if (!isWidget)
114
		 * Populate the items instance variable according to the items of the
115
			isString = eventItems instanceof String[];
115
		 * event
116
116
		 */
117
117
		if (eventItems != null) {
118
		/* Populate the items instance variable according to the items of the event */		
118
			/* For every embedded item */
119
		if (eventItems != null)
119
			for (int i = 0; i < eventItems.length; i++) {
120
		{
120
				Map attributeValuePairs = null;
121
			/* For every embedded item */
121
122
			for (int i = 0; i < eventItems.length; i++)
122
				if (isWidget) {
123
			{
123
					attributeValuePairs = getItemAttributes((Widget) eventItems[i]);
124
				Map attributeValuePairs = null;
124
				} else if (isString) {
125
				
125
					attributeValuePairs = getItemAttributes(null,
126
				if (isWidget)
126
							new PrimitiveUIObjectIdentifier(
127
				{
127
									(String) eventItems[i]));
128
					attributeValuePairs = getItemAttributes((Widget)eventItems[i]);
128
				}
129
				}
129
130
				else if (isString)
130
				if (attributeValuePairs != null) {
131
				{
131
					items.add(attributeValuePairs);
132
					attributeValuePairs = getItemAttributes(null, new PrimitiveWidgetId((String)eventItems[i]));
132
				}
133
				}
133
			}
134
134
		}
135
				if (attributeValuePairs != null)
135
136
				{
136
		super.findDescriptiveField(eventItems);
137
					items.add(attributeValuePairs);
137
	}
138
				}
138
139
			}
139
	/**
140
		}
140
	 * Returns the item attributes that will be used to find and resolve the
141
		
141
	 * item that is associated with this structured command.
142
		super.findDescriptiveField(eventItems);
142
	 * 
143
	}
143
	 * @param item
144
144
	 *            The item
145
145
	 * @return A map indicating the item attributes and values; null if the item
146
	/**
146
	 *         can't be resolved.
147
	 * Returns the item attributes that will be used to find and resolve the item
147
	 */
148
	 * that is associated with this structured command.
148
	protected Map getItemAttributes(Widget item) {
149
	 * 
149
		IUIObjectIdentifier id = null;
150
	 * @param item The item
150
		try {
151
	 * @return A map indicating the item attributes and values; null if the item can't be resolved.
151
			id = UIObjectResolver.resolve(null, new UIObject(item));
152
	 */
152
		} catch (CoreException e) {
153
	protected Map getItemAttributes(Widget item)
153
			e.printStackTrace();
154
	{
154
		}
155
		MacroManager macroManager = MacroManager.getInstance();		
155
		if (id == null) {
156
		IWidgetId id = macroManager.resolveWidget(item, null, MacroUtil.newCounter());
156
			id = getDefaultItemAttributes(item);
157
		if (id == null)
157
		}
158
		{
158
159
			id = getDefaultItemAttributes(item);
159
		if (id != null) {
160
		}
160
			return getItemAttributes(item, id);
161
		
161
		}
162
		if (id != null)
162
163
		{			
163
		return null;
164
			return getItemAttributes(item, id);
164
	}
165
		}
165
166
				
166
	/**
167
		return null;
167
	 * Returns the item attributes that will be used to find and resolve the
168
	}
168
	 * item that is associated with this structured command.
169
	
169
	 * 
170
	
170
	 * @param item
171
	private IWidgetId getDefaultItemAttributes(Widget item)
171
	 *            The item
172
	{
172
	 * @param id
173
		Object data = item.getData();
173
	 *            The item id
174
		
174
	 * @return A map indicating the item attributes and values; null if the item
175
		String idStr = MacroConstants.EMPTY_STRING;
175
	 *         can't be resolved.
176
		if (data != null)
176
	 */
177
			idStr = data.getClass().getName();
177
	private Map getItemAttributes(Widget item, IUIObjectIdentifier id) {
178
		
178
		Hashtable attributeValuePair = new Hashtable();
179
		/* Append index to id if it's a table or a tree item */
179
		attributeValuePair.put(MacroConstants.WIDGET_ID_ATTRIBUTE, id);
180
		if (item instanceof TreeItem)
180
181
		{
181
		MacroObjectDescriptor uiObject = findItemInObjectMine(item, id);
182
			TreeItem treeItem = (TreeItem)item;
182
		if (uiObject != null) {
183
			idStr = idStr + findTreeItemInx(treeItem, MacroConstants.EMPTY_STRING);
183
			attributeValuePair.put(MacroConstants.REFERENCE_ID_ATTRIBUTE,
184
		}
184
					uiObject.getReferenceId());
185
		else if (item instanceof TableItem)
185
		}
186
		{
186
187
			TableItem tableItem = (TableItem)item;
187
		if (id.getResolverId() != null) {
188
			idStr = idStr + tableItem.getParent().indexOf(tableItem);
188
			attributeValuePair.put(MacroConstants.RESOLVER_ID_ATTRIBUTE, id
189
		}
189
					.getResolverId());
190
		if (idStr.length() > 0)
190
		}
191
			return new PrimitiveWidgetId(idStr);
191
		return attributeValuePair;
192
		
192
	}
193
		return null;
193
194
	}
194
	/**
195
195
	 * Attempts to find an item in the current object mine. If it's not found,
196
	/**
196
	 * then it is registered.
197
	 * Returns the item attributes that will be used to find and resolve the item
197
	 * 
198
	 * that is associated with this structured command.
198
	 * @param item
199
	 * 
199
	 *            The item
200
	 * @param item The item
200
	 * @param id
201
	 * @param id The item id
201
	 *            The item id
202
	 * @return A map indicating the item attributes and values; null if the item can't be resolved.
202
	 * @return The object or null if it cannot be found or registered.
203
	 */
203
	 */
204
	protected Map getItemAttributes(Widget item, IWidgetId id)
204
	private MacroObjectDescriptor findItemInObjectMine(Widget item,
205
	{
205
			IUIObjectIdentifier id) {
206
		Hashtable attributeValuePair = new Hashtable();
206
		if (useObjectMine()) {
207
		attributeValuePair.put(MacroConstants.PATH_ATTRIBUTE, id);
207
			/* Determine if the item is already registered with the object mine */
208
		
208
			MacroObjectDescriptorMine objectMine = MacroManager.getInstance()
209
		IUIObject uiObject = findItemInObjectMine (item, id);
209
					.getObjectMine();
210
		if (uiObject != null)
210
			MacroObjectDescriptor activeObject = getCorrespondingMacroObjectDescriptor();
211
		{
211
			MacroObjectDescriptor objectItem = null;
212
			attributeValuePair.put(MacroConstants.REFERENCE_ID_ATTRIBUTE, uiObject.getReferenceId());
212
			if (activeObject != null) {
213
		}
213
				objectItem = objectMine.lookupMacroObjectDescriptor(
214
			
214
						activeObject, null, id.getWidgetId(), id.getObjectId());
215
		if (id.getResolverId() != null)
215
				/* It's not registered, register the object */
216
		{
216
				if (objectItem == null) {
217
			attributeValuePair.put(MacroConstants.RESOLVER_ATTRIBUTE, id.getResolverId());
217
					objectItem = new MacroObjectDescriptor(activeObject);
218
		}
218
					((MacroObjectDescriptor) objectItem).setWidgetId(id
219
		return attributeValuePair;
219
							.getWidgetId());
220
	}
220
					((MacroObjectDescriptor) objectItem).setResolver(id
221
	
221
							.getResolverId());
222
222
					((MacroObjectDescriptor) objectItem).setObjectId(id
223
	/**
223
							.getObjectId());
224
	 * Attempts to find an item in the current object mine.  If it's not found,
224
					String descriptiveField = getObjectClassName(item);
225
	 * then it is registered.
225
					if (descriptiveField == null)
226
	 * 
226
						descriptiveField = MacroConstants.EMPTY_STRING;
227
	 * @param item The item
227
					String itemText = getText(item);
228
	 * @param id The item id
228
					descriptiveField += itemText == null ? MacroConstants.EMPTY_STRING
229
	 * @return The object or null if it cannot be found or registered.
229
							: ": " + itemText;
230
	 */
230
					((MacroObjectDescriptor) objectItem).setDescriptive(XMLUtil
231
	private IUIObject findItemInObjectMine (Widget item, IWidgetId id)
231
							.useXMLSymbols(MacroUtil
232
	{
232
									.normalizeDescriptiveField(MacroUtil
233
		/* Determine if the item is already registered with the object mine */
233
											.boundSize(descriptiveField,
234
		IObjectMine objectMine = MacroManager.getInstance().getObjectMine();
234
													DESCRIPTIVE_FIELD_BOUND))));
235
		IUIObject activeObject = getCorrespondingObject();
235
					((MacroObjectDescriptor) objectItem)
236
		IUIObject objectItem = null;
236
							.setParent(activeObject);
237
		if (activeObject != null)
237
					try {
238
		{
238
						objectMine
239
			objectItem = objectMine.lookupUIObject(activeObject, null, id.toString());
239
								.registerObject((MacroObjectDescriptor) objectItem);
240
			/* It's not registered, register the object */
240
					} catch (Exception e) {
241
			if (objectItem == null)
241
						objectItem = null;
242
			{
242
243
				objectItem = new UIObject(activeObject);
243
						/*
244
				objectItem.setObjectId(id.toString());
244
						 * We can't show an error message because it will
245
				objectItem.setReferenceId(objectMine.getUniqueReferenceId());
245
						 * distrupt the record session, instead print to error
246
				objectItem.setResolver(id.getResolverId());
246
						 * stream
247
				String descriptiveField = getObjectClassName(item);
247
						 */
248
				if (descriptiveField == null)
248
						System.err
249
					descriptiveField = MacroConstants.EMPTY_STRING;
249
								.println(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REG);
250
				String itemText = getText(item);
250
						e.printStackTrace();
251
				descriptiveField += itemText == null ? MacroConstants.EMPTY_STRING :  ": " + itemText;	
251
					}
252
				objectItem.setDescriptive (XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField, DESCRIPTIVE_FIELD_BOUND))));
252
				}
253
				objectItem.setParent(activeObject);
253
			}
254
				try
254
255
				{
255
			return objectItem;
256
					objectMine.registerObject(objectItem);
256
		} else {
257
				} catch (Exception e)
257
			return null;
258
				{
258
		}
259
					objectItem = null;
259
	}
260
					
260
261
					/* We can't show an error message because it will distrupt the record session, instead print to error stream */
261
	/**
262
					System.err.println(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REG);
262
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#getCorrespondingMacroObjectDescriptor()
263
					e.printStackTrace();
263
	 */
264
				}
264
	public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() {
265
			}
265
		if (super.getCorrespondingMacroObjectDescriptor() != null)
266
		}
266
			return super.getCorrespondingMacroObjectDescriptor();
267
		
267
268
		return objectItem;
268
		MacroObjectDescriptorMine objectMine = MacroManager.getInstance()
269
	}
269
				.getObjectMine();
270
	
270
		MacroObjectDescriptor activeObject = objectMine.getActiveObject();
271
	
271
272
	/**
272
		if (useObjectMine() && getMacroObjectIdentifier() != null) {
273
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#getCorrespondingObject()
273
			String contextId = (getMacroObjectIdentifier()
274
	 */
274
					.getContextIdentifier() == null) ? null
275
	public IUIObject getCorrespondingObject ()
275
					: getMacroObjectIdentifier().getContextIdentifier()
276
	{
276
							.toString();
277
		if (super.getCorrespondingObject() != null)
277
			super
278
			return super.getCorrespondingObject();
278
					.setCorrespondingMacroObjectDescriptor(activeObject == null ? null
279
		
279
							: objectMine.lookupMacroObjectDescriptor(
280
		IObjectMine objectMine = MacroManager.getInstance().getObjectMine();
280
									activeObject, contextId,
281
		IUIObject activeObject = objectMine.getActiveObject();
281
									getMacroObjectIdentifier()
282
		String contextId = getWidgetId().getContextId() == null ? null : getWidgetId().getContextId().toString();
282
											.getObjectIdentifier()
283
		super.setCorrespondingObject(activeObject == null ? null : objectMine.lookupUIObject(activeObject, contextId, getWidgetId().getObjectId().toString()));
283
											.getWidgetId(),
284
		
284
									getMacroObjectIdentifier()
285
		return super.getCorrespondingObject();
285
											.getObjectIdentifier()
286
	}
286
											.getObjectId()));
287
	
287
		}
288
	/**
288
289
	 * Returns the tree item index in the form of N1|N2|N2|...|Nn where
289
		return super.getCorrespondingMacroObjectDescriptor();
290
	 * Ni corresponds to the item index in the tree.
290
	}
291
	 * 
291
292
	 * @param treeItem The tree item
292
	/**
293
	 * @param currentInx The current index
293
	 * Returns the tree item index in the form of N1|N2|N2|...|Nn where Ni
294
	 * @return A string representation of the index.
294
	 * corresponds to the item index in the tree.
295
	 */
295
	 * 
296
	private String findTreeItemInx(TreeItem treeItem, String currentInx) 
296
	 * @param treeItem
297
	{	
297
	 *            The tree item
298
		if (currentInx != null && currentInx.length() > 0)
298
	 * @param currentInx
299
			currentInx = "|" + currentInx;		
299
	 *            The current index
300
		
300
	 * @return A string representation of the index.
301
		/* We're not the root */
301
	 */
302
		if (treeItem.getParentItem() != null)
302
	private static String findTreeItemInx(TreeItem treeItem, String currentInx) {
303
		{
303
		if (currentInx != null && currentInx.length() > 0)
304
			TreeItem parentItem = treeItem.getParentItem();
304
			currentInx = "|" + currentInx;
305
			currentInx = parentItem.indexOf(treeItem) + "|" + currentInx;
305
306
			return findTreeItemInx(parentItem, currentInx);
306
		/* We're not the root */
307
		}
307
		if (treeItem.getParentItem() != null) {
308
		/* Otherwise we are the root */
308
			TreeItem parentItem = treeItem.getParentItem();
309
		int index = treeItem.getParent().indexOf(treeItem);
309
			currentInx = parentItem.indexOf(treeItem) + "|" + currentInx;
310
		return index + currentInx;			
310
			return findTreeItemInx(parentItem, currentInx);
311
	}
311
		}
312
312
		/* Otherwise we are the root */
313
	
313
		int index = treeItem.getParent().indexOf(treeItem);
314
	/**
314
		return index + currentInx;
315
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#load(org.w3c.dom.Node, java.util.Hashtable)
315
	}
316
	 */
316
317
	public void load(Node node, Hashtable lineTable) throws CoreException
317
	private static Item findItem(Item[] children, IUIObjectIdentifier widgetId) {
318
	{
318
		for (int i = 0; i < children.length; i++) {
319
		super.load(node, lineTable);
319
			IUIObjectIdentifier defaultAttributes = getDefaultItemAttributes(children[i]);
320
		NodeList children = node.getChildNodes();
320
			if (UIObjectDeprecatedDeresolvingSupport.foundWidget(children[i],
321
		for (int i = 0; i < children.getLength(); i++)
321
					widgetId)
322
		{
322
					|| defaultAttributes.getWidgetId().equals(
323
			Node child = children.item(i);
323
							widgetId.getWidgetId()))
324
			if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(MacroConstants.ITEM_ELEMENT))
324
				return children[i];
325
			{				
325
326
				/* First check to see if a reference id is available */
326
			/* We need to do a recursive search in the case of a tree */
327
				String attribute = MacroConstants.REFERENCE_ID_ATTRIBUTE;
327
			if (children instanceof TreeItem[]) {
328
				String attributeValue = MacroUtil.getAttribute(child, attribute);
328
				TreeItem treeItem = (TreeItem) children[i];
329
				
329
				int ccount = treeItem.getItemCount();
330
				/* If a reference id is not available, then check the path attribute */
330
				if (ccount > 0) {
331
				if (attributeValue == null)
331
					/* Test the item's children */
332
				{
332
					Item citem = findItem(treeItem.getItems(), widgetId);
333
					attribute = MacroConstants.PATH_ATTRIBUTE;
333
					if (citem != null)
334
					attributeValue = MacroUtil.getAttribute(child, attribute);
334
						return citem;
335
				}
335
				}
336
							
336
			}
337
				if (attributeValue != null)
337
		}
338
				{
338
		return null;
339
					Hashtable itemData = new Hashtable();
339
	}
340
					itemData.put(attribute, attributeValue);
340
341
					String resolverId = MacroUtil.getAttribute(child, MacroConstants.RESOLVER_ATTRIBUTE);
341
	private static IUIObjectIdentifier getDefaultItemAttributes(Widget item) {
342
					if (resolverId != null)
342
		Object data = item.getData();
343
						itemData.put(MacroConstants.RESOLVER_ATTRIBUTE, resolverId);
343
344
					items.add(itemData);
344
		String idStr = MacroConstants.EMPTY_STRING;
345
				}
345
		if (data != null)
346
			}
346
			idStr = data.getClass().getName();
347
		}
347
348
	}
348
		/* Append index to id if it's a table or a tree item */
349
349
		if (item instanceof TreeItem) {
350
	/**
350
			TreeItem treeItem = (TreeItem) item;
351
	 * Sub-classes can optionally overwrite this method to write additional
351
			idStr = idStr
352
	 * attributes to command.
352
					+ findTreeItemInx(treeItem, MacroConstants.EMPTY_STRING);
353
	 *  
353
		} else if (item instanceof TableItem) {
354
	 * @param sb The string buffer that the attributes should be written to.
354
			TableItem tableItem = (TableItem) item;
355
	 */
355
			idStr = idStr + tableItem.getParent().indexOf(tableItem);
356
	protected void writeAdditionalAttributes(StringBuffer sb)
356
		}
357
	{
357
		if (idStr.length() > 0)
358
	}
358
			return new PrimitiveUIObjectIdentifier(idStr);
359
359
360
	
360
		return null;
361
	/**
361
	}
362
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#write(int, java.lang.StringBuffer)
362
363
	 */
363
	/**
364
	public void write(int indent, StringBuffer sb) 
364
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#load(org.w3c.dom.Node,
365
	{
365
	 *      java.util.Hashtable)
366
		super.write(indent, sb);
366
	 */
367
		writeAdditionalAttributes(sb);
367
	public void load(Node node, Hashtable lineTable) throws CoreException {
368
		sb.append(MacroConstants.CLOSE_ANGLE_BRACKET);
368
		super.load(node, lineTable);
369
		sb.append(GlobalConstants.LINE_SEPARATOR);
369
		NodeList children = node.getChildNodes();
370
						
370
		for (int i = 0; i < children.getLength(); i++) {
371
		int cindent = indent + 1;
371
			Node child = children.item(i);
372
		boolean isObjectMineOn = MacroManager.getInstance().isObjectMineOn();
372
			if (child.getNodeType() == Node.ELEMENT_NODE
373
		for (int i = 0; i < items.size(); i++)
373
					&& child.getNodeName().equals(MacroConstants.ITEM_ELEMENT)) {
374
		{
374
				/* First check to see if a reference id is available */
375
			Map itemData = (Map)items.get(i);
375
				String attribute = MacroConstants.REFERENCE_ID_ATTRIBUTE;
376
			if (itemData != null)
376
				String attributeValue = MacroUtil
377
			{
377
						.getAttribute(child, attribute);
378
				String referenceId = (String)itemData.get(MacroConstants.REFERENCE_ID_ATTRIBUTE);
378
379
				String itemId = itemData.get(MacroConstants.PATH_ATTRIBUTE).toString();
379
				/*
380
				boolean useReferenceId = isObjectMineOn && referenceId != null;
380
				 * If a reference id is not available, then check the path
381
				MacroUtil.addElement(sb, cindent, MacroConstants.ITEM_ELEMENT, false, false);
381
				 * attribute
382
				MacroUtil.addAttribute(sb, 
382
				 */
383
						new String[]{
383
				if (attributeValue == null) {
384
							useReferenceId ? MacroConstants.REFERENCE_ID_ATTRIBUTE : MacroConstants.PATH_ATTRIBUTE, 
384
					attribute = MacroConstants.WIDGET_ID_ATTRIBUTE;
385
							MacroConstants.RESOLVER_ATTRIBUTE
385
					attributeValue = MacroUtil.getAttribute(child, attribute);
386
									}, 
386
				}
387
						new String[]{
387
388
							useReferenceId ? referenceId : itemId,
388
				if (attributeValue != null) {
389
							useReferenceId ? null : (String)itemData.get(MacroConstants.RESOLVER_ATTRIBUTE)
389
					Hashtable itemData = new Hashtable();
390
									}, true, true);
390
					itemData.put(attribute, attributeValue);
391
			}			
391
					String resolverId = MacroUtil.getAttribute(child,
392
		}
392
							MacroConstants.RESOLVER_ID_ATTRIBUTE);
393
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true);		
393
					if (resolverId != null)
394
	}
394
						itemData.put(MacroConstants.RESOLVER_ID_ATTRIBUTE,
395
395
								resolverId);
396
	/**
396
					items.add(itemData);
397
	 * Used to play the structured command collectively for all the discovered matches.
397
				}
398
	 * 
398
			}
399
	 * @param widget The widget
399
		}
400
	 * @param matches The matches discovered
400
	}
401
	 */
401
402
	protected abstract void playStructuredCommand(Widget widget, Object[] matches);
402
	/**
403
	
403
	 * Sub-classes can optionally overwrite this method to write additional
404
	
404
	 * attributes to command.
405
	/**
405
	 * 
406
	 * Some events require to be played as matches are discovered.  (e.g. an expansion command
406
	 * @param sb
407
	 * requires to be played for each discovered item in order for successive children to be found)
407
	 *            The string buffer that the attributes should be written to.
408
	 * It's recommended that either playStructuredCommandForFoundMatch or playStructuredCommand be implemented
408
	 */
409
	 * by clients, eventhough both methods will be invoked.
409
	protected void writeAdditionalAttributes(StringBuffer sb) {
410
	 *
410
	}
411
	 * @param widget The widget
411
412
	 * @param matches The match discovered
412
	/**
413
	 */
413
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#write(int,
414
	protected abstract void playStructuredCommandForFoundMatch(Widget widget, Object match);
414
	 *      java.lang.StringBuffer)
415
	
415
	 */
416
	
416
	public void write(int indent, StringBuffer sb) {
417
	public final boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
417
		super.write(indent, sb);
418
	{
418
		writeAdditionalAttributes(sb);
419
		CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine());
419
		sb.append(MacroConstants.CLOSE_ANGLE_BRACKET);
420
420
		sb.append(GlobalConstants.LINE_SEPARATOR);
421
		if (targets == null)
421
422
			return false;
422
		int cindent = indent + 1;
423
		
423
		boolean isObjectMineOn = MacroManager.getInstance().isObjectMineOn();
424
		for (int i = 0; i < targets.length; i++)
424
		for (int i = 0; i < items.size(); i++) {
425
		{
425
			Map itemData = (Map) items.get(i);
426
			targets[i].setFocus();
426
			if (itemData != null) {
427
			
427
				String referenceId = (String) itemData
428
			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: A process display event causes the target widget to sometimes
428
						.get(MacroConstants.REFERENCE_ID_ATTRIBUTE);
429
			 * be disposed.  
429
				String itemId = itemData
430
			 * MacroUtil.processDisplayEvents(display);	*/
430
						.get(MacroConstants.WIDGET_ID_ATTRIBUTE).toString();
431
			Widget widget = targets[i].getWidget();
431
				boolean useReferenceId = isObjectMineOn && referenceId != null;
432
432
				MacroUtil.addElement(sb, cindent, MacroConstants.ITEM_ELEMENT,
433
			if (widget == null || widget.isDisposed())
433
						false, false);
434
				continue;
434
				MacroUtil.addAttribute(sb, new String[] {
435
435
						useReferenceId ? MacroConstants.REFERENCE_ID_ATTRIBUTE
436
			Object[] matches = findMatches(widget);
436
								: MacroConstants.WIDGET_ID_ATTRIBUTE,
437
				
437
						MacroConstants.RESOLVER_ID_ATTRIBUTE }, new String[] {
438
			/* If we failed to locate the item, then continue */
438
						useReferenceId ? referenceId : itemId,
439
			if (matches != null && items.size() != matches.length)
439
						useReferenceId ? null : (String) itemData
440
				continue;
440
								.get(MacroConstants.RESOLVER_ID_ATTRIBUTE) },
441
				
441
						true, true);
442
			playStructuredCommand(widget, matches);
442
			}
443
			return true;
443
		}
444
		}
444
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true,
445
		
445
				true);
446
		return false;
446
	}
447
	}
447
448
448
	/**
449
	protected Object[] findMatches(Widget widget) throws CoreException
449
	 * Used to play the structured command collectively for all the discovered
450
	{
450
	 * matches.
451
		if (widget instanceof Tree)
451
	 * 
452
			return findMatches((Tree)widget);
452
	 * @param widget
453
		else if (widget instanceof Table)
453
	 *            The widget
454
			return findMatches((Table)widget);
454
	 * @param matches
455
		else if (widget instanceof List)
455
	 *            The matches discovered
456
			return findMatches ((List) widget);
456
	 */
457
		
457
	protected abstract void playStructuredCommand(Widget widget,
458
		return null;
458
			Object[] matches);
459
	}
459
460
460
	/**
461
	private String[] findMatches(List list) throws CoreException
461
	 * Some events require to be played as matches are discovered. (e.g. an
462
	{
462
	 * expansion command requires to be played for each discovered item in order
463
		String[] children = list.getItems();
463
	 * for successive children to be found) It's recommended that either
464
		ArrayList matches = new ArrayList();
464
	 * playStructuredCommandForFoundMatch or playStructuredCommand be
465
		for (int i = 0; i < items.size(); i++)
465
	 * implemented by clients, eventhough both methods will be invoked.
466
		{
466
	 * 
467
			String itemId = findObjectId(i).toString();
467
	 * @param widget
468
			int itemInx = list.indexOf(itemId);
468
	 *            The widget
469
			if (itemInx >= 0 && itemInx < children.length)
469
	 * @param matches
470
			{
470
	 *            The match discovered
471
				playStructuredCommandForFoundMatch (list, children[itemInx]);
471
	 */
472
				matches.add(children[itemInx]);
472
	protected abstract void playStructuredCommandForFoundMatch(Widget widget,
473
			}
473
			Object match);
474
		}
474
475
		return (String[]) matches.toArray(new String[matches.size()]);
475
	public final boolean doPlayback(Display display, Shell parent,
476
	}
476
			IProgressMonitor monitor) throws CoreException {
477
	
477
		if (macroObject == null)
478
478
			return false;
479
	private TreeItem[] findMatches(Tree tree) throws CoreException
479
480
	{
480
		// for (int i = 0; i < targets.length; i++) {
481
		TreeItem[] children = tree.getItems();
481
		setFocus(macroObject);
482
		ArrayList matches = new ArrayList();
482
483
		for (int i = 0; i < items.size(); i++)
483
		/*
484
		{
484
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: A process
485
			IWidgetId currentWidgetId = findObjectId(i);
485
		 * display event causes the target widget to sometimes be disposed.
486
			String itemId = currentWidgetId.toString();
486
		 * MacroUtil.processDisplayEvents(display);
487
			Item item = findItem(children, currentWidgetId.getResolverId(), itemId);
487
		 */
488
			if (item != null)
488
		Widget widget = macroObject.getUIObject().getWidget();
489
			{
489
490
				playStructuredCommandForFoundMatch (tree, item);
490
		if (widget == null || widget.isDisposed())
491
				matches.add(item);
491
			return false;// continue;
492
			}
492
493
		}
493
		Object[] matches = findMatches(widget);
494
		return (TreeItem[]) matches.toArray(new TreeItem[matches.size()]);
494
495
	}
495
		/* If we failed to locate the item, then continue */
496
496
		if (matches != null && items.size() != matches.length)
497
	private TableItem[] findMatches(Table table) throws CoreException
497
			return false;// continue;
498
	{
498
499
		TableItem[] elements = table.getItems();
499
		playStructuredCommand(widget, matches);
500
		ArrayList matches = new ArrayList();
500
		return true;
501
501
		// }
502
		for (int i = 0; i < items.size(); i++)
502
503
		{
503
		// return false;
504
			IWidgetId currentWidgetId = findObjectId(i);
504
	}
505
			String itemId = currentWidgetId.toString();
505
506
			Item item = findItem(elements, currentWidgetId.getResolverId(), itemId);
506
	protected Object[] findMatches(Widget widget) throws CoreException {
507
			if (item != null)
507
		if (widget instanceof Tree)
508
			{
508
			return findMatches((Tree) widget);
509
				playStructuredCommandForFoundMatch (table, item);
509
		else if (widget instanceof Table)
510
				matches.add(item);
510
			return findMatches((Table) widget);
511
			}
511
		else if (widget instanceof List)
512
		}
512
			return findMatches((List) widget);
513
		return (TableItem[]) matches.toArray(new TableItem[matches.size()]);
513
514
	}
514
		return null;
515
515
	}
516
	
516
517
	/**
517
	private String[] findMatches(List list) throws CoreException {
518
	 * Returns the object id of the inx-th item associated with this
518
		String[] children = list.getItems();
519
	 * structured command.
519
		ArrayList matches = new ArrayList();
520
	 * 
520
		for (int i = 0; i < items.size(); i++) {
521
	 * @param inx The index of the item
521
			String itemId = findObjectId(i).toString();
522
	 * @return The object id
522
			int itemInx = list.indexOf(itemId);
523
	 * 
523
			if (itemInx >= 0 && itemInx < children.length) {
524
	 * @throws CoreException If an error occurrs while attempting to find the object
524
				playStructuredCommandForFoundMatch(list, children[itemInx]);
525
	 */
525
				matches.add(children[itemInx]);
526
	protected IWidgetId findObjectId(int inx) throws CoreException
526
			}
527
	{
527
		}
528
		Hashtable itemData = null;
528
		return (String[]) matches.toArray(new String[matches.size()]);
529
		if (inx < 0 || inx >= items.size() || (itemData = (Hashtable)items.get(inx)) == null)
529
	}
530
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_ITEM, getStartLine());
530
531
		
531
	private TreeItem[] findMatches(Tree tree) throws CoreException {
532
		Object itemObjectId = null;
532
		TreeItem[] children = tree.getItems();
533
		PrimitiveWidgetId widgetId = null;
533
		ArrayList matches = new ArrayList();
534
		if ((itemObjectId = itemData.get(MacroConstants.PATH_ATTRIBUTE)) != null)
534
		for (int i = 0; i < items.size(); i++) {
535
		{
535
			IUIObjectIdentifier currentWidgetId = findObjectId(i);
536
			widgetId = new PrimitiveWidgetId(itemObjectId.toString());
536
			Item item = findItem(children, currentWidgetId);
537
			widgetId.setResolverId((String)itemData.get(MacroConstants.RESOLVER_ATTRIBUTE));
537
			if (item != null) {
538
			return widgetId;
538
				playStructuredCommandForFoundMatch(tree, item);
539
		}
539
				matches.add(item);
540
		
540
			}
541
		String referenceId = (String)itemData.get(MacroConstants.REFERENCE_ID_ATTRIBUTE);
541
		}
542
		if (referenceId == null)
542
		return (TreeItem[]) matches.toArray(new TreeItem[matches.size()]);
543
			return new PrimitiveWidgetId(MacroConstants.EMPTY_STRING);
543
	}
544
		
544
545
		IObjectMine objectMine = MacroManager.getInstance().getObjectMine();
545
	private TableItem[] findMatches(Table table) throws CoreException {
546
		if (objectMine == null)
546
		TableItem[] elements = table.getItems();
547
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_T, getStartLine());
547
		ArrayList matches = new ArrayList();
548
			
548
549
		IUIObject parentObject = getCorrespondingObject();
549
		for (int i = 0; i < items.size(); i++) {
550
		IUIObject itemObject = null;
550
			IUIObjectIdentifier currentWidgetId = findObjectId(i);
551
		if (parentObject != null)
551
			Item item = findItem(elements, currentWidgetId);
552
			itemObject = MacroManager.getInstance().getObjectMine().lookupUIObject(parentObject, referenceId);
552
			if (item != null) {
553
		
553
				playStructuredCommandForFoundMatch(table, item);
554
		
554
				matches.add(item);
555
		if (itemObject == null || (itemObjectId = itemObject.getObjectId()) == null)
555
			}
556
			return new PrimitiveWidgetId(MacroConstants.EMPTY_STRING);
556
		}
557
		
557
		return (TableItem[]) matches.toArray(new TableItem[matches.size()]);
558
		itemData.put(MacroConstants.PATH_ATTRIBUTE, itemObjectId);
558
	}
559
		widgetId = new PrimitiveWidgetId(itemObjectId.toString());
559
560
		widgetId.setResolverId(itemObject.getResolverId());
560
	/**
561
		return widgetId;
561
	 * Returns the object id of the inx-th item associated with this structured
562
	}
562
	 * command.
563
	
563
	 * 
564
	
564
	 * @param inx
565
	private Item findItem(Item[] children, String resolverId, String itemId)
565
	 *            The index of the item
566
	{
566
	 * @return The object id
567
		for (int i = 0; i < children.length; i++)
567
	 * 
568
		{
568
	 * @throws CoreException
569
			if (MacroObjectLocator.foundWidget(children[i], resolverId, itemId) || getDefaultItemAttributes(children[i]).equals(itemId))
569
	 *             If an error occurrs while attempting to find the object
570
				return children[i];
570
	 */
571
571
	protected IUIObjectIdentifier findObjectId(int inx) throws CoreException {
572
			/* We need to do a recursive search in the case of a tree */
572
		Hashtable itemData = null;
573
			if (children instanceof TreeItem[])
573
		if (inx < 0 || inx >= items.size()
574
			{
574
				|| (itemData = (Hashtable) items.get(inx)) == null)
575
				TreeItem treeItem = (TreeItem)children[i];
575
			AutoGUIUtil.throwCoreException(
576
				int ccount = treeItem.getItemCount();
576
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_ITEM, getStartLine());
577
				if (ccount > 0)
577
578
				{
578
		Object itemObjectId = null;
579
					/* Test the item's children */
579
		PrimitiveUIObjectIdentifier widgetId = null;
580
					Item citem = findItem(treeItem.getItems(), resolverId, itemId);
580
		if ((itemObjectId = itemData.get(MacroConstants.WIDGET_ID_ATTRIBUTE)) != null) {
581
					if (citem != null)
581
			widgetId = new PrimitiveUIObjectIdentifier(itemObjectId.toString(),
582
						return citem;				
582
					(String) itemData.get(MacroConstants.RESOLVER_ID_ATTRIBUTE));
583
				}
583
			return widgetId;
584
			}
584
		}
585
		}
585
586
		return null;
586
		String referenceId = (String) itemData
587
	}
587
				.get(MacroConstants.REFERENCE_ID_ATTRIBUTE);
588
588
		if (referenceId == null)
589
	
589
			return new PrimitiveUIObjectIdentifier(MacroConstants.EMPTY_STRING);
590
	/**
590
591
	 * Returns the items that this command must match
591
		MacroObjectDescriptorMine objectMine = MacroManager.getInstance()
592
	 * 
592
				.getObjectMine();
593
	 * @return Matched items
593
		if (objectMine == null)
594
	 */
594
			AutoGUIUtil.throwCoreException(
595
	protected ArrayList getItems() 
595
					AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_T,
596
	{
596
					getStartLine());
597
		return items;
597
598
	}
598
		MacroObjectDescriptor parentObject = getCorrespondingMacroObjectDescriptor();
599
	
599
		MacroObjectDescriptor itemObject = null;
600
	
600
		if (parentObject != null)
601
	public boolean equals (Object obj)
601
			itemObject = MacroManager.getInstance().getObjectMine()
602
	{
602
					.lookupMacroObjectDescriptor(parentObject, referenceId);
603
		boolean equalState = super.equals(obj);
603
604
		if (!equalState)
604
		if (itemObject == null
605
			return false;
605
				|| (itemObjectId = itemObject.getWidgetId()) == null)
606
		
606
			return new PrimitiveUIObjectIdentifier(MacroConstants.EMPTY_STRING);
607
		AbstractStructuredCommand compareWithObj = (AbstractStructuredCommand)obj;
607
608
		if (compareWithObj.getItems().size() != items.size())
608
		itemData.put(MacroConstants.WIDGET_ID_ATTRIBUTE, itemObjectId);
609
			return false;
609
		widgetId = new PrimitiveUIObjectIdentifier(itemObjectId.toString(),
610
		
610
				itemObject.getResolverId());
611
		/* For each item */
611
		return widgetId;
612
		for (int i = 0, objectCount = items.size(); i < objectCount; i++)
612
	}
613
		{
613
614
			try
614
	/**
615
			{
615
	 * Returns the items that this command must match
616
				if (!compareWithObj.findObjectId(i).equals(findObjectId(i)))
616
	 * 
617
					return false;
617
	 * @return Matched items
618
			} catch (CoreException e)
618
	 */
619
			{
619
	protected ArrayList getItems() {
620
				return false;
620
		return items;
621
			}
621
	}
622
		}
622
623
		
623
	public boolean equals(Object obj) {
624
		return true;
624
		boolean equalState = super.equals(obj);
625
	}
625
		if (!equalState)
626
626
			return false;
627
628
		AbstractStructuredCommand compareWithObj = (AbstractStructuredCommand) obj;
629
		if (compareWithObj.getItems().size() != items.size())
630
			return false;
631
632
		/* For each item */
633
		for (int i = 0, objectCount = items.size(); i < objectCount; i++) {
634
			try {
635
				if (!compareWithObj.findObjectId(i).equals(findObjectId(i)))
636
					return false;
637
			} catch (CoreException e) {
638
				return false;
639
			}
640
		}
641
642
		return true;
643
	}
644
627
}
645
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ModifyCommand.java (-255 / +244 lines)
Lines 1-256 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.Hashtable;
13
import java.util.Hashtable;
14
14
15
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.custom.CCombo;
18
import org.eclipse.swt.custom.CCombo;
19
import org.eclipse.swt.custom.StyledText;
19
import org.eclipse.swt.custom.StyledText;
20
import org.eclipse.swt.widgets.Combo;
20
import org.eclipse.swt.widgets.Combo;
21
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Display;
22
import org.eclipse.swt.widgets.Display;
22
import org.eclipse.swt.widgets.Event;
23
import org.eclipse.swt.widgets.Event;
23
import org.eclipse.swt.widgets.Shell;
24
import org.eclipse.swt.widgets.Text;
24
import org.eclipse.swt.widgets.Text;
25
import org.eclipse.swt.widgets.Widget;
25
import org.eclipse.swt.widgets.Widget;
26
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
26
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
27
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
27
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.w3c.dom.Node;
31
import org.w3c.dom.Node;
31
import org.w3c.dom.NodeList;
32
import org.w3c.dom.NodeList;
32
33
33
public class ModifyCommand extends ObjectBasedCommand {
34
public class ModifyCommand extends AbstractMacroCommand {
34
35
	
35
	public static final String TYPE = IMacroCommand.MODIFY;
36
	public static final String TYPE = "modify";
36
	public static final String CDATA_OPEN = "<![CDATA[";
37
	public static final String CDATA_OPEN = "<![CDATA[";
37
	public static final String CDATA_CLOSE = "]]>";
38
	public static final String CDATA_CLOSE = "]]>";
38
39
39
	private String text;
40
	private String text;
40
41
	
41
	public ModifyCommand(MacroCommandShell parent) {
42
	public ModifyCommand(MacroCommandShell parent, WidgetIdentifier wid) {
42
		super(parent);
43
		super(parent, wid);
43
	}
44
	}
44
45
45
	public String getType() {
46
	public String getType() {
46
		return TYPE;
47
		return TYPE;
47
	}
48
	}
48
49
49
	public boolean mergeEvent(Event e) throws Exception {
50
	public boolean mergeEvent(Event e) {
50
		try {
51
		return doProcessEvent(e);
51
			doProcessEvent(e);
52
	}
52
			return true;
53
53
		} catch (Exception exception) {
54
	public void processEvent(Event e) {
54
			return false;
55
		doProcessEvent(e);
55
		}
56
	}
56
	}
57
57
58
	public void load(Node node, Hashtable lineTable) throws CoreException
58
	public void load(Node node, Hashtable lineTable) throws CoreException {
59
	{
59
		super.load(node, lineTable);
60
		super.load(node, lineTable);
60
61
61
		NodeList children = node.getChildNodes();
62
		NodeList children = node.getChildNodes();
62
		for (int i = 0; i < children.getLength(); i++) {
63
		for (int i=0; i<children.getLength(); i++) {
63
			Node child = children.item(i);
64
			Node child = children.item(i);
64
			if (child.getNodeType() == Node.TEXT_NODE) {
65
			if (child.getNodeType()==Node.TEXT_NODE) {
65
				text = child.getNodeValue().trim();
66
				text = child.getNodeValue().trim();
66
				break;
67
				break;
67
			}
68
			}
68
		}
69
		}
69
70
		
70
		/* If in case the text is null, then set it to an empty string */
71
		/* If in case the text is null, then set it to an empty string */
71
		if (text == null)
72
		if (text == null)
72
			text = "";
73
			text = "";
73
		else
74
		else
74
			text = convertHTMLCodeToChar(text);
75
			text = convertHTMLCodeToChar(text);
75
	}
76
	}
76
77
77
	protected void doProcessEvent(Event e) throws CoreException {
78
	private boolean doProcessEvent(Event e) {
78
		findDescriptiveField(e.widget);
79
		String text = extractText(e.widget);
79
		String text = extractText(e.widget);
80
		if (text != null) {
80
		if (text != null) {
81
			this.text = text;
81
			this.text = text;
82
			return true;
82
		}
83
		}
83
	}
84
		return false;
84
85
	}
85
	private String extractText(Widget widget) {
86
86
		String widgetText = null;
87
	private String extractText(Widget widget) 
87
		if (widget instanceof Text)
88
	{		
88
			widgetText = ((Text) widget).getText();
89
		String widgetText = null;
89
90
		if (widget instanceof Text)	
90
		else if (widget instanceof Combo)
91
			widgetText = ((Text) widget).getText();
91
			widgetText = ((Combo) widget).getText();
92
		
92
93
		else if (widget instanceof Combo)
93
		else if (widget instanceof CCombo)
94
			widgetText = ((Combo) widget).getText();
94
			widgetText = ((CCombo) widget).getText();
95
		
95
96
		else if (widget instanceof CCombo)
96
		else if (widget instanceof StyledText)
97
			widgetText = ((CCombo) widget).getText();
97
			widgetText = ((StyledText) widget).getText();
98
		
98
99
		else if (widget instanceof StyledText)
99
		if (widgetText != null)
100
			widgetText = ((StyledText) widget).getText();
100
			return convertSpaces(widgetText);
101
		
101
102
		if (widgetText != null)
102
		return null;
103
			return convertSpaces(widgetText);
103
	}
104
		
104
105
		return null;
105
	/**
106
	}
106
	 * Convert leading and trailing spaces to their respective HTML code. This
107
107
	 * is so that the user inserted spaces are not lost after a trim operation.
108
	/**
108
	 */
109
	 * Convert leading and trailing spaces to their respective HTML code.  This is so
109
	public String convertSpaces(String input) {
110
	 * that the user inserted spaces are not lost after a trim operation.
110
		String convertedString = "";
111
	 */
111
		char[] inputCharacters = input.toCharArray();
112
	public String convertSpaces (String input)
112
113
	{
113
		/* Convert leading spaces */
114
		String convertedString = "";
114
		boolean validCharacterReached = false;
115
		char[] inputCharacters = input.toCharArray();
115
		String htmlCode;
116
		
116
		int i = 0;
117
		/* Convert leading spaces */
117
		for (; i < inputCharacters.length && !validCharacterReached; i++) {
118
		boolean validCharacterReached = false;
118
			htmlCode = convertCharacter(inputCharacters[i]);
119
		String htmlCode;
119
			if (htmlCode == null)
120
		int i = 0;
120
				break;
121
		for (; i < inputCharacters.length && !validCharacterReached; i++)
121
			convertedString += htmlCode;
122
		{			
122
		}
123
			htmlCode = convertCharacter (inputCharacters[i]);
123
		convertedString += input.substring(i).trim();
124
			if (htmlCode == null)
124
125
				break;
125
		/* Convert trailing spaces */
126
			convertedString += htmlCode;
126
		String trailingSpaces = "";
127
		}
127
		for (i = inputCharacters.length - 1; i >= 0; i--) {
128
		convertedString += input.substring(i).trim();
128
			htmlCode = convertCharacter(inputCharacters[i]);
129
		
129
			if (htmlCode == null)
130
		/* Convert trailing spaces */
130
				break;
131
		String trailingSpaces = "";
131
			trailingSpaces = htmlCode + trailingSpaces;
132
		for (i = inputCharacters.length - 1; i >= 0; i--)
132
		}
133
		{
133
		convertedString += trailingSpaces;
134
			htmlCode = convertCharacter (inputCharacters[i]);
134
		return convertedString;
135
			if (htmlCode == null)
135
	}
136
				break;
136
137
			trailingSpaces = htmlCode + trailingSpaces;
137
	public String convertCharacter(char character) {
138
		}
138
		switch (character) {
139
		convertedString += trailingSpaces;		
139
		case '\t':
140
		return convertedString;
140
			return "&#09;";
141
	}
141
		case '\n':
142
	
142
			return "&#10;";
143
	
143
		case '\r':
144
	public String convertCharacter (char character)
144
			return "&#13;";
145
	{
145
		case ' ':
146
		switch (character)
146
			return "&#32;";
147
		{
147
		default:
148
			case '\t':
148
			return null;
149
				return "&#09;";
149
		}
150
			case '\n':
150
	}
151
				return  "&#10;";
151
152
			case '\r':
152
	private String convertHTMLCodeToChar(String input) {
153
				return "&#13;";
153
		String normalizedString = "";
154
			case ' ':
154
		String inputCloned = input;
155
				return "&#32;";
155
		int currentHTMLCodeInx;
156
			default:
156
		final int HTML_LENGTH_CODE = 5;
157
				return null;						
157
158
		}
158
		while ((currentHTMLCodeInx = inputCloned.indexOf("&#")) != -1) {
159
	}
159
			int totalHTMLCodeLen = currentHTMLCodeInx + HTML_LENGTH_CODE;
160
	
160
			if (totalHTMLCodeLen > inputCloned.length())
161
	private String convertHTMLCodeToChar(String input) 
161
				break;
162
	{		
162
163
		String normalizedString = "";
163
			String htmlCode = inputCloned.substring(currentHTMLCodeInx,
164
		String inputCloned = input;
164
					totalHTMLCodeLen);
165
		int currentHTMLCodeInx;
165
			String htmlChar = convertCodeToChar(htmlCode);
166
		final int HTML_LENGTH_CODE = 5;
166
			normalizedString += inputCloned.substring(0, currentHTMLCodeInx)
167
		
167
					+ htmlChar;
168
		while ((currentHTMLCodeInx = inputCloned.indexOf("&#"))!= -1)
168
			inputCloned = inputCloned.substring(totalHTMLCodeLen);
169
		{
169
		}
170
			int totalHTMLCodeLen = currentHTMLCodeInx + HTML_LENGTH_CODE;
170
		normalizedString += inputCloned;
171
			if (totalHTMLCodeLen > inputCloned.length())
171
172
				break;
172
		return normalizedString;
173
			
173
	}
174
			String htmlCode = inputCloned.substring(currentHTMLCodeInx, totalHTMLCodeLen);
174
175
			String htmlChar = convertCodeToChar(htmlCode);
175
	private String convertCodeToChar(String htmlCode) {
176
			normalizedString +=  inputCloned.substring(0, currentHTMLCodeInx) + htmlChar;
176
		if (htmlCode.equals("&#09;"))
177
			inputCloned = inputCloned.substring(totalHTMLCodeLen);
177
			return "\t";
178
		}
178
		else if (htmlCode.equals("&#10;"))
179
		normalizedString += inputCloned;
179
			return "\n";
180
		
180
		else if (htmlCode.equals("&#13;"))
181
		return normalizedString;
181
			return "\r";
182
	}
182
		else if (htmlCode.equals("&#32;"))
183
	
183
			return " ";
184
	private String convertCodeToChar(String htmlCode) 
184
		else
185
	{
185
			return htmlCode;
186
		if (htmlCode.equals("&#09;"))
186
	}
187
			return "\t";
187
188
		else if (htmlCode.equals("&#10;"))
188
	public void write(int indent, StringBuffer sb) {
189
			return "\n";
189
		/* Ignore this command if it's corrupted */
190
		else if (htmlCode.equals("&#13;"))
190
		if (getMacroObjectIdentifier() == null || text == null
191
			return "\r";
191
				|| text.length() <= 0)
192
		else if (htmlCode.equals("&#32;"))
192
			return;
193
			return " ";
193
194
		else
194
		super.write(indent, sb, false, true);
195
			return htmlCode;
195
		if (text != null) {
196
	}
196
			MacroUtil.addIndent(sb, indent);
197
197
			sb.append(CDATA_OPEN);
198
	public void write(int indent, StringBuffer sb) 
198
			sb.append(text);
199
	{
199
			sb.append(CDATA_CLOSE);
200
		/* Ignore this command if it's corrupted */
200
			sb.append(GlobalConstants.LINE_SEPARATOR);
201
		if (getWidgetId() == null || text == null || text.length() <= 0)
201
		}
202
			return;
202
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true,
203
203
				true);
204
		super.write(indent, sb, false, true);
204
	}
205
		if (text != null) 
205
206
		{
206
	public boolean doPlayback(Display display, Shell parent,
207
			MacroUtil.addIndent(sb, indent);
207
			IProgressMonitor monitor) throws CoreException {
208
			sb.append(CDATA_OPEN);
208
209
			sb.append(text);
209
		if (parent.isDisposed())
210
			sb.append(CDATA_CLOSE);
210
			return false;
211
			sb.append(GlobalConstants.LINE_SEPARATOR);
211
212
		}
212
		if (macroObject != null) {
213
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true);
213
			setFocus(macroObject);
214
	}
214
			Widget widget = macroObject.getUIObject().getWidget();
215
215
216
	public boolean playback(Display display, Composite parent, 
216
			if (widget instanceof Text)
217
			IProgressMonitor monitor) throws CoreException 
217
				((Text) widget).setText(text);
218
	{
218
			else if (widget instanceof Combo)
219
		
219
				((Combo) widget).setText(text);
220
		if (parent.isDisposed()) 
220
			else if (widget instanceof CCombo)
221
			return false;
221
				((CCombo) widget).setText(text);
222
		
222
			else if (widget instanceof StyledText)
223
		CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine());
223
				((StyledText) widget).setText(text);
224
		CommandTarget target = targets[0];
224
225
		if (target != null) 
225
			/*
226
		{
226
			 * Ali M.: Some classes explicitly listen for a selection before a
227
			target.setFocus();
227
			 * modification is made
228
			Widget widget = target.getWidget();
228
			 */
229
			
229
			Event event = new Event();
230
			if (widget instanceof Text)
230
			event.display = display;
231
				((Text) widget).setText(text);
231
			event.widget = widget;
232
			else if (widget instanceof Combo)
232
			event.type = SWT.Selection;
233
				((Combo) widget).setText(text);
233
			widget.notifyListeners(SWT.Selection, event);
234
			else if (widget instanceof CCombo)
234
			MacroUtil.processDisplayEvents(display);
235
				((CCombo) widget).setText(text);
235
236
			else if (widget instanceof StyledText)
236
			/* Send out a modify command to notify modify listeners */
237
				((StyledText)widget).setText(text);
237
			event.type = SWT.Modify;
238
			
238
			widget.notifyListeners(SWT.Modify, event);
239
			/* Ali M.: Some classes explicitly listen for a selection before a modification is made */			
239
			MacroUtil.processDisplayEvents(display);
240
			Event event = new Event();
240
241
			event.display = display;
241
		}
242
			event.widget = widget;
242
243
			event.type = SWT.Selection;
243
		return true;
244
			widget.notifyListeners(SWT.Selection, event);
244
	}
245
			MacroUtil.processDisplayEvents(display);	
246
			
247
			/* Send out a modify command to notify modify listeners */
248
			event.type = SWT.Modify;			
249
			widget.notifyListeners(SWT.Modify, event);
250
			MacroUtil.processDisplayEvents(display);
251
			
252
		}		
253
		
254
		return true;
255
	}
256
}
245
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/AbstractMacroCommand.java (-142 / +153 lines)
Lines 13-27 Link Here
13
import java.util.Hashtable;
13
import java.util.Hashtable;
14
14
15
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.Path;
17
import org.eclipse.hyades.test.common.util.XMLUtil;
16
import org.eclipse.hyades.test.common.util.XMLUtil;
17
import org.eclipse.jface.window.Window;
18
import org.eclipse.swt.widgets.Control;
19
import org.eclipse.swt.widgets.Display;
18
import org.eclipse.swt.widgets.Event;
20
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Widget;
21
import org.eclipse.swt.widgets.Widget;
20
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction;
22
import org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction;
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
22
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
26
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject;
27
import org.eclipse.ui.IEditorPart;
28
import org.eclipse.ui.IViewPart;
29
import org.eclipse.ui.IWorkbenchPage;
25
import org.w3c.dom.Node;
30
import org.w3c.dom.Node;
26
31
27
/**
32
/**
Lines 31-36 Link Here
31
 * 
36
 * 
32
 * @author  Ali Mehregani
37
 * @author  Ali Mehregani
33
 * @author  Paul Slauenwhite
38
 * @author  Paul Slauenwhite
39
 * @author Alexander Nyssen
34
 * @version May 22, 2009
40
 * @version May 22, 2009
35
 * @since   July 10, 2006
41
 * @since   July 10, 2006
36
 */
42
 */
Lines 46-150 Link Here
46
	private String descriptiveField;	
52
	private String descriptiveField;	
47
53
48
	/** Time difference between this command and the previous command (applicable when artificial wait time is enabled) */
54
	/** Time difference between this command and the previous command (applicable when artificial wait time is enabled) */
49
	private long timeDifference;	
55
	private long timeDifference;
50
	
56
51
	
52
	/**
57
	/**
53
	 * Constructor
58
	 * Constructor
54
	 * 
59
	 * 
55
	 * @param parent The parent command shell
60
	 * @param parent
56
	 * @param widgetId The associated widget id
61
	 *            The parent command shell
62
	 * @param widgetId
63
	 *            The associated widget id
57
	 */
64
	 */
58
	public AbstractMacroCommand(MacroCommandShell parent, WidgetIdentifier widgetId)
65
	public AbstractMacroCommand(MacroCommandShell parent) {
59
	{
60
		setWidgetId(widgetId);
61
		this.parent = parent;
66
		this.parent = parent;
62
	}
67
	}
63
68
	
64
69
	public boolean mergeEvent(Event e) throws Exception {
65
	public void load(Node node, Hashtable lineTable) throws CoreException
66
	{
67
		super.load(node, lineTable);
68
		String cid = MacroUtil.getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE);
69
		String wid = MacroUtil.getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE);		
70
		String rid = MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE);		
71
		
72
		if (cid != null && wid != null)
73
		{
74
			setWidgetId(new WidgetIdentifier(
75
					cid == null ? new Path(MacroConstants.EMPTY_STRING) : new Path(cid), 
76
					wid == null ? new Path(MacroConstants.EMPTY_STRING) : new Path(wid),
77
					rid));			
78
		}
79
	}
80
81
82
	public boolean mergeEvent(Event e)
83
	{
84
		return false;
70
		return false;
85
	}
71
	}
72
86
	
73
	
87
	
74
88
	/**
75
	/**
89
	 * Returns the descriptive field of this command.
76
	 * Returns the descriptive field of this command.
90
	 * 
77
	 * 
91
	 * @return The descriptive field of this command.
78
	 * @return The descriptive field of this command.
92
	 */
79
	 */
93
	public String getDescriptiveField()
80
	public String getDescriptiveField() {
94
	{
95
		return descriptiveField;
81
		return descriptiveField;
96
	}
82
	}
97
	
83
98
	
99
	/**
84
	/**
100
	 * Set the descriptive field of this command.  The descriptive field is used
85
	 * Set the descriptive field of this command. The descriptive field is used to more easily identify the semantics of a command.
101
	 * to more easily identify the semantics of a command. 
86
	 * 
102
	 *  
87
	 * @param descriptiveField
103
	 * @param descriptiveField The descriptive field (can be a button's text, a tree
88
	 *            The descriptive field (can be a button's text, a tree item label, or etc...)
104
	 * item label, or etc...)
105
	 */
89
	 */
106
	public void setDescriptiveField(String descriptiveField)
90
	public void setDescriptiveField(String descriptiveField) {
107
	{
91
		this.descriptiveField = XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField,
108
		this.descriptiveField = XMLUtil.useXMLSymbols(MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(descriptiveField, DESCRIPTIVE_FIELD_BOUND)));
92
			DESCRIPTIVE_FIELD_BOUND)));
109
	}
93
	}
110
94
111
	
112
	/**
95
	/**
113
	 * Initializes the descriptive field of this command based on the
96
	 * Initializes the descriptive field of this command based on the value returned by the getText() method of the widget (if it has one)
114
	 * value returned by the getText() method of the widget (if it has one)
115
	 * 
97
	 * 
116
	 * @param widget The widget
98
	 * @param widget
99
	 *            The widget
117
	 */
100
	 */
118
	protected void findDescriptiveField(Widget widget)
101
	protected void findDescriptiveField(Widget widget) {
119
	{
102
		setDescriptiveField(getText(widget));
120
		setDescriptiveField(getText(widget));	
121
	}
103
	}
122
	
104
123
	
124
	/**
105
	/**
125
	 * Similar to initializeDescriptiveField(Widget), but the descriptive field
106
	 * Similar to initializeDescriptiveField(Widget), but the descriptive field is a comma-separated string of all the descriptive fields that
126
	 * is a comma-separated string of all the descriptive fields that corresponds
107
	 * corresponds to the objects passed in.
127
	 * to the objects passed in.
128
	 * 
108
	 * 
129
	 * @param objects The objects
109
	 * @param objects
110
	 *            The objects
130
	 */
111
	 */
131
	protected void findDescriptiveField(Object[] objects) 
112
	protected void findDescriptiveField(Object[] objects) {
132
	{
133
		String descriptive = "";
113
		String descriptive = "";
134
		for (int i = 0; i < objects.length; i++) 
114
		for (int i = 0; i < objects.length; i++) {
135
		{
136
			if (descriptive.length() > 0)
115
			if (descriptive.length() > 0)
137
				descriptive += ", ";
116
				descriptive += ", ";
138
			String textValue = getText(objects[i]);
117
			String textValue = getText(objects[i]);
139
			if (textValue != null && textValue.length() > 0)
118
			if (textValue != null && textValue.length() > 0)
140
				descriptive += textValue; 			
119
				descriptive += textValue;
141
		}
120
		}
142
		
121
143
		if (descriptive.length() > 0)
122
		if (descriptive.length() > 0)
144
			setDescriptiveField(descriptive);
123
			setDescriptiveField(descriptive);
145
	}
124
	}
146
	
125
147
	
148
	protected String getText(Object obj)
126
	protected String getText(Object obj)
149
	{
127
	{
150
		if (obj == null)
128
		if (obj == null)
Lines 168-188 Link Here
168
		return null;
146
		return null;
169
	}
147
	}
170
148
171
149
	public String toString() {
172
	public String toString()
173
	{
174
		return "MacroCommand [" + getType() + ", line " + getStartLine() + "]";
150
		return "MacroCommand [" + getType() + ", line " + getStartLine() + "]";
175
	}
151
	}
176
	
152
177
	public boolean equals (Object obj)
153
	public boolean equals(Object obj) {
178
	{
179
		if (!(obj instanceof IMacroCommand))
154
		if (!(obj instanceof IMacroCommand))
180
			return false;
155
			return false;
181
		
156
182
		IMacroCommand compareWithObj = (IMacroCommand)obj;
157
		IMacroCommand compareWithObj = (IMacroCommand) obj;
183
		if (compareWithObj.getType() == this.getType() && compareWithObj.getWidgetId() != null && compareWithObj.getWidgetId().equals(getWidgetId()))
158
		if (compareWithObj.getType() == this.getType())
184
			return true;
159
			return true;
185
		
160
186
		return false;
161
		return false;
187
	}
162
	}
188
163
Lines 193-297 Link Here
193
	public void setParent(MacroCommandShell parent) {
168
	public void setParent(MacroCommandShell parent) {
194
		this.parent = parent;
169
		this.parent = parent;
195
	}
170
	}
196
	
171
197
	/**
172
	/**
198
	 * Should return false if executing this command just after it 
173
	 * 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
199
	 * has already been executed will have a different output.  
174
	 * that are identical are redundant but two button selections are not)
200
	 * (e.g. If two focus commands that are identical are redundant but 
175
	 */
201
	 * two button selections are not)
176
	public boolean isRepeatRedundant() {
202
	 */ 
203
	public boolean isRepeatRedundant()
204
	{
205
		return true;
177
		return true;
206
	}
178
	}
207
	
179
208
	/**
180
	/**
209
	 * This is our chance to write any artificial wait commands if the 
181
	 * This is our chance to write any artificial wait commands if the option is enabled.
210
	 * option is enabled.
211
	 * 
182
	 * 
212
	 * @param indent The current indent that the command should be at
183
	 * @param indent
213
	 * @param writer The writer used to write the macro
184
	 *            The current indent that the command should be at
185
	 * @param writer
186
	 *            The writer used to write the macro
214
	 */
187
	 */
215
	public void writeStart(int indent, StringBuffer writer)
188
	public void writeStart(int indent, StringBuffer writer) {
216
	{
217
		if (timeDifference <= 0)
189
		if (timeDifference <= 0)
218
			return;
190
			return;
219
		
191
220
		WaitCommand waitCommand = new WaitCommand(parent);
192
		WaitCommand waitCommand = new WaitCommand(parent);
221
		waitCommand.setWaitTime(timeDifference);			
193
		waitCommand.setWaitTime(timeDifference);
222
		waitCommand.write(indent, writer);
194
		waitCommand.write(indent,
195
			writer);
223
	}
196
	}
224
225
	
197
	
226
	/**
198
	/**
199
	 * {@inheritDoc}
200
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable)
201
	 */
202
	public void load(Node node, Hashtable lineTable) throws CoreException {
203
		super.load(node,
204
			lineTable);
205
		// load the descriptive field
206
		descriptiveField = MacroUtil.getAttribute(node, MacroConstants.DESCRIPTIVE_ATTRIBUTE);
207
		
208
	}
209
210
	/**
227
	 * Equivalent to write(indent, writer, false, false)
211
	 * Equivalent to write(indent, writer, false, false)
228
	 */
212
	 */
229
	public void write(int indent, StringBuffer sb)
213
	public void write(int indent, StringBuffer sb) {
230
	{
214
		write(indent,
231
		write(indent, sb, false, false);
215
			sb,
216
			false,
217
			false);
232
	}
218
	}
233
	
219
234
	
235
	/**
220
	/**
236
	 * Writes the common fiels of this command
221
	 * Writes the common fiels of this command
237
	 * 
222
	 * 
238
	 * @param indent The current indent that the command should be at
223
	 * @param indent
239
	 * @param writer The writer used to write the macro
224
	 *            The current indent that the command should be at
240
	 * @param close A flag that indicates whether the command fragment should be closed (i.e.adding "/" to the end). 
225
	 * @param writer
241
	 * @param end A flag that indicates whether the command fragment should end (i.e.adding "/" to the end).
226
	 *            The writer used to write the macro
227
	 * @param close
228
	 *            A flag that indicates whether the command fragment should be closed (i.e.adding "/" to the end).
229
	 * @param end
230
	 *            A flag that indicates whether the command fragment should end (i.e.adding "/" to the end).
242
	 */
231
	 */
243
	public void write(int indent, StringBuffer sb, boolean close, boolean end)
232
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
244
	{
233
		MacroUtil.addElement(sb,
245
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false);		
234
			indent,
246
		boolean noWidgetId = getWidgetId() == null;
235
			MacroConstants.COMMAND_ELEMENT,
247
		boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn() && getWidgetId().getReferenceId() != null;
236
			false,
248
		MacroUtil.addAttribute(sb, 
237
			false);
249
			new String[] {			
238
		MacroUtil.addAttribute(sb,
250
				MacroConstants.DESCRIPTIVE_ATTRIBUTE,
251
				MacroConstants.TYPE_ATTRIBUTE, 
252
				MacroConstants.RESOLVER_ATTRIBUTE, 
253
				MacroConstants.CONTEXT_ID_ATTRIBUTE,
254
				MacroConstants.WIDGET_ID_ATTRIBUTE,
255
				MacroConstants.REFERENCE_ID_ATTRIBUTE}, 
256
			new String[] {
239
			new String[] {
257
				getDescriptiveField(),
240
				MacroConstants.DESCRIPTIVE_ATTRIBUTE,
258
				getType(),
241
				MacroConstants.TYPE_ATTRIBUTE},
259
				objectMineInUse || noWidgetId ? null : getWidgetId().getResolverId(),
242
			new String[] {getDescriptiveField(), getType()},
260
				objectMineInUse || noWidgetId ? null : getWidgetId().getContextId().toString(),
243
			close,
261
				objectMineInUse || noWidgetId ? null : getWidgetId().getObjectId().toString(),
244
			end);
262
				objectMineInUse && !noWidgetId ? getWidgetId().getReferenceId() : null
263
		}, close, end);
264
		
265
	}
245
	}
266
	
246
267
	
247
	public void writeFinish(int indent, StringBuffer writer) {
268
	public void writeFinish(int indent, StringBuffer writer)
248
269
	{
270
		
271
	}
249
	}
272
250
273
	public long getTimeDifference() 
251
	public long getTimeDifference() {
274
	{
275
		return timeDifference;
252
		return timeDifference;
276
	}
253
	}
277
254
278
	public void setTimeDifference(long timeDifference) 
255
	public void setTimeDifference(long timeDifference) {
279
	{
280
		this.timeDifference = timeDifference;
256
		this.timeDifference = timeDifference;
281
	}
257
	}
282
258
283
	
284
	
285
	/**
259
	/**
286
	 * Returns the class name of the object passed in (excluding the package name)
260
	 * Added by ANy
287
	 * This is useful for adding a descriptive field to the command
261
	 * 
262
	 * @param macroObject
263
	 */
264
	protected void setFocus(IMacroObject macroObject) {
265
		ensureVisible(macroObject);
266
		Widget widget = macroObject.getUIObject().getWidget();
267
		Display display = widget.getDisplay();
268
		if (widget instanceof Control) {
269
			Control c = (Control) widget;
270
			if (!c.equals(display.getFocusControl()))
271
				c.setFocus();
272
		}		
273
	}
274
275
	/*
276
	 * Added by ANy
277
	 */
278
	private void ensureVisible(IMacroObject macroObject) {
279
		if (macroObject.getContext() instanceof Window) {
280
			Window window = (Window) macroObject.getContext();
281
			window.getShell().setActive();
282
		}
283
		else if (macroObject.getContext() instanceof IEditorPart) {
284
			IEditorPart editor = (IEditorPart) macroObject.getContext();
285
			IWorkbenchPage page = editor.getEditorSite().getPage();
286
			page.activate(editor);
287
		}
288
		else if (macroObject.getContext() instanceof IViewPart) {
289
			IViewPart view = (IViewPart) macroObject.getContext();
290
			IWorkbenchPage page = view.getViewSite().getPage();
291
			page.activate(view);
292
		}
293
	}
294
295
	/**
296
	 * Returns the class name of the object passed in (excluding the package name) This is useful for adding a descriptive field to the command
288
	 * 
297
	 * 
289
	 * @param object The object
298
	 * @param object
299
	 *            The object
290
	 * @return The object class name
300
	 * @return The object class name
291
	 */
301
	 */
292
	protected String getObjectClassName (Object object)
302
	public String getObjectClassName(Object object) {
293
	{
303
		String className = object == null
294
		String className = object == null ? "" : object.getClass().getName();
304
			? ""
305
			: object.getClass().getName();
295
		int lastDotInx = className.lastIndexOf('.');
306
		int lastDotInx = className.lastIndexOf('.');
296
		if (lastDotInx != -1 && lastDotInx + 1 < className.length())
307
		if (lastDotInx != -1 && lastDotInx + 1 < className.length())
297
			return className.substring(lastDotInx + 1);
308
			return className.substring(lastDotInx + 1);
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ChoiceSelectionCommand.java (-258 / +335 lines)
Lines 1-259 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.Hashtable;
13
import java.util.Hashtable;
14
14
15
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.swt.SWT;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.swt.custom.CCombo;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.custom.CTabFolder;
19
import org.eclipse.swt.custom.CCombo;
20
import org.eclipse.swt.custom.CTabItem;
20
import org.eclipse.swt.custom.CTabFolder;
21
import org.eclipse.swt.widgets.Combo;
21
import org.eclipse.swt.custom.CTabItem;
22
import org.eclipse.swt.widgets.Composite;
22
import org.eclipse.swt.widgets.Combo;
23
import org.eclipse.swt.widgets.Display;
23
import org.eclipse.swt.widgets.Display;
24
import org.eclipse.swt.widgets.Event;
24
import org.eclipse.swt.widgets.Event;
25
import org.eclipse.swt.widgets.Item;
25
import org.eclipse.swt.widgets.Item;
26
import org.eclipse.swt.widgets.TabFolder;
26
import org.eclipse.swt.widgets.Shell;
27
import org.eclipse.swt.widgets.TabItem;
27
import org.eclipse.swt.widgets.TabFolder;
28
import org.eclipse.swt.widgets.Widget;
28
import org.eclipse.swt.widgets.TabItem;
29
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
29
import org.eclipse.swt.widgets.Widget;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
31
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
31
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
32
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
32
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
33
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
33
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject;
34
import org.w3c.dom.Node;
34
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
35
35
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
36
36
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
37
/**
37
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
38
 * A choice selection command represents a user selection of an item from
38
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
39
 * a set of items present.  For example, selecting a specific tab from a tab 
39
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
40
 * group or an item from a combo box.
40
import org.w3c.dom.Node;
41
 * 
41
42
 * @author Ali Mehregani
42
/**
43
 */
43
 * A choice selection command represents a user selection of an item from a set
44
public class ChoiceSelectionCommand extends AbstractMacroCommand
44
 * of items present. For example, selecting a specific tab from a tab group or
45
{
45
 * an item from a combo box.
46
	public static final String TYPE = "choice-select";
46
 * 
47
47
 * @author Ali Mehregani
48
	/** Widget types */
48
 * @author Alexander Nyssen (complete refactoring to use new widget resolving
49
	private static final byte WIDGET_TYPE_TAB_FOLDER = 0x00;
49
 *         mechanism)
50
	private static final byte WIDGET_TYPE_CTAB_FOLDER = 0x01;
50
 */
51
	private static final byte WIDGET_TYPE_COMBO = 0x02;
51
public class ChoiceSelectionCommand extends SingleSelectionCommand {
52
	private static final byte WIDGET_TYPE_CCOMBO = 0x03;	
52
53
	
53
	public static final String TYPE = IMacroCommand.CHOICE_SELECT;
54
	private Object choiceId;
54
55
55
	// ANy: this field is only needed for backwards compatibility issues
56
	public ChoiceSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid)
56
	private String choiceId = null;
57
	{
57
58
		super(parent, wid);
58
	// /** Widget types */
59
	}
59
	// private static final byte WIDGET_TYPE_TAB_FOLDER = 0x00;
60
60
	// private static final byte WIDGET_TYPE_CTAB_FOLDER = 0x01;
61
	public String getType()
61
	// private static final byte WIDGET_TYPE_COMBO = 0x02;
62
	{
62
	// private static final byte WIDGET_TYPE_CCOMBO = 0x03;
63
		return TYPE;
63
64
	}
64
	public ChoiceSelectionCommand(MacroCommandShell parent) {
65
65
		super(parent);
66
	public void processEvent(Event e)
66
	}
67
	{	
67
68
		choiceId = resolveChoiceId(e.widget, e.item, MacroUtil.newCounter());
68
	public String getType() {
69
		
69
		return TYPE;
70
		boolean isCombo = e.widget instanceof Combo;
70
	}
71
		boolean isCCombo = e.widget instanceof CCombo;
71
72
		
72
	protected IMacroObject locateMacroObject(Event event) {
73
		Combo combo = isCombo ? (Combo)e.widget : null;
73
		// find the selected item
74
		CCombo ccombo = isCCombo ? (CCombo)e.widget : null;
74
		boolean isCombo = event.widget instanceof Combo;
75
		Object item = isCombo ? combo.getItem(combo.getSelectionIndex()) : (isCCombo ? (Object)ccombo.getItem(ccombo.getSelectionIndex()) : e.item);
75
		boolean isCCombo = event.widget instanceof CCombo;
76
		
76
77
		choiceId = choiceId == null ? computeDefaultChoiceId(e.widget, item) : choiceId;
77
		Combo combo = isCombo ? (Combo) event.widget : null;
78
			
78
		CCombo ccombo = isCCombo ? (CCombo) event.widget : null;
79
		if (isCombo || isCCombo)
79
		Object item = isCombo ? combo.getItem(combo.getSelectionIndex())
80
		{
80
				: (isCCombo ? (Object) ccombo.getItem(ccombo
81
			setDescriptiveField(isCombo ? combo.getItem(combo.getSelectionIndex()) : ccombo.getItem(ccombo.getSelectionIndex()));
81
						.getSelectionIndex()) : event.item);
82
		}
82
83
		else
83
		// if the item is itself a widget it can be resolved without its parent
84
		{
84
		// widget, e.g. in case of a TabItem or CTabItem
85
			findDescriptiveField(e.item);
85
		if (item != null && item instanceof Widget) {
86
		}
86
			return new MacroObject(new UIObject((Widget) item));
87
	}
87
		} else {
88
88
			return new MacroObject(new UIObject(event.widget, item));
89
	private Object resolveChoiceId (Widget widget, Object item, int[] resolverIndex)
89
		}
90
	{		
90
	}
91
		return MacroManager.getInstance().resolveWidget(widget, item, getWidgetId().getResolverId(), resolverIndex); 
91
92
	}
92
	// @Override
93
	
93
	// protected void writeMacroObject(int indent, StringBuffer sb, boolean
94
	
94
	// close,
95
	private Object computeDefaultChoiceId(Widget widget, Object item)
95
	// boolean end) {
96
	{
96
	//		
97
		int index = -1;
97
	// // remove the trailing path fragment and store it separately (for
98
		boolean isCombo = widget instanceof Combo;
98
	// // backwards compatibility)
99
		boolean isCCombo = isCombo ? false : widget instanceof CCombo;		
99
	// MacroObjectIdentifier identifier = (MacroObjectIdentifier)
100
		if (isCombo || isCCombo)
100
	// getMacroObjectIdentifier();
101
		{
101
	// String originalContextId = identifier.getContextIdentifier();
102
			Combo combo = isCombo ? ((Combo)widget) : null;
102
	// String originalObjectId = identifier.getObjectIdentifier()
103
			CCombo ccombo = isCCombo ? ((CCombo)widget) : null;
103
	// .getObjectId();
104
			
104
	// String resolverId = identifier.getObjectIdentifier().getResolverId();
105
			index = isCombo ? combo.indexOf((String)item) : ccombo.indexOf((String)item);
105
	// String choiceId = new Path(originalObjectId).removeFirstSegments(1)
106
		}
106
	// .toString();
107
		else
107
	//		
108
		{	
108
	// setMacroObjectIdentifier(new MacroObjectIdentifier(originalContextId,
109
			boolean isTabFolder = widget instanceof TabFolder;
109
	// new PrimitiveUIObjectIdentifier(new Path(originalObjectId).segment(0)
110
			boolean isCTabFolder = isTabFolder ? false : widget instanceof CTabFolder;
110
	// .toString(), resolverId)));
111
			if (isTabFolder || isCTabFolder)
111
	//		
112
			{
112
	// super.writeMacroObject(indent, sb, false, false);
113
				index = isTabFolder ? ((TabFolder)widget).indexOf((TabItem)item) : ((CTabFolder)widget).indexOf((CTabItem)item);
113
	//		
114
			}
114
	// setMacroObjectIdentifier(identifier);
115
		}
115
	//
116
		
116
	// MacroUtil.addAttribute(sb,
117
		if (index != -1)
117
	// new String[] { MacroConstants.CHOICE_ID_ATTRIBUTE },
118
			return "item#" + index;
118
	// new String[] { choiceId == null || choiceId.equals("") ? null
119
		return null;
119
	// : choiceId.toString() }, close, end);
120
	}
120
	// }
121
121
122
	public void load(Node node, Hashtable lineTable) throws CoreException
122
	protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable)
123
	{
123
			throws CoreException {
124
		super.load(node, lineTable);
124
		super.loadMacroObjectIdentifier(node, lineTable);
125
		choiceId = MacroUtil.getAttribute(node, MacroConstants.CHOICE_ID_ATTRIBUTE);
125
126
	}
126
		// for backwards compatibility, the choice id is read (if present) and
127
127
		// appended to the macro object identifier
128
	public void write(int indent, StringBuffer sb)
128
		MacroObjectIdentifier identifier = (MacroObjectIdentifier) getMacroObjectIdentifier();
129
	{
129
130
		super.write(indent, sb);
130
		// ANy: added for backwards compatibility, in case we have a macro that
131
		MacroUtil.addAttribute(sb, 
131
		// still has the choice id attribute stored
132
				new String[] {MacroConstants.CHOICE_ID_ATTRIBUTE}, 
132
		choiceId = MacroUtil.getAttribute(node,
133
				new String[] {choiceId == null ? null : choiceId.toString()}, 
133
				MacroConstants.CHOICE_ID_ATTRIBUTE);
134
				true, true);
134
	}
135
	}
135
136
136
	public void doProcessEvent(Event e) {
137
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
137
		if (e.widget instanceof Combo || e.widget instanceof CCombo) {
138
	{
138
			setDescriptiveField(e.widget instanceof Combo ? ((Combo) e.widget)
139
		CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), getStartLine());
139
					.getItem(((Combo) e.widget).getSelectionIndex())
140
		if (targets == null)
140
					: ((CCombo) e.widget).getItem(((CCombo) e.widget)
141
			return false;
141
							.getSelectionIndex()));
142
		
142
		} else {
143
		CommandTarget target = targets[0];
143
			findDescriptiveField(e.item);
144
		target.setFocus();
144
		}
145
		Widget widget = target.getWidget();
145
	}
146
		if (widget instanceof TabFolder)
146
147
		{
147
	// public void load(Node node, Hashtable lineTable) throws CoreException {
148
			doSelect(WIDGET_TYPE_TAB_FOLDER, widget);
148
	// super.load(node, lineTable);
149
		}
149
	// String choiceId = MacroUtil.getAttribute(node,
150
		else if (widget instanceof CTabFolder)
150
	// MacroConstants.CHOICE_ID_ATTRIBUTE);
151
		{
151
	// }
152
			doSelect(WIDGET_TYPE_CTAB_FOLDER, widget);
152
	//
153
		}
153
154
		else if (widget instanceof Combo)
154
	// public void write(int indent, StringBuffer sb) {
155
		{
155
	// super.write(indent, sb);
156
			doSelect(WIDGET_TYPE_COMBO, widget);
156
	// MacroUtil.addAttribute(sb,
157
		}
157
	// new String[] { MacroConstants.CHOICE_ID_ATTRIBUTE },
158
		else if (widget instanceof CCombo)
158
	// new String[] { choiceId == null ? null : choiceId.toString() },
159
		{
159
	// true, true);
160
			doSelect(WIDGET_TYPE_CCOMBO, (CCombo) widget);
160
	// }
161
		}
161
162
		
162
	public boolean playback(Display display, Shell parent,
163
		return true;
163
			IProgressMonitor monitor) throws CoreException {
164
	}
164
		IMacroObjectIdentifier identifier = getMacroObjectIdentifier();
165
	
165
		// backwards compatibility issues
166
	
166
		if (choiceId != null && !choiceId.equals("")) {
167
	private void doSelect(byte widgetType, Widget widget)
167
			// we need to deresolve here to decide wether we have an identifier
168
	{
168
			// for a Combo (CCombo) or a TabFolder (CTabFolder)
169
		Object[] items = null;
169
			IMacroObject macroObject = MacroObjectResolver.deresolve(
170
		switch (widgetType)
170
					getParent().getShell(), identifier);
171
		{
171
			if (macroObject.getUIObject().getWidget() instanceof Combo
172
			case WIDGET_TYPE_TAB_FOLDER:
172
					|| macroObject.getUIObject().getWidget() instanceof CCombo) {
173
				items = ((TabFolder)widget).getItems();
173
				// set the enhanced identifier that used the object id to denote
174
				break;
174
				// the String item on the Combo or CCombo
175
			case WIDGET_TYPE_CTAB_FOLDER:
175
				setMacroObjectIdentifier(new MacroObjectIdentifier(identifier
176
				items = ((CTabFolder)widget).getItems();
176
						.getContextIdentifier(),
177
				break;
177
						new PrimitiveUIObjectIdentifier(identifier
178
			case WIDGET_TYPE_COMBO:
178
								.getObjectIdentifier().getWidgetId(), choiceId,
179
				items = ((Combo)widget).getItems();
179
								identifier.getObjectIdentifier()
180
				break;
180
										.getResolverId())));
181
			case WIDGET_TYPE_CCOMBO:
181
			} else if (macroObject.getUIObject().getWidget() instanceof TabFolder
182
				items = ((CCombo)widget).getItems();
182
					|| macroObject.getUIObject().getWidget() instanceof CTabFolder) {
183
				break;		
183
				// compute a new macro object identifier, the old one points to
184
		}
184
				// the tabFolder
185
				
185
				String contextId = new Path(MacroConstants.TAB_VALUE).append(
186
		Object widgetId = null;
186
						MacroObjectIdentifier
187
		int[] resolverIndex = MacroUtil.newCounter();
187
								.serializeMacroObjectIdentifier(identifier))
188
		boolean foundItem = false;
188
						.toString();
189
		for (int i = 0; !foundItem && i < items.length; i++)
189
				String widgetId = choiceId;
190
		{
190
				setMacroObjectIdentifier(new MacroObjectIdentifier(contextId,
191
			while (!foundItem && (widgetId = resolveChoiceId(widget, items[i], resolverIndex)) != null)
191
						new PrimitiveUIObjectIdentifier(widgetId, identifier
192
			{
192
								.getObjectIdentifier().getResolverId())));
193
				foundItem = foundItem (widgetType, widget, items[i], widgetId, i);
193
			}
194
			}	
194
		}
195
			
195
		return super.playback(display, parent, monitor);
196
			if (foundItem)
196
	}
197
				break;
197
198
			resolverIndex[0] = 0;
198
	public boolean doPlayback(Display display, Shell parent,
199
			foundItem = foundItem (widgetType, widget, items[i], computeDefaultChoiceId(widget, items[i]), i);
199
			IProgressMonitor monitor) throws CoreException {
200
		}
200
201
	}
201
		// deresolve the macro object (using the old path format (the choice id
202
202
		// was kept separately before) -> locating a child with the given item
203
	private boolean foundItem(byte widgetType, Widget widget, Object item, Object itemId, int index)
203
		// suffix does not work yet)
204
	{
204
		// Path path = new Path(getMacroObjectIdentifier().getObjectIdentifier()
205
		if (itemId != null && itemId.equals(choiceId))
205
		// .getObjectId());
206
		{
206
		// String oldObjectId = path.segmentCount() > 1 ?
207
			switch(widgetType)
207
		// path.removeLastSegments(
208
			{
208
		// 1).toString() : path.toString();
209
				case WIDGET_TYPE_TAB_FOLDER: 
209
210
					((TabFolder)widget).setSelection(index);
210
		// IMacroObject target = MacroObjectResolver.deresolve(parent,
211
					break;
211
		// getMacroObjectIdentifier());
212
				case WIDGET_TYPE_CTAB_FOLDER:
212
		// // new MacroObjectIdentifier(getMacroObjectIdentifier()
213
					((CTabFolder)widget).setSelection(index);
213
		// .getContextIdentifier(),
214
					break;
214
		// new PrimitiveUIObjectIdentifier(oldObjectId,
215
				case WIDGET_TYPE_COMBO:
215
		// getMacroObjectIdentifier()
216
					((Combo)widget).select(index);
216
		// .getObjectIdentifier()
217
					break;
217
		// .getResolverId())));
218
				case WIDGET_TYPE_CCOMBO:
218
219
					((CCombo)widget).select(index);
219
		if (macroObject == null) {
220
					break;
220
			return false;
221
			}
221
		}
222
				
222
223
			/* Ali M.: A set selection is not enough for Eclipse forms.  We have to send out a selection event */
223
		setFocus(macroObject);
224
			Event selectionEvent = new Event();
224
		doSelect(macroObject);
225
			selectionEvent.type = SWT.Selection;
225
226
			selectionEvent.widget = widget;
226
		return true;
227
			selectionEvent.display = widget.getDisplay();
227
	}
228
			selectionEvent.item = item instanceof Item ? (Item)item : null;
228
229
			widget.notifyListeners(SWT.Selection, selectionEvent);
229
	protected void doSelect(IMacroObject target) {
230
			MacroUtil.processDisplayEvents(selectionEvent.display);
230
		Widget widget = target.getUIObject().getWidget();
231
			
231
		Object object = target.getUIObject().getObject();
232
			return true;
232
233
		}				
233
		Widget parent = null;
234
		
234
		Item item = null;
235
		return false;
235
236
	}
236
		if (widget instanceof Combo) {
237
	
237
			Combo combo = (Combo) widget;
238
	
238
			combo.select(combo.indexOf((String) object));
239
	public boolean mergeEvent(Event e)
239
			parent = combo;
240
	{
240
		} else if (widget instanceof CCombo) {
241
		return false;
241
			CCombo combo = (CCombo) widget;
242
	}
242
			combo.select(combo.indexOf((String) object));
243
	
243
			parent = combo;
244
	/**
244
		}
245
	 * Overwrite this method in order to indicate that two choice commands that have
245
		// TabItems and CTabItems are widgets themselves, so when selecting,
246
	 * different choice ids are not the same
246
		// they have to be passed into the event as item
247
	 */
247
		else if (widget instanceof TabItem) {
248
	public boolean equals (Object obj)
248
			TabItem tabItem = (TabItem) widget;
249
	{
249
			TabFolder tabFolder = tabItem.getParent();
250
		if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj))
250
			tabFolder.setSelection(tabItem);
251
			return false;
251
			parent = tabFolder;
252
		
252
			item = tabItem;
253
		ChoiceSelectionCommand compareWithObj = (ChoiceSelectionCommand)obj;
253
		} else if (widget instanceof CTabItem) {
254
		if ((this.choiceId != null && this.choiceId.equals(compareWithObj.choiceId)) || (this.choiceId == null && compareWithObj.choiceId == null))
254
			CTabItem tabItem = (CTabItem) widget;
255
			return true;
255
			CTabFolder tabFolder = tabItem.getParent();
256
		
256
			tabFolder.setSelection(tabItem);
257
		return false;
257
			parent = tabFolder;
258
	}
258
			item = tabItem;
259
		}
260
261
		/*
262
		 * Ali M.: A set selection is not enough for Eclipse forms. We have to
263
		 * send out a selection event
264
		 */
265
		Event selectionEvent = new Event();
266
		selectionEvent.type = SWT.Selection;
267
		selectionEvent.widget = parent;
268
		selectionEvent.display = parent.getDisplay();
269
		selectionEvent.item = item;
270
		widget.notifyListeners(SWT.Selection, selectionEvent);
271
		MacroUtil.processDisplayEvents(selectionEvent.display);
272
	}
273
274
	// private void doSelect(byte widgetType, Widget widget) {
275
	// Object[] items = null;
276
	// switch (widgetType) {
277
	// case WIDGET_TYPE_TAB_FOLDER:
278
	// items = ((TabFolder) widget).getItems();
279
	// break;
280
	// case WIDGET_TYPE_CTAB_FOLDER:
281
	// items = ((CTabFolder) widget).getItems();
282
	// break;
283
	// case WIDGET_TYPE_COMBO:
284
	// items = ((Combo) widget).getItems();
285
	// break;
286
	// case WIDGET_TYPE_CCOMBO:
287
	// items = ((CCombo) widget).getItems();
288
	// break;
289
	// }
290
	//
291
	// // tries to determine the item by querying all resolves
292
	// IUIObjectIdentifier widgetId = null;
293
	// boolean foundItem = false;
294
	// for (int i = 0; !foundItem && i < items.length; i++) {
295
	// while (!foundItem
296
	// && ((widgetId = MacroObjectResolver.resolve(new MacroObject(new
297
	// UIObject(widget, items[i]))).getObjectIdentifier()) != null)) {
298
	// foundItem = itemId != null
299
	// && itemId.equals(getMacroObjectIdentifier()
300
	// .getObjectIdentifier())
301
	//					
302
	// }
303
	//
304
	// if (foundItem)
305
	// break;
306
	// // foundItem = foundItem(widgetType, widget, items[i],
307
	// // computeDefaultChoiceId(widget, items[i]), i);
308
	// }
309
	// }
310
311
	public boolean mergeEvent(Event e) throws Exception {
312
		return false;
313
	}
314
315
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
316
		super.write(indent, sb, true, true);
317
	}
318
319
	/**
320
	 * Overwrite this method in order to indicate that two choice commands that
321
	 * have different choice ids are not the same
322
	 */
323
	public boolean equals(Object obj) {
324
		if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj))
325
			return false;
326
327
		return true;
328
		// ChoiceSelectionCommand compareWithObj = (ChoiceSelectionCommand) obj;
329
		// if ((this.choiceId != null && this.choiceId
330
		// .equals(compareWithObj.choiceId))
331
		// || (this.choiceId == null && compareWithObj.choiceId == null))
332
		// return true;
333
		//
334
		// return false;
335
	}
259
}
336
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/EditorCommandTarget.java (-38 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import org.eclipse.swt.widgets.Widget;
14
import org.eclipse.ui.IEditorPart;
15
import org.eclipse.ui.IWorkbenchPage;
16
17
public class EditorCommandTarget extends CommandTarget {
18
	/**
19
	 * @param widget
20
	 * @param context
21
	 */
22
	public EditorCommandTarget(Widget widget, IEditorPart editor) {
23
		super(widget, editor);
24
	}
25
	
26
	public IEditorPart getEditor() {
27
		return (IEditorPart)getContext();
28
	}
29
30
	/* (non-Javadoc)
31
	 * @see org.eclipse.ui.macro.CommandTarget#ensureVisible()
32
	 */
33
	public void ensureVisible() {
34
		IEditorPart editor = getEditor();
35
		IWorkbenchPage page = editor.getEditorSite().getPage();
36
		page.activate(editor);
37
	}
38
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ToggleStructuredCommand.java (-99 / +99 lines)
Lines 1-99 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
15
16
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.swt.widgets.Event;
17
import org.eclipse.swt.widgets.Event;
18
import org.eclipse.swt.widgets.Widget;
18
import org.eclipse.swt.widgets.Widget;
19
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
22
import org.w3c.dom.Node;
22
import org.w3c.dom.Node;
23
23
24
public abstract class ToggleStructuredCommand extends AbstractStructuredCommand {
24
public abstract class ToggleStructuredCommand extends AbstractStructuredCommand {
25
	protected boolean itemState;
25
26
26
	protected boolean itemState;
27
	/**
27
28
	 * @param wid
28
	/**
29
	 */
29
	 * @param wid
30
	public ToggleStructuredCommand(MacroCommandShell parent, WidgetIdentifier wid) {
30
	 */
31
		super(parent, wid);
31
	public ToggleStructuredCommand(MacroCommandShell parent) {
32
	}
32
		super(parent);
33
	
33
	}
34
	
34
35
	/**
35
	/**
36
	 * There are more incomming events, merge them appropriately
36
	 * There are more incomming events, merge them appropriately
37
	 * 
37
	 * 
38
	 * @param e The event to be merged with this command
38
	 * @param e
39
	 */
39
	 *            The event to be merged with this command
40
	public boolean mergeEvent(Event e) 
40
	 */
41
	{
41
	public boolean mergeEvent(Event e) throws Exception {
42
		ArrayList itemMatches = super.getItems();
42
		ArrayList itemMatches = super.getItems();
43
		
43
44
		if (e.item != null && itemState == getItemState(e.item))
44
		if (e.item != null && itemState == getItemState(e.item)) {
45
		{
45
			itemMatches.add(super.getItemAttributes(e.item));
46
			itemMatches.add(super.getItemAttributes(e.item));
46
			return true;
47
			return true;
47
		}
48
		}
48
49
		
49
		return false;
50
		return false;
50
	}
51
	}
51
52
	
52
	public void load(Node node, Hashtable lineTable) throws CoreException {
53
	public void load(Node node, Hashtable lineTable) throws CoreException
53
		super.load(node,
54
	{
54
			lineTable);
55
		super.load(node, lineTable);
55
		String att = MacroUtil.getAttribute(node,
56
		String att = MacroUtil.getAttribute(node, MacroConstants.VALUE_ATTRIBUTE);
56
			MacroConstants.VALUE_ATTRIBUTE);
57
		this.itemState = att!=null && att.equals(MacroConstants.TRUE_VALUE);
57
		this.itemState = att != null && att.equals(MacroConstants.TRUE_VALUE);
58
	}
58
	}
59
	
59
60
	protected void writeAdditionalAttributes(StringBuffer sb) 
60
	protected void writeAdditionalAttributes(StringBuffer sb) {
61
	{
61
		MacroUtil.addAttribute(sb,
62
		MacroUtil.addAttribute(sb, 
62
			new String[] {MacroConstants.VALUE_ATTRIBUTE},
63
				new String[]{MacroConstants.VALUE_ATTRIBUTE}, 
63
			new String[] {itemState
64
				new String[]{itemState?MacroConstants.TRUE_VALUE:MacroConstants.FALSE_VALUE}, 
64
				? MacroConstants.TRUE_VALUE
65
				false, false);
65
				: MacroConstants.FALSE_VALUE},
66
	}
66
			false,
67
67
			false);
68
	
68
	}
69
	public boolean getValue() {
69
70
		return itemState;
70
	public boolean getValue() {
71
	}
71
		return itemState;
72
	
72
	}
73
	/**
73
74
	 * Overwirte this method to indicate that if there are two toggle commands
74
	/**
75
	 * with different values, then they are not the same.
75
	 * Overwirte this method to indicate that if there are two toggle commands with different values, then they are not the same.
76
	 * 
76
	 * 
77
	 * @param obj The object that this object will be comapred against
77
	 * @param obj
78
	 */
78
	 *            The object that this object will be comapred against
79
	public boolean equals (Object obj)
79
	 */
80
	{
80
	public boolean equals(Object obj) {
81
		if (!(obj instanceof ToggleStructuredCommand) || !super.equals(obj))
81
		if (!(obj instanceof ToggleStructuredCommand) || !super.equals(obj))
82
			return false;
82
			return false;
83
				
83
84
		ToggleStructuredCommand compareWithObj = (ToggleStructuredCommand)obj;
84
		ToggleStructuredCommand compareWithObj = (ToggleStructuredCommand) obj;
85
		if (compareWithObj.getValue() == this.getValue())
85
		if (compareWithObj.getValue() == this.getValue())
86
			return true;
86
			return true;
87
		
87
88
		return false;
88
		return false;
89
	}
89
	}
90
		
90
91
	/**
91
	/**
92
	 * Returns the state of the item (e.g. whether it is check/unchecked, expanded/
92
	 * Returns the state of the item (e.g. whether it is check/unchecked, expanded/ collapsed, and etc...)
93
	 * collapsed, and etc...)
93
	 * 
94
	 * 
94
	 * @param item
95
	 * @param item The item for which its state is being queried
95
	 *            The item for which its state is being queried
96
	 * @return The state of the item
96
	 * @return The state of the item
97
	 */
97
	 */
98
	public abstract boolean getItemState (Widget item);
98
	public abstract boolean getItemState(Widget item);
99
}
99
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/MouseEventCommand.java (-191 / +188 lines)
Lines 1-191 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: MouseEventCommand.java,v 1.2 2006/10/27 14:39:12 amehregani Exp $
7
 * $Id: MouseEventCommand.java,v 1.2 2006/10/27 14:39:12 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
13
14
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Hashtable;
15
16
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.graphics.Point;
20
import org.eclipse.swt.graphics.Point;
20
import org.eclipse.swt.widgets.Display;
21
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Event;
22
import org.eclipse.swt.widgets.Display;
22
import org.eclipse.swt.widgets.Shell;
23
import org.eclipse.swt.widgets.Event;
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
24
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
26
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
26
import org.eclipse.ui.PlatformUI;
27
import org.eclipse.ui.PlatformUI;
27
import org.w3c.dom.Node;
28
import org.w3c.dom.Node;
28
29
29
/**
30
/**
30
 * A concrete extension of PositionBasedCommand used to represent SWT.MouseUp
31
 * A concrete extension of PositionBasedCommand used to represent SWT.MouseUp and SWT.MouseDown
31
 * and SWT.MouseDown and SWT.MouseMove events.
32
 * events.
32
 * 
33
 * 
33
 * @author Ali Mehregani
34
 * @author Ali Mehregani
34
 * @author Alexander Nyssen (refactored and added mouse move event support)
35
 */
35
 */
36
public class MouseEventCommand extends PositionBasedCommand 
36
public class MouseEventCommand extends PositionBasedCommand {
37
{
37
38
	public static final String TYPE0 = "mouse-up";
38
	private Point coordinates; /* Keep track of the coordinates */
39
	public static final String TYPE1 = "mouse-down";
39
40
	public static final String TYPE2 = "mouse-click";
40
	private static Point lastCoordinates;
41
	
41
42
	private String type;			/* The type of this command (either TYPE0 or TYPE1) */
42
	public MouseEventCommand(MacroCommandShell parent) {
43
	private int button;				/* The mouse button that was pressed or released */
43
		super(parent);
44
	private Point coordinates;		/* Keep track of the coordinates */
44
	}
45
	
45
46
	private static Point lastCoordinates;
46
	public void processEvent(Event event) throws Exception {
47
	
47
		super.processEvent(event);
48
	public MouseEventCommand(MacroCommandShell parent) 
48
		coordinates = PlatformUI.getWorkbench().getDisplay()
49
	{
49
				.getCursorLocation();
50
		super(parent, WidgetIdentifier.NULL_IDENTIFIER);		
50
	}
51
	}
51
52
52
	protected String determineType(Event e) {
53
	public String getType() 
53
		String type = null;
54
	{
54
		if (e.type == SWT.MouseUp) {
55
		return type;
55
			type = MOUSE_UP;
56
	}
56
		} else if (e.type == SWT.MouseDown) {
57
57
			type = MOUSE_DOWN;
58
	public void processEvent(Event e) 
58
		} else if (e.type == SWT.MouseMove) {
59
	{
59
			type = MOUSE_MOVE;
60
		coordinates = PlatformUI.getWorkbench().getDisplay().getCursorLocation();
60
		}
61
		button = e.button;
61
		return type;
62
		
62
	}
63
		if (e.type == SWT.MouseUp)
63
64
		{
64
	protected Integer determineDetail(Event e) {
65
			/* Defect #: 110726 -- If the previous event was a mouse down event at the same
65
		if (e.button > 0) {
66
			 * exact location, then replace the two of them with the mouse click event */
66
			return new Integer(e.button);
67
			ArrayList commands = getParent().getCommands();
67
		} else {
68
			int commandSize;
68
			return null;
69
			if (commands != null && (commandSize = commands.size()) > 0)
69
		}
70
			{
70
	}
71
				Object lastCommand = commands.get(commandSize - 1);
71
72
				if (lastCommand instanceof MouseEventCommand)
72
	public boolean mergeEvent(Event e) throws Exception {
73
				{
73
		/*
74
					Point lastCommandCoordinates = ((MouseEventCommand)lastCommand).getCoordinates();
74
		 * Defect #: 110726 -- If the previous event was a mouse down event at
75
					if (lastCommandCoordinates.equals(coordinates))
75
		 * the same exact location, then replace the two of them with the mouse
76
					{
76
		 * click event (ANy: As merging of position based commands is now
77
						type = TYPE2;
77
		 * supported, this defect can be handled here more elegantly)
78
						commands.remove(commandSize - 1);
78
		 */
79
						return;
79
		if (e.type == SWT.MouseUp
80
					}
80
				&& type != null
81
				}				
81
				&& type.equals(MOUSE_DOWN)
82
			}
82
				&& coordinates != null
83
			
83
				&& coordinates.equals(PlatformUI.getWorkbench().getDisplay()
84
			type = TYPE0;
84
						.getCursorLocation())
85
		}
85
				&& (detail == null || detail.intValue() == e.button)) {
86
		else if (e.type == SWT.MouseDown)
86
			type = MOUSE_CLICK;
87
			type = TYPE1;		
87
			return true;
88
	}
88
		}
89
89
		// if the last command was a mouse move command, and this one as well,
90
	public int getDetail() 
90
		// the
91
	{
91
		// last may be ignored.
92
		return button;
92
		else if (e.type == SWT.MouseMove && type != null
93
	}
93
				&& type.equals(MOUSE_MOVE)) {
94
94
			coordinates = PlatformUI.getWorkbench().getDisplay()
95
	public Event[] constructSWTEvents()
95
					.getCursorLocation();
96
	{
96
			return true;
97
		Event[] mouseEvents;
97
		} else {
98
		if (type.equals(TYPE2))
98
			return super.mergeEvent(e);
99
			mouseEvents = new Event[2];
99
		}
100
		else
100
	}
101
			mouseEvents = new Event[1];
101
102
		
102
	public Event[] constructSWTEvents() {
103
		Event mouseUpEvent 	= new Event(), 
103
		Event[] mouseEvents;
104
			  mouseDownEvent= new Event();
104
		if (type.equals(MOUSE_CLICK))
105
		
105
			mouseEvents = new Event[2];
106
		mouseUpEvent.type = SWT.MouseUp;
106
		else
107
		mouseDownEvent.type = SWT.MouseDown;
107
			mouseEvents = new Event[1];
108
		
108
109
		mouseUpEvent.button = button;
109
		if (type.equals(MOUSE_UP)) {
110
		mouseDownEvent.button = button;
110
			mouseEvents[0] = new Event();
111
		
111
			mouseEvents[0].type = SWT.MouseUp;
112
		if (type.equals(TYPE0))
112
			mouseEvents[0].button = detail.intValue();
113
			mouseEvents[0] = mouseUpEvent;
113
		} else if (type.equals(MOUSE_DOWN)) {
114
		
114
			mouseEvents[0] = new Event();
115
		else if (type.equals(TYPE1))
115
			mouseEvents[0].type = SWT.MouseDown;
116
			mouseEvents[0] = mouseDownEvent;
116
			mouseEvents[0].button = detail.intValue();
117
		
117
		} else if (type.equals(MOUSE_CLICK)) {
118
		else if (type.equals(TYPE2))
118
			mouseEvents[0] = new Event();
119
		{
119
			mouseEvents[0].type = SWT.MouseDown;
120
			mouseEvents[0] = mouseDownEvent;
120
			mouseEvents[0].button = detail.intValue();
121
			mouseEvents[1] = mouseUpEvent;
121
			mouseEvents[1] = new Event();
122
		}
122
			mouseEvents[1].type = SWT.MouseUp;
123
				
123
			mouseEvents[1].button = detail.intValue();
124
		return mouseEvents;
124
		} else if (type.equals(MOUSE_MOVE)) {
125
	}
125
			mouseEvents[0] = new Event();
126
	
126
			mouseEvents[0].type = SWT.MouseMove;
127
127
			mouseEvents[0].x = coordinates.x;
128
	public void load(Node node, Hashtable lineTable) throws CoreException 
128
			mouseEvents[0].y = coordinates.y;
129
	{
129
		}
130
		super.load(node, lineTable);
130
131
		
131
		return mouseEvents;
132
		type = MacroUtil.getAttribute(node, "type");
132
	}
133
		int x = Integer.parseInt(MacroUtil.getAttribute(node, "x-coord"));
133
134
		int y = Integer.parseInt(MacroUtil.getAttribute(node, "y-coord"));
134
	public void load(Node node, Hashtable lineTable) throws CoreException {
135
		button = Integer.parseInt(MacroUtil.getAttribute(node, "detail"));		
135
		super.load(node, lineTable);
136
		coordinates = new Point (x, y);
136
137
	}
137
		// load coordinates
138
	
138
		int x = Integer.parseInt(MacroUtil.getAttribute(node, "x-coord"));
139
	public void write(int indent, StringBuffer sb, boolean close, boolean end)
139
		int y = Integer.parseInt(MacroUtil.getAttribute(node, "y-coord"));
140
	{
140
		coordinates = new Point(x, y);
141
		super.write(indent, sb, close, end);
141
	}
142
		MacroUtil.addAttribute(sb, 
142
143
				new String[] {			
143
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
144
					MacroConstants.X_COORD_ATTRIBUTE,
144
		super.write(indent, sb, false, false);
145
					MacroConstants.Y_COORD_ATTRIBUTE, 
145
		MacroUtil.addAttribute(sb, new String[] {
146
				}, 
146
				MacroConstants.X_COORD_ATTRIBUTE,
147
				new String[] {
147
				MacroConstants.Y_COORD_ATTRIBUTE, },
148
					String.valueOf(coordinates.x),
148
				new String[] { String.valueOf(coordinates.x),
149
					String.valueOf(coordinates.y),
149
						String.valueOf(coordinates.y), }, true, true);
150
				}
150
	}
151
		, true, true);
151
152
	}
152
	/**
153
	
153
	 * Plays back this command
154
	/**
154
	 */
155
	 * Plays back this command
155
	public boolean playback(final Display display, Shell parent,
156
	 */
156
			IProgressMonitor monitor) throws CoreException {
157
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException 
157
		/*
158
	{		
158
		 * It's important not to move the cursor if the last command had the
159
		/* It's important not to move the cursor if the last command had the same cursor position as this one */
159
		 * same cursor position as this one
160
		if (lastCoordinates == null || !lastCoordinates.equals(coordinates))
160
		 */
161
		{
161
		if (lastCoordinates == null || !lastCoordinates.equals(coordinates)) {
162
			display.setCursorLocation(coordinates.x, coordinates.y);
162
			display.setCursorLocation(coordinates.x, coordinates.y);
163
		}
163
		}
164
		lastCoordinates = coordinates;
164
		lastCoordinates = coordinates;
165
		return super.playback(display, parent, monitor);
165
		return super.playback(display, parent, monitor);
166
	}
166
	}
167
	
167
168
	public boolean equals (Object obj)
168
	public boolean equals(Object obj) {
169
	{
169
		if (!(obj instanceof MouseEventCommand))
170
		if (!(obj instanceof MouseEventCommand))
170
			return false;
171
			return false;
171
172
		
172
		MouseEventCommand mouseEvent = (MouseEventCommand) obj;
173
		MouseEventCommand mouseEvent = (MouseEventCommand)obj;
173
		if (this.type.equals(mouseEvent.getType())
174
		if (this.type.equals(mouseEvent.getType()) && this.button == mouseEvent.getButton() && this.coordinates.equals(mouseEvent.getCoordinates()))
174
				&& this.detail == mouseEvent.getDetail()
175
			return true;
175
				&& this.coordinates.equals(mouseEvent.getCoordinates()))
176
		return false;
176
			return true;
177
	}
177
		return false;
178
178
	}
179
	public Point getCoordinates() {
179
180
		return coordinates;
180
	public Point getCoordinates() {
181
	}
181
		return coordinates;
182
182
	}
183
	public int getButton() {
183
184
		return button;
184
	// TODO: This is ugly, it has to be removed
185
	}
185
	public static void init() {
186
186
		lastCoordinates = null;
187
	public static void init()
187
	}
188
	{
188
}
189
		lastCoordinates = null;
190
	}
191
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/IMacroCommand.java (-101 / +121 lines)
Lines 1-101 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
2
 * Copyright (c) 2006, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import org.eclipse.swt.widgets.Event;
13
import org.eclipse.swt.widgets.Event;
14
import org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction;
14
import org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction;
15
15
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
16
16
17
/**
17
/**
18
 * Represents a macro command that can be included as part of the
18
 * Represents a macro command that can be included as part of the macro script
19
 * macro script or played back to perform a UI interaction. 
19
 * or played back to perform a UI interaction.
20
 * 
20
 * 
21
 * @author Ali Mehregani
21
 * @author Ali Mehregani
22
 */
22
 * @author Alexander Nyssen
23
public interface IMacroCommand extends IMacroInstruction
23
 */
24
{	
24
public interface IMacroCommand extends IMacroInstruction {
25
	/**
25
	/* command type constants */
26
	 * Returns the type of this command
26
	public static final String VERIFICATION = "verification";
27
	 *  
27
	public static final String WAIT = "wait";
28
	 * @return The type
28
	public static final String MODIFY = "modify";
29
	 */
29
	public static final String SELECT = "select";
30
	public String getType();
30
	public static final String ITEM_CHECK = "item-check";
31
	
31
	public static final String CHOICE_SELECT = "choice-select";
32
	
32
	public static final String CLOSE_WORKBENCHPART = "close-workbenchpart";
33
	/**
33
	public static final String ITEM_EXPAND = "item-expand";
34
	 * Allows this command to process the corresponding event. 
34
	public static final String FOCUS = "focus";
35
	 * 
35
	public static final String KEY_UP = "key-up";
36
	 * @param event The event that awaits processing
36
	public static final String KEY_DOWN = "key-down";
37
	 */
37
	public static final String KEY_PRESS = "key-press";
38
	public void processEvent(Event event);
38
	public static final String MOUSE_UP = "mouse-up";
39
	
39
	public static final String MOUSE_DOWN = "mouse-down";
40
	
40
	public static final String MOUSE_MOVE = "mouse-move";
41
	/**
41
	public static final String MOUSE_CLICK = "mouse-click";
42
	 * If this command occurs consecutively, then this method
42
	public static final String DEFAULT_SELECT = "default-select";
43
	 * gives this command a chance to merge mutliple commands
43
	public static final String ITEM_SELECT = "item-select";
44
	 * together to reduce the overhead.
44
45
	 * 
45
	/** The bound for the value of descriptive fields */
46
	 * @param event The event that caused the creation of a consecutive
46
	public static final int DESCRIPTIVE_FIELD_BOUND = 50;
47
	 * command of this type.
47
48
	 * 
48
	/**
49
	 * @return true if the command is merged; false otherwise.
49
	 * Returns the type of this command
50
	 */
50
	 * 
51
	public boolean mergeEvent(Event e);
51
	 * @return The type
52
	
52
	 */
53
	
53
	public String getType();
54
	/**
54
55
	 * Returns the descriptive field of this command.  The descriptive field
55
	/**
56
	 * is a human readable label that allows users to easily identify the 
56
	 * Allows this command to process the corresponding event.
57
	 * purpose of this command.
57
	 * 
58
	 * 
58
	 * @param event
59
	 * @return The descriptive field
59
	 *            The event that awaits processing
60
	 */
60
	 */
61
	public String getDescriptiveField();
61
	public void processEvent(Event event) throws Exception;
62
	
62
63
	
63
	/**
64
	/**
64
	 * If this command occurs consecutively, then this method gives this command
65
	 * Sets the descriptive field of this command.  The descriptive field
65
	 * a chance to merge mutliple commands together to reduce the overhead.
66
	 * is a human readable label that allows users to easily identify the 
66
	 * 
67
	 * purpose of this command.
67
	 * @param event
68
	 * 
68
	 *            The event that caused the creation of a consecutive command of
69
	 * @param descriptiveField The descriptive field
69
	 *            this type.
70
	 */
70
	 * 
71
	public void setDescriptiveField(String descriptiveField);
71
	 * @return true if the command is merged; false otherwise.
72
	
72
	 * @throws Exception
73
	
73
	 *             TODO
74
	/**
74
	 */
75
	 * Returns the parent of this command.
75
	public boolean mergeEvent(Event e) throws Exception;
76
	 * 
76
77
	 * @return The parent
77
	/**
78
	 */
78
	 * Returns the descriptive field of this command. The descriptive field is a
79
	public MacroCommandShell getParent();
79
	 * human readable label that allows users to easily identify the purpose of
80
	
80
	 * this command.
81
	
81
	 * 
82
	/**
82
	 * @return The descriptive field
83
	 * Sets the parent of this command.
83
	 */
84
	 * 
84
	public String getDescriptiveField();
85
	 * @param parent The parent 
85
86
	 */
86
	/**
87
	public void setParent(MacroCommandShell parent);
87
	 * Sets the descriptive field of this command. The descriptive field is a
88
	
88
	 * human readable label that allows users to easily identify the purpose of
89
	
89
	 * this command.
90
	/**
90
	 * 
91
	 * Returns false if executing this command just after it has already been executed 
91
	 * @param descriptiveField
92
	 * will have a different output.  (e.g. Two focus commands that are identical are 
92
	 *            The descriptive field
93
	 * redundant but two button selections are not); otherwise true should be returned.
93
	 */
94
	 * 
94
	public void setDescriptiveField(String descriptiveField);
95
	 * @return A flag indicating if repeats of this command are redundant.
95
96
	 */ 
96
	/**
97
	public boolean isRepeatRedundant();
97
	 * Returns the parent of this command.
98
98
	 * 
99
}
99
	 * @return The parent
100
100
	 */
101
101
	public MacroCommandShell getParent();
102
103
	/**
104
	 * Sets the parent of this command.
105
	 * 
106
	 * @param parent
107
	 *            The parent
108
	 */
109
	public void setParent(MacroCommandShell parent);
110
111
	/**
112
	 * Returns false if executing this command just after it has already been
113
	 * executed will have a different output. (e.g. Two focus commands that are
114
	 * identical are redundant but two button selections are not); otherwise
115
	 * true should be returned.
116
	 * 
117
	 * @return A flag indicating if repeats of this command are redundant.
118
	 */
119
	public boolean isRepeatRedundant();
120
121
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/CheckCommand.java (-106 / +103 lines)
Lines 1-107 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import org.eclipse.swt.SWT;
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.widgets.Event;
14
import org.eclipse.swt.widgets.Event;
15
import org.eclipse.swt.widgets.Table;
15
import org.eclipse.swt.widgets.Table;
16
import org.eclipse.swt.widgets.TableItem;
16
import org.eclipse.swt.widgets.TableItem;
17
import org.eclipse.swt.widgets.Tree;
17
import org.eclipse.swt.widgets.Tree;
18
import org.eclipse.swt.widgets.TreeItem;
18
import org.eclipse.swt.widgets.TreeItem;
19
import org.eclipse.swt.widgets.Widget;
19
import org.eclipse.swt.widgets.Widget;
20
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
22
22
23
public class CheckCommand extends ToggleStructuredCommand 
23
public class CheckCommand extends ToggleStructuredCommand {
24
{
24
25
	public static final String TYPE = "item-check";
25
	public static final String TYPE = IMacroCommand.ITEM_CHECK;
26
	/**
26
27
	 * @param wid
27
	/**
28
	 */
28
	 * @param wid
29
	public CheckCommand(MacroCommandShell parent, WidgetIdentifier wid) {
29
	 */
30
		super(parent, wid);
30
	public CheckCommand(MacroCommandShell parent) {
31
	}
31
		super(parent);
32
	
32
	}
33
	public String getType() {
33
34
		return TYPE;
34
	public String getType() {
35
	}
35
		return TYPE;
36
	
36
	}
37
	public void processEvent(Event event) 
37
38
	{
38
	public void doProcessEvent(Event event) {
39
		super.processEvent(event);
39
		super.doProcessEvent(event);
40
		Widget item = event.item;
40
		
41
		itemState = getItemState (item);
41
		Widget item = event.item;
42
	}
42
		itemState = getItemState(item);
43
	
43
	}
44
	public boolean getItemState(Widget item)
44
45
	{		
45
	public boolean getItemState(Widget item) {
46
		if (item instanceof TreeItem)
46
		if (item instanceof TreeItem)
47
			return ((TreeItem)item).getChecked();
47
			return ((TreeItem) item).getChecked();
48
		else if (item instanceof TableItem)
48
		else if (item instanceof TableItem)
49
			return ((TableItem)item).getChecked();
49
			return ((TableItem) item).getChecked();
50
		
50
51
		return false;
51
		return false;
52
	}
52
	}
53
	
53
54
	protected void playStructuredCommand(Widget widget, Object[] matches) 
54
	protected void playStructuredCommand(Widget widget, Object[] matches) {
55
	{
55
		boolean isTree = widget instanceof Tree;
56
		boolean isTree = widget instanceof Tree;
56
		boolean isTable = false;
57
		boolean isTable = false;
57
		if (!isTree)
58
		if (!isTree)
58
			isTable = widget instanceof Table;
59
			isTable = widget instanceof Table;
59
60
		
60
		if (!isTree && !isTable)
61
		if (!isTree && !isTable)
61
			return;
62
			return;
62
63
		
63
		Event selectionEvent = null;
64
		Event selectionEvent = null;
64
65
		
65
		for (int i = 0; i < matches.length; i++) {
66
		for (int i=0; i<matches.length; i++) 
66
			selectionEvent = constructSelectionEvent(widget);
67
		{
67
68
			selectionEvent = constructSelectionEvent(widget);
68
			if ((widget.getStyle() & SWT.CHECK) != 0)
69
			
69
				selectionEvent.detail = SWT.CHECK;
70
			if ((widget.getStyle() & SWT.CHECK) != 0)
70
			selectionEvent.item = (Widget) matches[i];
71
				selectionEvent.detail = SWT.CHECK;
71
72
			selectionEvent.item = (Widget)matches[i];
72
			if (isTree)
73
			
73
				((TreeItem) matches[i]).setChecked(getValue());
74
			if (isTree)
74
			else
75
				((TreeItem)matches[i]).setChecked(getValue());
75
				((TableItem) matches[i]).setChecked(getValue());
76
			else
76
77
				((TableItem)matches[i]).setChecked(getValue());
77
			/* Send the selection event */
78
			
78
			widget.notifyListeners(SWT.Selection,
79
			/* Send the selection event */
79
				selectionEvent);
80
			widget.notifyListeners(SWT.Selection, selectionEvent);
80
			MacroUtil.processDisplayEvents(widget.getDisplay());
81
			MacroUtil.processDisplayEvents(widget.getDisplay());
81
		}
82
		}
82
83
		
83
	}
84
	}
84
85
	
85
	/**
86
	/**
86
	 * Clients will often expect a selection event to be sent. This helper method is used to construct a selection event.
87
	 * Clients will often expect a selection event to be sent.
87
	 * 
88
	 * This helper method is used to construct a selection event.
88
	 * @param widget
89
	 * 
89
	 *            The widget that will be used to send out the event.
90
	 * @param widget The widget that will be used to send out the event.
90
	 * @return The event.
91
	 * @return The event. 
91
	 */
92
	 */
92
	private Event constructSelectionEvent(Widget widget) {
93
	private Event constructSelectionEvent(Widget widget)
93
		Event event = new Event();
94
	{
94
		event.display = widget.getDisplay();
95
		Event event = new Event();
95
		event.widget = widget;
96
		event.display = widget.getDisplay();
96
		event.type = SWT.Selection;
97
		event.widget = widget;
97
		return event;
98
		event.type = SWT.Selection;		
98
	}
99
		return event;
99
100
	}
100
	protected void playStructuredCommandForFoundMatch(Widget widget, Object match) {
101
101
		/* Deosn't need to be implemented */
102
	protected void playStructuredCommandForFoundMatch(Widget widget, Object match) 
102
	}
103
	{
103
104
		/* Deosn't need to be implemented */
105
	}
106
107
}
104
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/BooleanSelectionCommand.java (-599 / +596 lines)
Lines 1-600 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
15
16
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.jface.action.ActionContributionItem;
18
import org.eclipse.jface.action.ActionContributionItem;
19
import org.eclipse.jface.action.ContributionItem;
19
import org.eclipse.jface.action.ContributionItem;
20
import org.eclipse.jface.action.IMenuCreator;
20
import org.eclipse.jface.action.IMenuCreator;
21
import org.eclipse.jface.action.MenuManager;
21
import org.eclipse.jface.action.MenuManager;
22
import org.eclipse.osgi.util.NLS;
22
import org.eclipse.osgi.util.NLS;
23
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.graphics.Point;
24
import org.eclipse.swt.graphics.Point;
25
import org.eclipse.swt.widgets.Button;
25
import org.eclipse.swt.widgets.Button;
26
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Menu;
30
import org.eclipse.swt.widgets.Menu;
30
import org.eclipse.swt.widgets.MenuItem;
31
import org.eclipse.swt.widgets.MenuItem;
31
import org.eclipse.swt.widgets.Shell;
32
import org.eclipse.swt.widgets.ToolItem;
32
import org.eclipse.swt.widgets.ToolItem;
33
import org.eclipse.swt.widgets.Widget;
33
import org.eclipse.swt.widgets.Widget;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
35
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
35
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
36
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
36
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
37
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
38
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
39
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
40
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
41
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
42
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
42
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
43
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
43
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
44
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
44
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
45
import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject;
45
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
46
import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId;
46
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
47
import org.w3c.dom.Node;
47
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver;
48
import org.w3c.dom.NodeList;
48
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport;
49
49
import org.w3c.dom.Node;
50
50
import org.w3c.dom.NodeList;
51
/**
51
52
 * Represents the select command (e.g. button, check box, radio button, and 
52
/**
53
 * etc... selections)
53
 * Represents the select command (e.g. button, check box, radio button, and
54
 * 
54
 * etc... selections)
55
 * @author Ali Mehregani
55
 * 
56
 */
56
 * @author Ali Mehregani
57
public class BooleanSelectionCommand extends AbstractMacroCommand
57
 * @author Alexander Nyssen
58
{
58
 */
59
	public static final String TYPE = "select";
59
public class BooleanSelectionCommand extends SingleSelectionCommand {
60
60
61
	private Boolean selection;
61
	public static final String TYPE = IMacroCommand.SELECT;
62
62
63
	private ArrayList path;
63
	private Boolean selection;
64
64
65
	/* Indicates the cursor location relative to the tool bar item (the value is non-zero
65
	/*
66
	 * if the toolbar item is dropped down */
66
	 * Indicates the cursor location relative to the tool bar item (the value is
67
	private Point toolBarLocation;
67
	 * non-zero if the toolbar item is dropped down
68
68
	 */
69
	/* The detail of the event as described in the SWT class */
69
	private Point toolBarLocation;
70
	private int detail;
70
71
	
71
	/* The detail of the event as described in the SWT class */
72
	/* If an item is selected from a drop down menu, then this points to the id of the item */
72
	private int detail;
73
	private IWidgetId itemSelectedId;
73
74
74
	/*
75
	/* The refrence id of the selected item that points to an object in an object mine */
75
	 * If an item is selected from a drop down menu, then this points to the id
76
	private String itemSelectedRefId;
76
	 * of the item
77
	
77
	 */
78
	/* This listener is used to get a reference to a drop-down menu */
78
	private IUIObjectIdentifier itemSelectedIdentifier;
79
	private DropDownMenuListener dropDownMenuListener;
79
80
	
80
	/*
81
	/* Reference to a drop-down menu */
81
	 * The refrence id of the selected item that points to an object in an
82
	private Menu dropDownMenu;
82
	 * object mine
83
83
	 */
84
	/* Indicates whether we're waiting for a drop down menu item */
84
	private String itemSelectedRefId;
85
	private boolean menuIsNeeded;
85
86
	
86
	/* This listener is used to get a reference to a drop-down menu */
87
	/**
87
	private DropDownMenuListener dropDownMenuListener;
88
	 * The toolBarLocation argument is needed when the toolbar item is a drop down.
88
89
	 * 
89
	/* Reference to a drop-down menu */
90
	 * @param wid The widget identifier.
90
	private Menu dropDownMenu;
91
	 * @param toolBarLocation The cursor location
91
92
	 * @param detail The detail of the event as described by the SWT class
92
	/* Indicates whether we're waiting for a drop down menu item */
93
	 */
93
	private boolean menuIsNeeded;
94
	public BooleanSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid, Point toolBarLocation, int detail)
94
95
	{
95
	public BooleanSelectionCommand(MacroCommandShell parent) {
96
		super(parent, wid);
96
		super(parent);
97
		this.toolBarLocation = toolBarLocation;
97
	}
98
		this.detail = detail;			
98
99
	}
99
	public String getType() {
100
100
		return TYPE;
101
	public BooleanSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid)
101
	}
102
	{
102
103
		super(parent, wid);
103
	public void doProcessEvent(Event event) {
104
		this.detail = -10;		
104
		if (event.x != 0 || event.y != 0 || event.detail != 0) {
105
	}
105
			this.toolBarLocation = new Point(event.x, event.y);
106
106
			this.detail = event.detail;
107
	public String getType()
107
		} else {
108
	{
108
			this.detail = -10;
109
		return TYPE;
109
		}
110
	}
110
111
111
		selection = getSelection(event.widget);
112
	public void processEvent(Event e)
112
113
	{
113
		findDescriptiveField(event.widget);
114
		selection = getSelection(e.widget);
114
	}
115
		if (e.widget instanceof MenuItem)
115
116
		{
116
	private Boolean getSelection(Widget widget) {
117
			path = getPath((MenuItem) e.widget);
117
		if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0)
118
		}
118
			return null;
119
		
119
		if (widget instanceof Button)
120
		findDescriptiveField(e.widget);
120
			return new Boolean(((Button) widget).getSelection());
121
	}
121
		if (widget instanceof ToolItem)
122
122
			return new Boolean(((ToolItem) widget).getSelection());
123
	private Boolean getSelection(Widget widget)
123
		if (widget instanceof MenuItem)
124
	{
124
			return new Boolean(((MenuItem) widget).getSelection());
125
		if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0)
125
		return null;
126
			return null;
126
	}
127
		if (widget instanceof Button)
127
128
			return new Boolean(((Button) widget).getSelection());
128
	public void load(Node node, Hashtable lineTable) throws CoreException {
129
		if (widget instanceof ToolItem)
129
		super.load(node, lineTable);
130
			return new Boolean(((ToolItem) widget).getSelection());
130
		String sel = MacroUtil.getAttribute(node,
131
		if (widget instanceof MenuItem)
131
				MacroConstants.SELECTION_ATTRIBUTE);
132
			return new Boolean(((MenuItem) widget).getSelection());
132
		String xCoordStr = MacroUtil.getAttribute(node,
133
		return null;
133
				MacroConstants.X_COORD_ATTRIBUTE);
134
	}
134
		String yCoordStr = MacroUtil.getAttribute(node,
135
135
				MacroConstants.Y_COORD_ATTRIBUTE);
136
	private ArrayList getPath(MenuItem item)
136
		String detailStr = MacroUtil.getAttribute(node,
137
	{
137
				MacroConstants.DETAIL_ATTRIBUTE);
138
		ArrayList segments = new ArrayList();
138
139
		Object data = item.getData();
139
		if (xCoordStr != null && yCoordStr != null)
140
140
			toolBarLocation = new Point(Integer.parseInt(xCoordStr), Integer
141
		if (data instanceof ContributionItem)
141
					.parseInt(yCoordStr));
142
		{
142
		if (detailStr != null)
143
			ContributionItem aitem = (ContributionItem) data;
143
			detail = Integer.parseInt(detailStr);
144
			MenuManager manager = (MenuManager) aitem.getParent();
144
145
			while (manager != null)
145
		if (sel != null) {
146
			{
146
			selection = sel.equals(MacroConstants.TRUE_VALUE) ? Boolean.TRUE
147
				String id = manager.getId();
147
					: Boolean.FALSE;
148
				if (id == null)
148
		}
149
					break;
149
		NodeList children = node.getChildNodes();
150
				segments.add(0, id);
150
		for (int i = 0; i < children.getLength(); i++) {
151
				manager = (MenuManager) manager.getParent();
151
			Node child = children.item(i);
152
			}
152
			if (!(child.getNodeType() == Node.ELEMENT_NODE))
153
		}
153
				continue;
154
		return segments.size() > 0 ? segments : null;
154
155
	}
155
			if (child.getNodeName().equals(MacroConstants.SELECT_ITEM_ELEMENT)) {
156
156
				String pathOfItem = MacroUtil.getAttribute(child,
157
	public void load(Node node, Hashtable lineTable) throws CoreException
157
						MacroConstants.WIDGET_ID_ATTRIBUTE);
158
	{
158
				if (pathOfItem == null) {
159
		super.load(node, lineTable);
159
					String refId = MacroUtil.getAttribute(child,
160
		String sel = MacroUtil.getAttribute(node, MacroConstants.SELECTION_ATTRIBUTE);
160
							MacroConstants.REFERENCE_ID_ATTRIBUTE);
161
		String xCoordStr = MacroUtil.getAttribute(node, MacroConstants.X_COORD_ATTRIBUTE);
161
					if (refId == null) {
162
		String yCoordStr = MacroUtil.getAttribute(node, MacroConstants.Y_COORD_ATTRIBUTE);
162
						itemSelectedIdentifier = null;
163
		String detailStr = MacroUtil.getAttribute(node, MacroConstants.DETAIL_ATTRIBUTE);
163
					} else {
164
164
						MacroObjectDescriptor uiObject = MacroManager
165
		if (xCoordStr != null && yCoordStr != null)
165
								.getInstance()
166
			toolBarLocation = new Point(Integer.parseInt(xCoordStr), Integer.parseInt(yCoordStr));
166
								.getObjectMine()
167
		if (detailStr != null)
167
								.lookupMacroObjectDescriptor(
168
			detail = Integer.parseInt(detailStr);			
168
										getCorrespondingMacroObjectDescriptor(),
169
		
169
										refId);
170
170
						if (uiObject != null) {
171
		if (sel != null)
171
							itemSelectedIdentifier = new PrimitiveUIObjectIdentifier(
172
		{
172
									uiObject.getWidgetId(), uiObject
173
			selection = sel.equals(MacroConstants.TRUE_VALUE) ? Boolean.TRUE : Boolean.FALSE;
173
											.getResolverId());
174
		}
174
						}
175
		NodeList children = node.getChildNodes();
175
					}
176
		for (int i = 0; i < children.getLength(); i++)
176
177
		{
177
				} else {
178
			Node child = children.item(i);
178
					itemSelectedIdentifier = new PrimitiveUIObjectIdentifier(
179
			if (!(child.getNodeType() == Node.ELEMENT_NODE))
179
							pathOfItem);
180
				continue;
180
				}
181
			
181
182
			if (child.getNodeName().equals(MacroConstants.PARENT_ELEMENT))
182
				dropDownMenuListener = new DropDownMenuListener();
183
			{
183
			}
184
				if (path == null)
184
		}
185
					path = new ArrayList();
185
	}
186
				path.add(MacroUtil.getAttribute(child, MacroConstants.WIDGET_ID_ATTRIBUTE));
186
187
			}
187
	public void write(int indent, StringBuffer sb) {
188
			else if (child.getNodeName().equals(MacroConstants.SELECT_ITEM_ELEMENT))
188
		super.write(indent, sb);
189
			{
189
		boolean childElementPresent = itemSelectedIdentifier != null;
190
				String pathOfItem = MacroUtil.getAttribute(child, MacroConstants.PATH_ATTRIBUTE);
190
		MacroUtil
191
				if (pathOfItem == null)
191
				.addAttribute(
192
				{
192
						sb,
193
					String refId = MacroUtil.getAttribute(child, MacroConstants.REFERENCE_ID_ATTRIBUTE);
193
						new String[] { MacroConstants.X_COORD_ATTRIBUTE,
194
					if (refId == null)
194
								MacroConstants.Y_COORD_ATTRIBUTE,
195
					{
195
								MacroConstants.DETAIL_ATTRIBUTE,
196
						itemSelectedId = null;
196
								MacroConstants.SELECTION_ATTRIBUTE },
197
					}
197
198
					else
198
						new String[] {
199
					{
199
								toolBarLocation == null ? null : String
200
						IUIObject uiObject = MacroManager.getInstance().getObjectMine().lookupUIObject(getCorrespondingObject(), refId);
200
										.valueOf(toolBarLocation.x),
201
						if (uiObject != null)
201
								toolBarLocation == null ? null : String
202
						{
202
										.valueOf(toolBarLocation.y),
203
							itemSelectedId = new PrimitiveWidgetId(uiObject.getObjectId().toString());
203
								detail == -10 ? null : String.valueOf(detail),
204
							itemSelectedId.setResolverId(uiObject.getResolverId());
204
								selection == null ? null
205
						}
205
										: selection.equals(Boolean.TRUE) ? MacroConstants.TRUE_VALUE
206
					}
206
												: MacroConstants.FALSE_VALUE },
207
						
207
						!childElementPresent, true);
208
				}
208
209
				else
209
		int pindent = childElementPresent ? indent + 1 : 0;
210
				{
210
211
					itemSelectedId = new PrimitiveWidgetId(pathOfItem);
211
		if (itemSelectedIdentifier != null) {
212
				}
212
			boolean useObjectMine = useObjectMine()
213
				
213
					&& itemSelectedRefId != null;
214
				dropDownMenuListener = new DropDownMenuListener();
214
			MacroUtil.addElement(sb, pindent,
215
			}
215
					MacroConstants.SELECT_ITEM_ELEMENT, false, false);
216
		}
216
			MacroUtil
217
	}
217
					.addAttribute(
218
218
							sb,
219
	public void write(int indent, StringBuffer sb)
219
							new String[] { useObjectMine ? MacroConstants.REFERENCE_ID_ATTRIBUTE
220
	{
220
									: MacroConstants.WIDGET_ID_ATTRIBUTE },
221
		super.write(indent, sb);
221
							new String[] { useObjectMine ? itemSelectedRefId
222
		boolean childElementPresent = itemSelectedId != null;
222
									: itemSelectedIdentifier.getWidgetId() },
223
		MacroUtil.addAttribute(sb, 
223
							true, true);
224
				new String[]{MacroConstants.X_COORD_ATTRIBUTE,
224
			MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT,
225
							 MacroConstants.Y_COORD_ATTRIBUTE,
225
					true, true);
226
							 MacroConstants.DETAIL_ATTRIBUTE,
226
		}
227
							 MacroConstants.SELECTION_ATTRIBUTE
227
	}
228
							},
228
229
				
229
	public boolean doPlayback(Display display, Shell parent,
230
				new String[]{toolBarLocation == null ? null : String.valueOf(toolBarLocation.x),
230
			IProgressMonitor monitor) throws CoreException {
231
							 toolBarLocation == null ? null : String.valueOf(toolBarLocation.y),
231
232
							 detail == -10 ? null : String.valueOf(detail),
232
		if (macroObject == null)
233
							 selection == null ? null : selection.equals(Boolean.TRUE) ? MacroConstants.TRUE_VALUE : MacroConstants.FALSE_VALUE
233
			return false;
234
							}, 
234
235
							!childElementPresent, true);
235
		// boolean executeForFirstMatch = false;
236
				
236
		// for (int i = 0; i < targets.length && !executeForFirstMatch; i++) {
237
		
237
		setFocus(macroObject);
238
		int pindent = childElementPresent ? indent + 1 : 0;
238
		Widget widget = macroObject.getUIObject().getWidget();
239
				
239
240
		if (itemSelectedId != null)
240
		// executeForFirstMatch = widget instanceof Button;
241
		{	
241
		Display currentDisplay = GuiPlugin.getDefault().getWorkbench()
242
			boolean useObjectMine = MacroManager.getInstance().isObjectMineOn() && itemSelectedRefId != null;
242
				.getDisplay();
243
			MacroUtil.addElement(sb, pindent, MacroConstants.SELECT_ITEM_ELEMENT, false, false);			
243
		ActionContributionItem contributionItem = null;
244
			MacroUtil.addAttribute(sb, new String[]
244
		if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0) {
245
			          {
245
			/*
246
						useObjectMine ? MacroConstants.REFERENCE_ID_ATTRIBUTE : MacroConstants.PATH_ATTRIBUTE
246
			 * If in case we're dealing with a toolbar item that is a drop-down,
247
			          }, 
247
			 * then register appropriate listeners that will be used for getting
248
			          new String[]
248
			 * a reference to the menu. We only need to do this if a menu
249
			          {
249
			 * creator is not provided
250
						useObjectMine ? itemSelectedRefId : itemSelectedId.toString()
250
			 */
251
			          }, true, true);
251
			if (widget instanceof ToolItem && /* Are we a tool item? */
252
			MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, true, true);
252
			(widget.getStyle() & SWT.DROP_DOWN) != 0 && /* Are we a drop down? */
253
		}
253
			itemSelectedIdentifier != null && /*
254
	}
254
												 * Do we have a selected item
255
255
												 * from our menu (i.e. is the
256
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
256
												 * menu even needed)?
257
	{
257
												 */
258
		CommandTarget[] targets = MacroObjectLocator.locateCommandTarget(parent, getWidgetId(), path, getStartLine());
258
			widget.getData() instanceof ActionContributionItem)/*
259
		if (targets == null)
259
																 * Are we
260
			return false;
260
																 * dealing with
261
		
261
																 * a
262
		boolean executeForFirstMatch = false;
262
																 * contribution
263
		for (int i = 0; i < targets.length && !executeForFirstMatch; i++)
263
																 * item?
264
		{
264
																 */
265
			targets[i].setFocus();
265
			{
266
			Widget widget = targets[i].getWidget();
266
267
			
267
				contributionItem = (ActionContributionItem) widget.getData();
268
			executeForFirstMatch = widget instanceof Button;
268
269
			Display currentDisplay = GuiPlugin.getDefault().getWorkbench().getDisplay();
269
				/* We don't have a menu creator. Register the listeners */
270
			ActionContributionItem contributionItem = null;
270
				if (contributionItem.getAction().getMenuCreator() == null) {
271
			if ((widget.getStyle() & (SWT.CHECK | SWT.RADIO)) == 0)
271
					currentDisplay.addFilter(SWT.Show, dropDownMenuListener);
272
			{
272
273
				/* If in case we're dealing with a toolbar item that is a drop-down, then register 
273
				}
274
				 * appropriate listeners that will be used for getting a reference to the menu.  We only need
274
			}
275
				 * to do this if a menu creator is not provided */
275
276
				if ( widget instanceof ToolItem &&						/* Are we a tool item? */ 
276
			if (itemSelectedIdentifier == null
277
					 (widget.getStyle() & SWT.DROP_DOWN) != 0 && 		/* Are we a drop down? */
277
					|| (itemSelectedIdentifier != null
278
					 itemSelectedId != null &&							/* Do we have a selected item from our menu (i.e. is the menu even needed)? */ 		
278
							&& contributionItem != null && contributionItem
279
					 widget.getData() instanceof ActionContributionItem)/* Are we dealing with a contribution item? */
279
							.getAction().getMenuCreator() == null))
280
				{
280
				doClick(display, widget, false);
281
							
281
		}
282
					contributionItem = (ActionContributionItem)widget.getData();
282
283
					
283
		else if (selection != null) {
284
					/* We don't have a menu creator.  Register the listeners */
284
			doSelect(display, widget);
285
					if (contributionItem.getAction().getMenuCreator() == null)
285
		}
286
					{
286
287
						currentDisplay.addFilter(SWT.Show, dropDownMenuListener);			
287
		/* Select the item from the drop-down menu, if there is one set */
288
						
288
		if (itemSelectedIdentifier != null) {
289
					}
289
			if (contributionItem == null) {
290
				}
290
				currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);
291
				
291
				return false; // continue; /* we weren't able to select the
292
				if (itemSelectedId == null ||
292
				// item */
293
				   (itemSelectedId != null && contributionItem != null && contributionItem.getAction().getMenuCreator() == null))
293
			}
294
					doClick(display, widget, false);
294
295
			}
295
			Menu menu = null;
296
			
296
			IMenuCreator menuCreator = contributionItem.getAction()
297
297
					.getMenuCreator();
298
			else if (selection != null)
298
299
			{
299
			/* Attempt to create the menu */
300
				doSelect(display, widget);
300
			if (menuCreator != null)
301
			}
301
				menu = menuCreator.getMenu(parent);
302
						
302
			/* Otherwise we wait until the menu is handed out to us */
303
			/* Select the item from the drop-down menu, if there is one set */
303
			else {
304
			if (itemSelectedId != null)
304
				try {
305
			{
305
					menuIsNeeded = true;
306
				if (contributionItem == null)
306
					/*
307
				{
307
					 * Wait a maximum of INCREMENTS * COUNT in increments of
308
					currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);			
308
					 * INCREMENT
309
					continue;					/* we weren't able to select the item */
309
					 */
310
				}
310
					final int INCREMENT = 200;
311
			
311
					final int COUNT = 15;
312
				Menu menu = null;
312
					synchronized (this) {
313
				IMenuCreator menuCreator = contributionItem.getAction().getMenuCreator(); 
313
						int count = 0;
314
				
314
						while (dropDownMenu == null && count < COUNT) {
315
				/* Attempt to create the menu */
315
							wait(INCREMENT);
316
				if (menuCreator != null)
316
							count++;
317
					menu = menuCreator.getMenu(parent);
317
						}
318
				/* Otherwise we wait until the menu is handed out to us */
318
					}
319
				else
319
				} catch (InterruptedException e) {
320
				{				
320
					/* doesn't need to be handled */
321
					try 
321
				}
322
					{
322
				if (dropDownMenu != null)
323
						menuIsNeeded = true;
323
					menu = dropDownMenu;
324
						/* Wait a maximum of INCREMENTS * COUNT in increments of INCREMENT */
324
			}
325
						final int INCREMENT = 200;
325
			/* Bail out if we couldn't get the menu */
326
						final int COUNT = 15;
326
			if (menu == null) {
327
						synchronized (this)
327
				currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);
328
						{
328
				return false; // continue; /* we weren't able to select the
329
							int count = 0;
329
				// item */
330
							while (dropDownMenu == null && count < COUNT)
330
			}
331
							{
331
332
								wait (INCREMENT);
332
			/* Unregister the listener */
333
								count++;
333
			currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);
334
							}
334
335
						}
335
			/* Find the menu item corresponding to the drop down menu */
336
					} 
336
			MenuItem[] menuItems = menu.getItems();
337
					catch (InterruptedException e) 
337
			MenuItem foundItem = null;
338
					{					
338
			for (int j = 0; j < menuItems.length; j++) {
339
						/* doesn't need to be handled */
339
				if (foundMenuItem(menuItems[j])) {
340
					}
340
					foundItem = menuItems[j];
341
					if (dropDownMenu != null)
341
					break;
342
						menu = dropDownMenu;
342
				}
343
				}
343
			}
344
				/* Bail out if we couldn't get the menu */
344
345
				if (menu == null)
345
			if (foundItem == null)
346
				{
346
				return false;// /continue;
347
					currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);							
347
348
					continue;					/* we weren't able to select the item */
348
			doClick(display, foundItem, true);
349
				}
349
350
				
350
		}
351
				/* Unregister the listener */
351
352
				currentDisplay.removeFilter(SWT.Show, dropDownMenuListener);
352
		// }
353
				
353
354
				/* Find the menu item corresponding to the drop down menu */
354
		return true;
355
				MenuItem[] menuItems = menu.getItems();
355
	}
356
				MenuItem foundItem = null;
356
357
				for (int j = 0; j < menuItems.length; j++)
357
	private boolean foundMenuItem(MenuItem menuItem) {
358
				{				
358
		/* Try the widget resolvers first */
359
					if (foundMenuItem(menuItems[j]))
359
		if (UIObjectDeprecatedDeresolvingSupport.foundItem(menuItem,
360
					{
360
				itemSelectedIdentifier))
361
						foundItem = menuItems[j];
361
			return true;
362
						break;
362
363
					}
363
		/* Give the old policy a try */
364
				}
364
		Object menuItemIdObj = getDropDownItemTraditionalId(menuItem);
365
				
365
		if (menuItemIdObj.equals(itemSelectedIdentifier.getWidgetId()))
366
				if (foundItem == null)
366
			return true;
367
					continue;
367
368
				
368
		return false;
369
				doClick(display, foundItem, true);
369
	}
370
				
370
371
			}			
371
	private Object getDropDownItemTraditionalId(MenuItem menuItem) {
372
		}
372
		Object data = menuItem.getData();
373
		
373
		if (data instanceof ActionContributionItem) {
374
		return true;
374
			return ((ActionContributionItem) data).getAction().getClass()
375
	}
375
					.getName();
376
	
376
		} else if (data != null)
377
	private boolean foundMenuItem (MenuItem menuItem)
377
			return data.getClass().getName();
378
	{
378
379
		/* Try the widget resolvers first */
379
		/* As a last resort, index the menu item */
380
		if (MacroObjectLocator.foundItem(menuItem, itemSelectedId.getResolverId(), itemSelectedId.toString()))
380
		return findMenuItemInx(menuItem, "");
381
			return true;
381
	}
382
	
382
383
		/* Give the old policy a try */
383
	private String findMenuItemInx(MenuItem menuItem, String index) {
384
		Object menuItemIdObj = getDropDownItemTraditionalId(menuItem);
384
		if (index != null && index.length() > 0)
385
		if (menuItemIdObj.equals(itemSelectedId.toString()))
385
			index = index + "|";
386
			return true;
386
387
		
387
		Menu parentMenu = menuItem.getMenu();
388
		return false;
388
389
	}
389
		if (parentMenu == null)
390
390
			parentMenu = menuItem.getParent();
391
	
391
392
	private Object getDropDownItemTraditionalId (MenuItem menuItem)
392
		if (parentMenu != null) {
393
	{
393
			int currentInx = parentMenu.indexOf(menuItem);
394
		Object data = menuItem.getData();
394
			MenuItem parentItem = parentMenu.getParentItem();
395
		if (data instanceof ActionContributionItem)
395
396
		{
396
			index = index + currentInx;
397
			return ((ActionContributionItem)data).getAction().getClass().getName();
397
			if (parentItem != null)
398
		}
398
				return index + findMenuItemInx(parentItem, index);
399
		else if (data!=null)
399
		}
400
			return data.getClass().getName();
400
401
		
401
		return index;
402
		/* As a last resort, index the menu item */		
402
	}
403
		return findMenuItemInx (menuItem, "");
403
404
	}
404
	private void doClick(Display display, Widget widget, boolean isItemSelected)
405
	
405
			throws CoreException {
406
	private String findMenuItemInx(MenuItem menuItem, String index) 
406
407
	{
407
		checkEnableStatus(widget);
408
		if (index != null && index.length() > 0)
408
		Event e = new Event();
409
			index = index + "|";
409
		e.type = SWT.Selection;
410
		
410
		e.widget = widget;
411
		Menu parentMenu = menuItem.getMenu();
411
		e.display = display;
412
		
412
413
		if (parentMenu == null)
413
		boolean positionSet = false;
414
			parentMenu = menuItem.getParent();
414
		boolean detailSet = false;
415
		
415
		if (!isItemSelected) {
416
		if (parentMenu != null)
416
			if (toolBarLocation != null) {
417
		{
417
				e.x = toolBarLocation.x;
418
			int currentInx = parentMenu.indexOf(menuItem);
418
				e.y = toolBarLocation.y;
419
			MenuItem parentItem = parentMenu.getParentItem();
419
				positionSet = true;
420
			
420
			}
421
			index = index + currentInx;
421
422
			if (parentItem != null)
422
			if (detail != -10) {
423
				return index + findMenuItemInx(parentItem, index);
423
				e.detail = detail;
424
		}
424
				detailSet = true;
425
			
425
			}
426
		return index;
426
		}
427
	}
427
428
	
428
		boolean isWidgetNotified = false;
429
	private void doClick(Display display, Widget widget, boolean isItemSelected) throws CoreException
429
430
	{		
430
		/* We need to do an immediate notify if we're a drop down menu */
431
		checkEnableStatus(widget);
431
		if ((positionSet && detailSet) || menuIsNeeded) {
432
		Event e = new Event();
432
			isWidgetNotified = true;
433
		e.type = SWT.Selection;
433
			widget.notifyListeners(e.type, e);
434
		e.widget = widget;
434
		}
435
		e.display = display;
435
436
		
436
		/*
437
		boolean positionSet = false;
437
		 * If we're dealing with a drop down menu, then we have to send out this
438
		boolean detailSet = false;		
438
		 * mouse down event. Otherwise the readAndDispatch will wait
439
		if (!isItemSelected)
439
		 * indefinitely. This is safe because we're only sending a mouse down
440
		{
440
		 * event without a successive mouse up event.
441
			if (toolBarLocation != null)
441
		 */
442
			{
442
		if (positionSet && detailSet) {
443
				e.x = toolBarLocation.x;
443
			/* Move the cursor to a safe position */
444
				e.y = toolBarLocation.y;
444
			Event mouseMoveEvent = new Event();
445
				positionSet = true;
445
			mouseMoveEvent.type = SWT.MouseMove;
446
			}
446
			mouseMoveEvent.x = 10;
447
	
447
			mouseMoveEvent.y = widget.getDisplay().getClientArea().height / 2;
448
			if (detail != -10)			
448
			widget.getDisplay().post(mouseMoveEvent);
449
			{
449
450
				e.detail = detail;
450
			Event mouseDownEvent = new Event();
451
				detailSet = true;
451
			mouseDownEvent.type = SWT.MouseDown;
452
			}					
452
			mouseDownEvent.button = 1;
453
		}
453
			widget.getDisplay().post(mouseDownEvent);
454
		
454
		}
455
		boolean isWidgetNotified = false;
455
456
		
456
		/* Run the events */
457
		/* We need to do an immediate notify if we're a drop down menu */
457
		MacroUtil.processDisplayEvents(display);
458
		if ((positionSet && detailSet) || menuIsNeeded)
458
459
		{
459
		/*
460
			isWidgetNotified = true;
460
		 * Now notify the listeners of the widget if they haven't already been
461
			widget.notifyListeners(e.type, e);
461
		 * notified
462
		}
462
		 */
463
			
463
		if (!isWidgetNotified) {
464
464
			widget.notifyListeners(e.type, e);
465
		/* If we're dealing with a drop down menu, then we have to send out this
465
		}		
466
		 * mouse down event.  Otherwise the readAndDispatch will wait indefinitely.
466
	}
467
		 * This is safe because we're only sending a mouse down event without a successive
467
468
		 * mouse up event. */
468
	private void doSelect(Display display, Widget widget) throws CoreException {
469
		if (positionSet && detailSet)
469
		checkEnableStatus(widget);
470
		{
470
		boolean shouldClick = false;
471
			/* Move the cursor to a safe position */
471
		if (widget instanceof Button) {
472
			Event mouseMoveEvent = new Event();
472
			((Button) widget).setSelection(selection.booleanValue());
473
			mouseMoveEvent.type = SWT.MouseMove;
473
			shouldClick = true;
474
			mouseMoveEvent.x = 10;
474
		} else if (widget instanceof ToolItem) {
475
			mouseMoveEvent.y = widget.getDisplay().getClientArea().height / 2;
475
			((ToolItem) widget).setSelection(selection.booleanValue());
476
			widget.getDisplay().post(mouseMoveEvent);
476
			shouldClick = true;
477
			
477
		} else if (widget instanceof MenuItem) {
478
			Event mouseDownEvent = new Event();
478
			((MenuItem) widget).setSelection(selection.booleanValue());
479
			mouseDownEvent.type = SWT.MouseDown;
479
			shouldClick = true;
480
			mouseDownEvent.button = 1;
480
		}
481
			widget.getDisplay().post(mouseDownEvent);	
481
482
		}
482
		/* Ali M.: We need to also send out a selection event */
483
483
		if (shouldClick)
484
		
484
			doClick(display, widget, selection.booleanValue());
485
		/* Run the events */
485
	}
486
		MacroUtil.processDisplayEvents(display);
486
487
		
487
	/**
488
		/* Now notify the listeners of the widget if they haven't already been notified */	
488
	 * Checks the enable status of the widget. If in case the widget happens to
489
		if (!isWidgetNotified)
489
	 * be disabled, then throw a core exception.
490
			widget.notifyListeners(e.type, e);
490
	 * 
491
						
491
	 * @param widget
492
	}
492
	 *            The widget whose status is being checked.
493
493
	 * @throws CoreException
494
	private void doSelect(Display display, Widget widget) throws CoreException
494
	 *             If widget is disabled
495
	{
495
	 */
496
		checkEnableStatus(widget);
496
	public void checkEnableStatus(Widget widget) throws CoreException {
497
		boolean shouldClick = false;
497
		Button button = null;
498
		if (widget instanceof Button)
498
		if (widget instanceof Button
499
		{
499
				&& !(button = ((Button) widget)).isEnabled())
500
			((Button) widget).setSelection(selection.booleanValue());
500
			AutoGUIUtil.throwCoreException(NLS.bind(
501
			shouldClick = true;
501
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_DISABLE, button
502
		}
502
							.getText()), getStartLine());
503
		else if (widget instanceof ToolItem)
503
	}
504
		{
504
505
			((ToolItem) widget).setSelection(selection.booleanValue());
505
	public int getDetail() {
506
			shouldClick = true;						
506
		return detail;
507
		}
507
	}
508
		else if (widget instanceof MenuItem)
508
509
		{
509
	public void setItemSelected(Event event) {
510
			((MenuItem) widget).setSelection(selection.booleanValue());
510
		if (!(event.widget instanceof MenuItem))
511
			shouldClick = true;
511
			return;
512
		}
512
513
		
513
		// ANy: The formerly called determineItemId has moved into the
514
		/* Ali M.: We need to also send out a selection event */
514
		// NonTrivialUIObjectResolverDelegate, which is the only contributor to
515
		if (shouldClick)
515
		// resolve/deresolve items,
516
			doClick(display, widget, selection.booleanValue());								
516
		// so defect# 112668 is still handled properly here
517
	}
517
		try {
518
518
			itemSelectedIdentifier = UIObjectResolver.resolve(new MacroObject(
519
	
519
					new UIObject(event.widget)).getContext(), new UIObject(
520
	/**
520
					(MenuItem) event.widget));
521
	 * Checks the enable status of the widget.  If in case the widget happens to be
521
		} catch (Exception e) {
522
	 * disabled, then throw a core exception.
522
			e.printStackTrace();
523
	 * 
523
		}
524
	 * @param widget The widget whose status is being checked.
524
525
	 * @throws CoreException If widget is disabled
525
		/* Register the selected item with the object mine */
526
	 */
526
		MacroManager macroManager = MacroManager.getInstance();
527
	public void checkEnableStatus(Widget widget) throws CoreException
527
		if (macroManager.isObjectMineOn()) {
528
	{
528
			MacroObjectDescriptorMine objectMine = macroManager.getObjectMine();
529
		Button button = null;
529
530
		if (widget instanceof Button && !(button = ((Button)widget)).isEnabled())
530
			MacroObjectDescriptor parent = objectMine
531
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_DISABLE, button.getText()), getStartLine());
531
					.lookupMacroObjectDescriptor(objectMine.getActiveObject(),
532
	}
532
							getCorrespondingMacroObjectDescriptor()
533
	
533
									.getReferenceId());
534
	
534
			MacroObjectDescriptor macroObjectDescriptor = objectMine
535
	public int getDetail()
535
					.lookupMacroObjectDescriptor(parent, null,
536
	{
536
							itemSelectedIdentifier.getWidgetId(), itemSelectedIdentifier.getObjectId());
537
		return detail;
537
538
	}
538
			if (macroObjectDescriptor == null) {
539
539
				macroObjectDescriptor = new MacroObjectDescriptor(parent);
540
	public void setItemSelected(Event event)
540
				((MacroObjectDescriptor) macroObjectDescriptor)
541
	{
541
						.setWidgetId(itemSelectedIdentifier.getWidgetId());
542
		if (!(event.widget instanceof MenuItem))
542
				((MacroObjectDescriptor) macroObjectDescriptor)
543
			return;
543
				.setObjectId(itemSelectedIdentifier.getObjectId());				
544
		
544
				((MacroObjectDescriptor) macroObjectDescriptor)
545
		itemSelectedId = MacroUtil.determineItemId((MenuItem)event.widget);
545
						.setResolver(itemSelectedIdentifier.getResolverId());
546
		
546
				((MacroObjectDescriptor) macroObjectDescriptor)
547
		/* Register the selected item with the object mine */
547
						.setDescriptive(getObjectClassName(event.widget));
548
		MacroManager macroManager = MacroManager.getInstance();
548
				try {
549
		if (macroManager.isObjectMineOn())
549
					macroObjectDescriptor = objectMine
550
		{
550
							.registerObject((MacroObjectDescriptor) macroObjectDescriptor);
551
			IObjectMine objectMine = macroManager.getObjectMine();
551
				} catch (Exception e) {
552
			IUIObject parent = objectMine.lookupUIObject(objectMine.getActiveObject(), getWidgetId().getReferenceId());
552
					itemSelectedRefId = null;
553
			IUIObject uiObject = objectMine.lookupUIObject(parent, null, itemSelectedId.toString());
553
				}
554
			if (uiObject == null)
554
			}
555
			{				
555
556
				uiObject = new UIObject(parent);
556
			if (macroObjectDescriptor != null) {
557
				uiObject.setObjectId(itemSelectedId.toString());
557
				itemSelectedRefId = macroObjectDescriptor.getReferenceId();
558
				uiObject.setReferenceId(objectMine.getUniqueReferenceId());
558
			}
559
				uiObject.setResolver(itemSelectedId.getResolverId());			
559
		}
560
				uiObject.setDescriptive(getObjectClassName (event.widget));
560
	}
561
				try
561
562
				{
562
	public boolean isRepeatRedundant() {
563
					uiObject = objectMine.registerObject(uiObject);
563
		return false;
564
				} 
564
	}
565
				catch (Exception e)
565
566
				{
566
	public class DropDownMenuListener implements Listener {
567
					itemSelectedRefId = null;
567
568
				} 
568
		public void handleEvent(Event event) {
569
			}
569
			if (event.widget instanceof Menu) {
570
			
570
				dropDownMenu = (Menu) event.widget;
571
			if (uiObject != null)
571
				synchronized (BooleanSelectionCommand.this) {
572
			{
572
					BooleanSelectionCommand.this.notify();
573
				itemSelectedRefId = uiObject.getReferenceId();
573
				}
574
			}
574
			}
575
		}
575
		}
576
	}
576
577
577
	}
578
	public boolean isRepeatRedundant()
578
579
	{
579
	private static ArrayList getPath(MenuItem item) {
580
		return false;
580
		ArrayList segments = new ArrayList();
581
	}
581
		Object data = item.getData();
582
	
582
583
	
583
		if (data instanceof ContributionItem) {
584
	public class DropDownMenuListener implements Listener
584
			ContributionItem aitem = (ContributionItem) data;
585
	{
585
			MenuManager manager = (MenuManager) aitem.getParent();
586
586
			while (manager != null) {
587
		public void handleEvent(Event event) 
587
				String id = manager.getId();
588
		{
588
				if (id == null)
589
			if (event.widget instanceof Menu)
589
					break;
590
			{				
590
				segments.add(0, id);
591
				dropDownMenu = (Menu)event.widget;				
591
				manager = (MenuManager) manager.getParent();
592
				synchronized (BooleanSelectionCommand.this)
592
			}
593
				{
593
		}
594
					BooleanSelectionCommand.this.notify();	
594
		return segments.size() > 0 ? segments : null;
595
				}				
595
	}
596
			}
596
597
		}
598
		
599
	}
600
}
597
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/CloseWorkbenchPartCommand.java (-107 / +121 lines)
Lines 1-107 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: CloseWorkbenchPartCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
7
 * $Id: CloseWorkbenchPartCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
13
14
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.Path;
16
import org.eclipse.core.runtime.Path;
17
import org.eclipse.swt.widgets.Composite;
17
import org.eclipse.osgi.util.NLS;
18
import org.eclipse.swt.widgets.Display;
18
import org.eclipse.swt.widgets.Display;
19
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Event;
20
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
20
import org.eclipse.swt.widgets.Shell;
21
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
22
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
22
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
23
import org.eclipse.ui.IEditorPart;
23
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
24
import org.eclipse.ui.IEditorReference;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
25
import org.eclipse.ui.IViewPart;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
26
import org.eclipse.ui.IViewReference;
26
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
27
import org.eclipse.ui.IWorkbenchPage;
27
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
28
import org.eclipse.ui.IWorkbenchPart;
28
import org.eclipse.ui.IEditorPart;
29
29
import org.eclipse.ui.IEditorReference;
30
/**
30
import org.eclipse.ui.IViewPart;
31
 * The purpose of this class is to generate commands responsible for closing workbench parts.
31
import org.eclipse.ui.IViewReference;
32
 * 
32
import org.eclipse.ui.IWorkbenchPage;
33
 * @author Ali Mehregani
33
import org.eclipse.ui.IWorkbenchPart;
34
 */
34
35
public class CloseWorkbenchPartCommand extends AbstractMacroCommand 
35
/**
36
{
36
 * The purpose of this class is to generate commands responsible for closing workbench parts.
37
	public static final String TYPE = "close-workbenchpart";
37
 * 
38
	
38
 * @author Ali Mehregani
39
	public CloseWorkbenchPartCommand(MacroCommandShell parent, WidgetIdentifier widgetId)
39
 */
40
	{
40
public class CloseWorkbenchPartCommand extends ObjectBasedCommand {
41
		super(parent, widgetId);		
41
42
	}
42
	public static final String TYPE = IMacroCommand.CLOSE_WORKBENCHPART;
43
43
44
	public String getType() 
44
	public CloseWorkbenchPartCommand(MacroCommandShell parent) {
45
	{
45
		super(parent);
46
		return TYPE;
46
	}
47
	}
47
48
48
	public String getType() {
49
	public void processEvent(Event e) 
49
		return TYPE;
50
	{
50
	}
51
		setDescriptiveField(((IWorkbenchPart)e.data).getTitle());
51
	
52
	}
52
	protected final void preProcessEvent(Event event) throws CoreException {
53
53
		IMacroObjectIdentifier macroObjectIdentifier = MacroUtil.getCustomEventIdentifier(event);
54
	public void write(int indent, StringBuffer sb) 
54
		if(macroObjectIdentifier == null){
55
	{
55
			IWorkbenchPart part = (IWorkbenchPart) event.data;
56
		super.write(indent, sb, true, true);	
56
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE, part));
57
	}
57
		}
58
58
		setMacroObjectIdentifier(macroObjectIdentifier);
59
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException 
59
	}
60
	{
60
61
		String partType = getWidgetId().getContextId().toString();
61
	public void doProcessEvent(Event e) {
62
		String partId = getWidgetId().getObjectId().toString();
62
		setDescriptiveField(((IWorkbenchPart) e.data).getTitle());
63
		
63
	}
64
		boolean isView = partType.equals(MacroConstants.VIEW_VALUE);
64
65
		IEditorReference[] editorReferences = null;
65
	public void write(int indent, StringBuffer sb) {
66
		IViewReference[] viewReferences = null;
66
		super.write(indent,
67
		
67
			sb,
68
		IWorkbenchPage activePage = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
68
			true,
69
		String editorPartId = null;
69
			true);
70
		String editorInputName = null;
70
	}
71
		
71
	
72
		/* Try to locate the part */
72
	public boolean playback(Display display, Shell parent, IProgressMonitor monitor) throws CoreException {
73
		if (isView)
73
		String partType = getMacroObjectIdentifier().getContextIdentifier().toString();
74
		{
74
		String partId = getMacroObjectIdentifier().getObjectIdentifier().getWidgetId();
75
			viewReferences = activePage.getViewReferences();
75
76
		}
76
		boolean isView = partType.equals(MacroConstants.VIEW_VALUE);
77
		else
77
		IEditorReference[] editorReferences = null;
78
		{
78
		IViewReference[] viewReferences = null;
79
			editorReferences = activePage.getEditorReferences();
79
80
			Path partIdPath = new Path(partId);
80
		IWorkbenchPage activePage = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
81
			editorPartId = partIdPath.segment(0);
81
		String editorPartId = null;
82
			editorInputName = partIdPath.segment(1);
82
		String editorInputName = null;
83
		}
83
84
		
84
		/* Try to locate the part */
85
		IWorkbenchPart desiredPart = null;
85
		if (isView) {
86
		for (int i = 0; i < (isView ? viewReferences.length : editorReferences.length); i++)
86
			viewReferences = activePage.getViewReferences();
87
		{
87
		}
88
			if (isView ? viewReferences[i].getId().equals(partId) : (editorReferences[i].getId().equals(editorPartId) && editorReferences[i].getEditorInput().getName().equals(editorInputName)))
88
		else {
89
			{
89
			editorReferences = activePage.getEditorReferences();
90
				desiredPart = (isView ? (IWorkbenchPart)viewReferences[i].getView(false) : (IWorkbenchPart)editorReferences[i].getEditor(false));
90
			Path partIdPath = new Path(partId);
91
				break;
91
			editorPartId = partIdPath.segment(0);
92
			}
92
			editorInputName = partIdPath.segment(1);
93
		}
93
		}
94
		
94
95
		/* Close the part if we found it */
95
		IWorkbenchPart desiredPart = null;
96
		if (desiredPart != null)
96
		for (int i = 0; i < (isView
97
		{
97
			? viewReferences.length
98
			if (isView)
98
			: editorReferences.length); i++) {
99
				activePage.hideView((IViewPart)desiredPart);
99
			if (isView
100
			else
100
				? viewReferences[i].getId().equals(partId)
101
				activePage.closeEditor((IEditorPart)desiredPart, true);
101
				: (editorReferences[i].getId().equals(editorPartId) && editorReferences[i].getEditorInput().getName().equals(editorInputName))) {
102
		}
102
				desiredPart = (isView
103
		
103
					? (IWorkbenchPart) viewReferences[i].getView(false)
104
		return true;
104
					: (IWorkbenchPart) editorReferences[i].getEditor(false));
105
	}
105
				break;
106
106
			}
107
}
107
		}
108
109
		/* Close the part if we found it */
110
		if (desiredPart != null) {
111
			if (isView)
112
				activePage.hideView((IViewPart) desiredPart);
113
			else
114
				activePage.closeEditor((IEditorPart) desiredPart,
115
					true);
116
		}
117
118
		return true;
119
	}
120
121
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/PositionBasedCommand.java (-98 / +105 lines)
Lines 1-98 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: PositionBasedCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
7
 * $Id: PositionBasedCommand.java,v 1.1 2006/07/10 14:49:05 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
13
14
import org.eclipse.core.runtime.CoreException;
14
import java.util.Hashtable;
15
import org.eclipse.core.runtime.IProgressMonitor;
15
16
import org.eclipse.swt.widgets.Composite;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.swt.widgets.Display;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.swt.widgets.Event;
18
import org.eclipse.swt.widgets.Display;
19
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
19
import org.eclipse.swt.widgets.Event;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
20
import org.eclipse.swt.widgets.Shell;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
22
22
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
23
/**
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
24
 * An abstract representation of position-based commands
24
import org.w3c.dom.Node;
25
 * 
25
26
 * @author Ali Mehregani
26
/**
27
 */
27
 * An abstract representation of position-based commands
28
public abstract class PositionBasedCommand extends AbstractMacroCommand 
28
 * 
29
{
29
 * @author Ali Mehregani
30
30
 * @author Alexander Nyssen (refactoring)
31
	public PositionBasedCommand(MacroCommandShell parent, WidgetIdentifier wi) 
31
 */
32
	{
32
public abstract class PositionBasedCommand extends AbstractMacroCommand {
33
		super(parent, wi);
33
34
	}
34
	protected String type = null;
35
35
	protected Integer detail = null;
36
	/**
36
	
37
	 * The type of the event
37
	public PositionBasedCommand(MacroCommandShell parent) {
38
	 */
38
		super(parent);
39
	public abstract String getType();
39
	}
40
	
40
	
41
	/**
41
	protected abstract String determineType(Event e);
42
	 * A chance for the command to process the original SWT event
42
	
43
	 */
43
	protected abstract Integer determineDetail(Event e);
44
	public abstract void processEvent(Event e);
44
45
	
45
	public void processEvent(Event event) throws Exception {
46
	/**
46
		this.type = determineType(event);
47
	 * Returns a field that is required to complete the string serialization of the
47
		this.detail = determineDetail(event);
48
	 * command.
48
	}
49
	 * 
49
	
50
	 * @return A detail field (for mouse events it corresponds to the button pressed/released and
50
	public String getType() {
51
	 * for key events it corresponds to the key pressed/released
51
		return type;
52
	 */
52
	}
53
	public abstract int getDetail();
53
	
54
54
	public Integer getDetail() {
55
	/**
55
		return detail;
56
	 * Constructs the SWT event that will be played back
56
	}
57
	 * 
57
58
	 * @return The SWT event
58
	/**
59
	 */
59
	 * Constructs the SWT event that will be played back
60
	public abstract Event[] constructSWTEvents();
60
	 * 
61
	
61
	 * @return The SWT event
62
	
62
	 */
63
	/**
63
	public abstract Event[] constructSWTEvents();
64
	 * String serialize this event
64
65
	 */
65
	/**
66
	public void write(int indent, StringBuffer sb, boolean close, boolean end)
66
	 * String serialize this event
67
	{
67
	 */
68
		MacroUtil.addElement(sb, indent, MacroConstants.COMMAND_ELEMENT, false, false);		
68
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
69
		MacroUtil.addAttribute(sb, 
69
		MacroUtil.addElement(sb,
70
				new String[] {			
70
			indent,
71
					MacroConstants.TYPE_ATTRIBUTE,
71
			MacroConstants.COMMAND_ELEMENT,
72
					MacroConstants.DETAIL_ATTRIBUTE, 
72
			false,
73
				}, 
73
			false);
74
				new String[] {
74
		MacroUtil.addAttribute(sb,
75
					getType(),
75
			new String[] {MacroConstants.TYPE_ATTRIBUTE, MacroConstants.DETAIL_ATTRIBUTE},
76
					String.valueOf(getDetail()),
76
			new String[] {getType(), detail != null ? String.valueOf(detail) : null},
77
				}
77
			false,
78
		, false, false);
78
			false);
79
	}
79
	}
80
80
	
81
	/**
81
	public void load(Node node, Hashtable lineTable) throws CoreException {
82
	 * Plays back this command
82
		super.load(node, lineTable);
83
	 */
83
84
	public boolean playback(final Display display, Composite parent, IProgressMonitor monitor) throws CoreException 
84
		type = MacroUtil.getAttribute(node, "type");
85
	{
85
		if(MacroUtil.getAttribute(node, "detail") != null){
86
		Event[] events = constructSWTEvents ();
86
			detail = new Integer(MacroUtil.getAttribute(node, "detail"));
87
		boolean success = true;
87
		}
88
		
88
	}
89
		for (int i = 0; i < events.length; i++)
89
90
		{			
90
	/**
91
			success = success && display.post(events[i]);
91
	 * Plays back this command
92
		}
92
	 */
93
						
93
	public boolean playback(final Display display, final Shell parent, IProgressMonitor monitor) throws CoreException {
94
		MacroUtil.processDisplayEvents(display);
94
		Event[] events = constructSWTEvents();
95
		return success;
95
		boolean success = true;
96
	}
96
97
97
		for (int i = 0; i < events.length; i++) {
98
}
98
			success = success && display.post(events[i]);
99
		}
100
		
101
		MacroUtil.processDisplayEvents(display);
102
		return success;
103
	}
104
105
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/WizardCommandTarget.java (-29 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import org.eclipse.jface.window.Window;
14
import org.eclipse.jface.wizard.WizardDialog;
15
import org.eclipse.swt.widgets.Widget;
16
17
public class WizardCommandTarget extends WindowCommandTarget {
18
	/**
19
	 * @param widget
20
	 * @param window
21
	 */
22
	public WizardCommandTarget(Widget widget, Window window) {
23
		super(widget, window);
24
	}
25
26
	public WizardDialog getWizardDialog() {
27
		return (WizardDialog)getWindow();
28
	}
29
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ExpansionCommand.java (-82 / +93 lines)
Lines 1-83 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
import org.eclipse.swt.SWT;
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.widgets.Event;
14
import org.eclipse.swt.widgets.Event;
15
import org.eclipse.swt.widgets.Tree;
15
import org.eclipse.swt.widgets.Tree;
16
import org.eclipse.swt.widgets.TreeItem;
16
import org.eclipse.swt.widgets.TreeItem;
17
import org.eclipse.swt.widgets.Widget;
17
import org.eclipse.swt.widgets.Widget;
18
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
18
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
19
19
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
20
public class ExpansionCommand extends ToggleStructuredCommand {
20
21
	public static final String TYPE = "item-expand";
21
public class ExpansionCommand extends ToggleStructuredCommand {
22
	/**
22
23
	 * @param wid
23
	public static final String TYPE = IMacroCommand.ITEM_EXPAND;
24
	 */
24
25
	public ExpansionCommand(MacroCommandShell parent, WidgetIdentifier wid) {
25
	/**
26
		super(parent, wid);
26
	 * @param wid
27
	}
27
	 */
28
	
28
	public ExpansionCommand(MacroCommandShell parent) {
29
	public void processEvent(Event event) {
29
		super(parent);
30
		super.processEvent(event);
30
	}
31
		Widget item = event.item;
31
32
		itemState = getItemState (item);
32
	public ExpansionCommand(MacroCommandShell parent,
33
	}
33
			IMacroObjectIdentifier identifier) {
34
	
34
		super(parent);
35
	/* Added for defect 164197*/
35
		setMacroObjectIdentifier(identifier);
36
	
36
	}
37
	public void processEvent(Event event, boolean preferredState)
37
38
	{
38
	public void doProcessEvent(Event event) {
39
		super.processEvent(event);
39
		super.doProcessEvent(event);
40
		itemState = preferredState;
40
		Widget item = event.item;
41
	}
41
		itemState = getItemState(item);
42
	public boolean getItemState(Widget item)
42
	}
43
	{		
43
44
		if (item instanceof TreeItem)
44
	/* Added for defect 164197 */
45
			return !((TreeItem)item).getExpanded();
45
46
		
46
	public void doProcessEvent(Event event, boolean preferredState) {
47
		return false;
47
		super.doProcessEvent(event);
48
	}
48
49
49
		itemState = preferredState;
50
	protected void playStructuredCommand(Widget widget, Object[] matches) 
50
	}
51
	{
51
52
		/* Doesn't need to be implemented */
52
	public void setItemState(boolean state) {
53
	}
53
		this.itemState = state;
54
	
54
	}
55
	protected void playStructuredCommandForFoundMatch(Widget widget, Object match) 
55
56
	{
56
	public boolean getItemState(Widget item) {
57
		if (!(widget instanceof Tree))
57
		if (item instanceof TreeItem)
58
			return;
58
			return !((TreeItem) item).getExpanded();
59
		
59
60
		TreeItem treeItem = (TreeItem)match;
60
		return false;
61
		treeItem.setExpanded(getValue());
61
	}
62
		fireEvent(widget, treeItem);		
62
63
	}
63
	protected void playStructuredCommand(Widget widget, Object[] matches) {
64
	
64
		/* Doesn't need to be implemented */
65
	
65
	}
66
	private void fireEvent(Widget widget, Widget item) 
66
67
	{
67
	protected void playStructuredCommandForFoundMatch(Widget widget,
68
		Event event = new Event();
68
			Object match) {
69
		event.type = getValue()?SWT.Expand:SWT.Collapse;
69
		if (!(widget instanceof Tree))
70
		event.widget = widget;
70
			return;
71
		event.item= item;
71
72
		widget.notifyListeners(event.type, event);
72
		TreeItem treeItem = (TreeItem) match;
73
	}
73
		treeItem.setExpanded(getValue());
74
74
		fireEvent(widget, treeItem);
75
	
75
	}
76
	/* (non-Javadoc)
76
77
	 * @see org.eclipse.ui.macro.SelectionCommand#getKind()
77
	private void fireEvent(Widget widget, Widget item) {
78
	 */
78
		Event event = new Event();
79
	public String getType() {
79
		event.type = getValue() ? SWT.Expand : SWT.Collapse;
80
		return TYPE;
80
		event.widget = widget;
81
	}
81
		event.item = item;
82
82
		widget.notifyListeners(event.type, event);
83
	}
84
85
	/*
86
	 * (non-Javadoc)
87
	 * 
88
	 * @see org.eclipse.ui.macro.SelectionCommand#getKind()
89
	 */
90
	public String getType() {
91
		return TYPE;
92
	}
93
83
}
94
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/MacroCommandShell.java (-1478 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Vector;
16
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.core.runtime.Status;
23
import org.eclipse.core.runtime.SubProgressMonitor;
24
import org.eclipse.jface.dialogs.MessageDialog;
25
import org.eclipse.jface.window.Window;
26
import org.eclipse.osgi.util.NLS;
27
import org.eclipse.swt.SWT;
28
import org.eclipse.swt.SWTException;
29
import org.eclipse.swt.custom.CCombo;
30
import org.eclipse.swt.custom.CTabFolder;
31
import org.eclipse.swt.custom.StyledText;
32
import org.eclipse.swt.graphics.Point;
33
import org.eclipse.swt.widgets.Button;
34
import org.eclipse.swt.widgets.Combo;
35
import org.eclipse.swt.widgets.Composite;
36
import org.eclipse.swt.widgets.Control;
37
import org.eclipse.swt.widgets.Display;
38
import org.eclipse.swt.widgets.Event;
39
import org.eclipse.swt.widgets.List;
40
import org.eclipse.swt.widgets.Listener;
41
import org.eclipse.swt.widgets.MenuItem;
42
import org.eclipse.swt.widgets.Shell;
43
import org.eclipse.swt.widgets.TabFolder;
44
import org.eclipse.swt.widgets.Table;
45
import org.eclipse.swt.widgets.Text;
46
import org.eclipse.swt.widgets.ToolItem;
47
import org.eclipse.swt.widgets.Tree;
48
import org.eclipse.swt.widgets.TreeItem;
49
import org.eclipse.swt.widgets.Widget;
50
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
51
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
52
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
53
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
54
import org.eclipse.tptp.test.auto.gui.internal.core.IPlayable;
55
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
56
import org.eclipse.tptp.test.auto.gui.internal.core.IWritable;
57
import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData;
58
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
59
import org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction;
60
import org.eclipse.tptp.test.auto.gui.internal.macro.Macro;
61
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
62
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
63
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroObjectLocator;
64
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
65
import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject;
66
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException;
67
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound;
68
import org.w3c.dom.Node;
69
import org.w3c.dom.NodeList;
70
71
/**
72
 * <p>Keeps track of the macro commands while they are being captured.</p>
73
 * 
74
 * 
75
 * @author  Paul Slauenwhite
76
 * @version May 16, 2009
77
 * @since   July 10, 2006
78
 */
79
public class MacroCommandShell extends AbstractMacroInstruction
80
{
81
	/* The commands of this macro shell */
82
	private ArrayList commands;
83
84
	/* The expected return code */
85
	private int expectedReturnCode;
86
87
	/* The last event received */
88
	private transient Event lastEvent;
89
90
	/* The display object */
91
	private transient Display display;
92
93
	/* The shell that this macro command shell represents */
94
	private transient Shell shell;
95
	
96
	/* The reference id of the macro shell object */
97
	private String referenceId;
98
	
99
	/* The title of the shell that this macro command shell represents */
100
	private String shellTitle;
101
102
	private transient Window window;
103
	
104
	/* Indicates user interaction -- Set when a key up event is received */
105
	private transient boolean isKeyPressed;
106
107
	/* Indicates user interaction -- Set when a mouse up event is received */
108
	private transient boolean isMousePressed;
109
	
110
	/* Stores an event that is only acknowledged followed by user interaction. */
111
	private transient Event toBeAckEvent;
112
	
113
	/* Set when the stored event in toBeAckEvent is acknowledged */
114
	private transient boolean ackEvent;
115
116
	/* Set when there is a listener registered with this MacroCommandShell */
117
	private transient boolean isListenerRegistered;
118
119
	/* Stores the time for which a command was last created in */
120
	private long lastCommandCreationTime;
121
	
122
	/* A queue of nested shell waiting to be activated (this is used during playback) */ 
123
	private static Vector nestedShellQueue;
124
	
125
	/* Last index of the nested shell queue */ 
126
	private static int lastNestedShellInx;
127
	
128
	/* Stores the last command line executed */
129
	private static int lastCommandLineExecuted;
130
	
131
	/* Mutual lock used to block when a command is being executed.  This lock is used to forcefully wake up
132
	 * the thread that this object is running in if the command has caused a stall */
133
	private Boolean mutualLock;
134
135
	/* A mutual lock shared across multiple instances of this class -- It's general purpose is to lock shared static resources */
136
	private static Boolean mutualGlobalLock;
137
	
138
	/* The parent of this macro command shell.  This is null if this macro shell command is the root */
139
	private MacroCommandShell parent;
140
141
	/* The index of the command being executed -- this will correspond to the last command index if isComplete = true */
142
	private int currentCommandInx;
143
144
	/* Indicates if all the commands of this shell has been completed */
145
	private boolean isComplete;
146
	
147
	/* Indicates that the process needs to be interrupted -- due to an error */
148
	private static boolean interruptProcess;
149
	
150
	/* Set to true when process has been terminated */
151
	private static boolean processTerminated;
152
153
	/* The exception causing the interruption */
154
	private static Throwable interruptedException;
155
		
156
	/* A central container for all macro command operation being played */
157
	private static Vector macroCommandsBeingPlayed;
158
	
159
	/* A central container for all instances of this class */
160
	private static Vector macroCommandShellContainer;
161
	
162
	
163
	/* A central repository for all macro command shells */
164
	static
165
	{
166
		nestedShellQueue = new Vector();
167
		macroCommandsBeingPlayed = new Vector();
168
		macroCommandShellContainer = new Vector();
169
		mutualGlobalLock = new Boolean(true);
170
	}
171
	
172
173
	public MacroCommandShell(MacroCommandShell parent)
174
	{
175
		this(parent, null, null);
176
	}
177
178
	public MacroCommandShell(MacroCommandShell parent, Shell shell, WidgetIdentifier wid)
179
	{
180
		setWidgetId(wid);
181
		commands = new ArrayList();
182
		this.shell = shell;
183
		this.shellTitle = shell == null || shell.isDisposed() ? null : shell.getText();
184
		hookWindow(false);
185
		expectedReturnCode = -1;
186
		isListenerRegistered = false;
187
		mutualLock = new Boolean(true);
188
		this.parent = parent;
189
		isComplete = false;
190
		macroCommandShellContainer.add (this);		
191
	}
192
193
	private void hookWindow(boolean playback)
194
	{
195
		if (shell != null)
196
		{
197
			if (!playback)
198
				doHookWindow();
199
			else
200
				display.syncExec(new Runnable()
201
				{
202
					public void run()
203
					{
204
						doHookWindow();
205
					}
206
				});
207
		}
208
	}
209
210
	private void doHookWindow()
211
	{
212
		Object data = shell.getData();
213
		if (data != null && data instanceof Window)
214
			this.window = (Window) data;
215
	}
216
217
	
218
	/**
219
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable)
220
	 */
221
	public void load(Node node, Hashtable lineTable) throws CoreException
222
	{
223
		super.load(node, lineTable);
224
225
		/* If the corresponding shell of this command is referenced then attempt to find
226
		 * the corresponding object in the object mine. */
227
		setCorrespondingObject(MacroObjectLocator.lookupReferenceId(null, node, lineTable));		
228
		boolean useObjectMine = getCorrespondingObject() != null;
229
		setWidgetId(new WidgetIdentifier(
230
				null,
231
				new Path(useObjectMine ? getCorrespondingObject().getObjectId() : MacroUtil.getAttribute(node, MacroConstants.ID_ATTRIBUTE)),
232
				useObjectMine ? getCorrespondingObject().getResolverId() : MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE)));		
233
		String codeId = MacroUtil.getAttribute(node, MacroConstants.RETURN_CODE_ATTRIBUTE);
234
		if (codeId != null)
235
		{
236
			try
237
			{
238
				expectedReturnCode = new Integer(codeId).intValue();
239
			} catch (NumberFormatException e)
240
			{
241
			}
242
		}
243
		NodeList children = node.getChildNodes();
244
		for (int i = 0; i < children.getLength(); i++)
245
		{
246
			Node child = children.item(i);
247
			if (child.getNodeType() == Node.ELEMENT_NODE)
248
			{
249
				String name = child.getNodeName();
250
				if (name.equals(MacroConstants.COMMAND_ELEMENT))
251
					processCommand(child, lineTable);
252
				else if (name.equals(MacroConstants.SHELL_ELEMENT))
253
					processShell(child, lineTable);
254
			}
255
		}
256
	}
257
258
	/**
259
	 * Used to process the node that is passed in as argument, the lineTable hashtable indicates
260
	 * the range of line numbers that the node corresponds to in the macro script
261
	 *  
262
	 * @param node The node to be processed
263
	 * @param lineTable The line number range that the node corresponds to in the script.
264
	 */
265
	private void processCommand(Node node, Hashtable lineTable) throws CoreException
266
	{
267
		IUIObject commandObject = MacroObjectLocator.lookupReferenceId(getCorrespondingObject(), node, lineTable);
268
		boolean isObjectFound = commandObject != null;
269
		
270
		String cid = isObjectFound ? commandObject.getContextId() : MacroUtil.getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE);
271
		String wid = isObjectFound ? commandObject.getObjectId() : MacroUtil.getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE);		
272
		String rid = isObjectFound ? commandObject.getResolverId() : MacroUtil.getAttribute(node, MacroConstants.RESOLVER_ATTRIBUTE);
273
		String type = MacroUtil.getAttribute(node, MacroConstants.TYPE_ATTRIBUTE);
274
		if (type == null)
275
			return;
276
		AbstractMacroCommand command = null;
277
		WidgetIdentifier wi = (wid != null && cid != null) ? new WidgetIdentifier(new Path(cid), new Path(wid), rid) : null;
278
		
279
		
280
		if (type.equals(ModifyCommand.TYPE))
281
			command = new ModifyCommand(this, wi);
282
		
283
		else if (type.equals(BooleanSelectionCommand.TYPE))
284
			command = new BooleanSelectionCommand(this, wi);
285
		
286
		else if (type.equals(StructuredSelectionCommand.ITEM_SELECT) || type.equals(StructuredSelectionCommand.DEFAULT_SELECT))
287
			command = new StructuredSelectionCommand(this, wi, type);
288
		
289
		else if (type.equals(ExpansionCommand.TYPE))
290
			command = new ExpansionCommand(this, wi);
291
		
292
		else if (type.equals(CheckCommand.TYPE))
293
			command = new CheckCommand(this, wi);
294
		
295
		else if (type.equals(FocusCommand.TYPE))
296
			command = new FocusCommand(this, wi);
297
		
298
		else if (type.equals(ChoiceSelectionCommand.TYPE))
299
			command = new ChoiceSelectionCommand(this, wi);
300
		
301
		else if (type.equals(WaitCommand.TYPE))
302
			command = new WaitCommand(this);
303
		
304
		/* The verification command */
305
		else if (type.equals(VerificationCommand.TYPE))
306
			command = new VerificationCommand(this, new VerificationMetaData());
307
		
308
		/* The close workbench part command */
309
		else if (type.equals(CloseWorkbenchPartCommand.TYPE))
310
			command = new CloseWorkbenchPartCommand(this, wi);
311
		
312
		/* Mouse events */
313
		else if (type.equals(MouseEventCommand.TYPE0) || type.equals(MouseEventCommand.TYPE1) || type.equals(MouseEventCommand.TYPE2))
314
			command = new MouseEventCommand (this);
315
		
316
		/* Key events */
317
		else if (type.equals(KeyEventCommand.TYPE0) || type.equals(KeyEventCommand.TYPE1) || type.equals(KeyEventCommand.TYPE2))
318
			command = new KeyEventCommand (this);
319
		
320
		if (command != null)
321
		{
322
			command.setCorrespondingObject(commandObject);		
323
			command.load(node, lineTable);			
324
			commands.add(command);
325
		}
326
	}
327
328
329
	private void processShell(Node node, Hashtable lineTable) throws CoreException
330
	{
331
		MacroCommandShell shell = new MacroCommandShell(this);
332
		shell.load(node, lineTable);
333
		commands.add(shell);
334
	}
335
336
337
	public void addCommandShell(MacroCommandShell cshell)
338
	{
339
		commands.add(cshell);
340
	}
341
342
	public void write(int indent, StringBuffer sb)
343
	{
344
		/* If this shell command doesn't have any commands, then exit */
345
		if (commands == null || commands.size() <= 0)
346
			return;
347
				
348
		/* <shell */
349
		MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, false, false);
350
		boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn() && getWidgetId().getReferenceId() != null;
351
		MacroUtil.addAttribute(sb, 
352
				new String[] {	MacroConstants.DESCRIPTIVE_ATTRIBUTE,
353
								MacroConstants.RESOLVER_ATTRIBUTE,
354
								MacroConstants.ID_ATTRIBUTE,
355
								MacroConstants.REFERENCE_ID_ATTRIBUTE,
356
								MacroConstants.RETURN_CODE_ATTRIBUTE},
357
				new String[] {	getDescriptiveField(),
358
								objectMineInUse ? null : getWidgetId().getResolverId(),
359
								objectMineInUse ? null : getWidgetId().getObjectId().toString(),
360
								objectMineInUse ? getWidgetId().getReferenceId() : null,
361
								String.valueOf(expectedReturnCode)}, false, true
362
		);
363
		int cindent = indent + 1;
364
		for (int i = 0; i < commands.size(); i++)
365
		{
366
			IWritable writable = (IWritable) commands.get(i);
367
			writable.writeStart(cindent, sb);
368
			writable.write(cindent, sb);
369
			writable.writeFinish(cindent, sb);
370
		}
371
		MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, true, true);
372
	}
373
	
374
	public String getDescriptiveField()
375
	{
376
		return shellTitle == null ? null : MacroUtil.normalizeDescriptiveField(MacroUtil.boundSize(shellTitle, AbstractMacroCommand.DESCRIPTIVE_FIELD_BOUND));
377
	}
378
379
	public void addEvent(Event event)
380
	{
381
		if (event.widget instanceof Control)
382
		{
383
			if (((Control) event.widget).isVisible() == false)
384
				return;
385
		}
386
		
387
		AbstractMacroCommand command = null;
388
		if (event.detail == MacroManager.POSITION_BASED_EVENT)
389
			command = createPositionBasedCommand(event);
390
		else
391
			command = createCommand(event);
392
		
393
		if (command != null)
394
		{			
395
			AbstractMacroCommand lastCommand = getLastCommand();
396
			
397
			/* Take out the last command if it is a focus command and the command just passed in implicitly does a focus */ 
398
			if (lastCommand != null && 
399
					(lastCommand.getWidgetId() != null && lastCommand.getWidgetId().equals(command.getWidgetId()) && lastCommand.getType().equals(FocusCommand.TYPE) && isFocusCommand(command.getType())))
400
			{
401
				// focus followed by select or modify - focus implied
402
				commands.remove(lastCommand);
403
			}
404
			
405
			/* Modify the last event accordinggly */
406
			if (ackEvent)				
407
			{
408
				ackEvent = false;
409
				lastEvent = toBeAckEvent;
410
				toBeAckEvent = null;
411
			}
412
			else
413
			{
414
				lastEvent = event;
415
			}
416
			
417
			/* Add the artificial wait time if required */
418
			if (MacroManager.getInstance().isArtificialWaitOn() && lastCommandCreationTime > 0)
419
			{
420
				long currentTime = System.currentTimeMillis();
421
				long difference = currentTime - lastCommandCreationTime;
422
				command.setTimeDifference(difference);
423
			}
424
			
425
			lastCommandCreationTime = System.currentTimeMillis();
426
			
427
			/* Ali M.: The following block of code provides a workaround for a limitation that
428
			 * exists for CloseWorkbenchPartCommand.  We are only able to capture this event
429
			 * after the entire part has been disposed.  Things would be ideal if this event
430
			 * could be captured right after the user clicks on the close button of the part */			
431
			if (command instanceof CloseWorkbenchPartCommand)
432
			{
433
				int commandSize = commands.size();
434
				if (commandSize > 0)
435
				{
436
					/* If the last command corresponds to the message dialog that prompts the
437
					 * user to save an editor, then store it after the close command */
438
					Object lastCommandStored = commands.get(commandSize - 1);
439
					if (lastCommandStored instanceof MacroCommandShell &&													/* If the last stored command is a shell */ 
440
						((CloseWorkbenchPartCommand)command).getWidgetId().getContextId().equals(MacroConstants.EDITOR_VALUE) &&				/* If the part is an editor */
441
						((MacroCommandShell)lastCommandStored).getWidgetId().getObjectId().equals(MessageDialog.class.getName()))				/* If the shell is a MessageDialog */
442
						
443
					{						
444
						commands.add(commandSize - 1 , command);
445
						return;						
446
					}
447
				}
448
				
449
			}
450
			/* Added for defect 164197 in order to add an item-expansion to the parent whenever the 
451
			 * child is selected in a case where the parent has been pre-expanded.
452
			 * Liz D.
453
			 */
454
			if (command instanceof StructuredSelectionCommand && event.widget instanceof Tree){
455
				
456
				StructuredSelectionCommand s = (StructuredSelectionCommand)command;
457
				
458
				TreeItem[] items = (TreeItem [])s.getItemsForEvent(event);
459
				for (int i=0; i<items.length; i++)
460
				{
461
					TreeItem selectedItem = (TreeItem) items[i];
462
					
463
					while(selectedItem.getParentItem()!=null)
464
					{
465
						TreeItem parent = selectedItem.getParentItem();
466
						if (parent.getExpanded()== true)
467
						{//necessary so that we only apply this in the case where the parent is already expanded
468
							Event expansionEvent = new Event();
469
							expansionEvent.widget = parent;
470
							expansionEvent.item = parent;
471
							ExpansionCommand parentExpand = new ExpansionCommand(this, command.getWidgetId());
472
							parentExpand.processEvent(expansionEvent, true);
473
							commands.add(parentExpand);
474
						}
475
						selectedItem = parent;
476
					}// end while			
477
				}		
478
			}
479
						
480
			commands.add(command);}
481
		
482
	}
483
484
	
485
	/**
486
	 * Adds a wait command for as long as the last command is not already a wait (i.e.
487
	 * duplicate addition of wait commands are avoided through this method)
488
	 */
489
	public void addPause()
490
	{
491
		WaitCommand command = new WaitCommand(this);
492
		
493
		Object lastCommand = null;
494
		int commandSize = commands.size();
495
		boolean isLastCommandWait = false;
496
		
497
		if (commandSize <= 0)
498
			return;
499
		
500
		lastCommand = commands.get (commandSize - 1);
501
		int lastCmdInx = 2;
502
		
503
		/* Avoid MacroCommandShells that have no commands (since these will not be included 
504
		 * as part of the macro) */
505
		while (lastCommand instanceof MacroCommandShell && ((MacroCommandShell)lastCommand).getCommands().size() <= 0) 
506
		{
507
			if (commandSize - lastCmdInx >= 0)
508
				lastCommand = commands.get (commandSize - lastCmdInx);
509
			else
510
			{
511
				lastCommand = null;
512
				break;
513
			}
514
			
515
			lastCmdInx++;
516
		}
517
		
518
		AbstractMacroCommand lastMacroCommand = null;
519
		if (lastCommand instanceof AbstractMacroCommand)
520
			lastMacroCommand = (AbstractMacroCommand)lastCommand;
521
		
522
		isLastCommandWait = lastMacroCommand != null && lastMacroCommand.getType() == WaitCommand.TYPE;
523
		if (commands.size() > 0 && !isLastCommandWait)
524
		{
525
			commands.add(command);				
526
		}
527
	}
528
529
	public void addVerificationCommand (VerificationCommand command)
530
	{
531
		commands.add(command);
532
	}
533
	
534
	public void extractExpectedReturnCode()
535
	{
536
		if (window != null)
537
			expectedReturnCode = window.getReturnCode();
538
	}
539
540
	public boolean matchesReturnCode()
541
	{
542
		if (window != null)
543
		{
544
			return window.getReturnCode() == expectedReturnCode;
545
		}
546
		return true;
547
	}
548
549
	private boolean isFocusCommand(String type)
550
	{
551
		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);
552
	}
553
554
	/**
555
	 * Handles position-based events 
556
	 */
557
	protected AbstractMacroCommand createPositionBasedCommand (Event event)
558
	{
559
		AbstractMacroCommand command = null;
560
		
561
		switch (event.type)
562
		{
563
			case SWT.MouseUp:
564
			case SWT.MouseDown:
565
			case SWT.MouseDoubleClick:
566
				command = new MouseEventCommand (this);			
567
				break;
568
			
569
			case SWT.KeyUp:
570
			case SWT.KeyDown:
571
				command = new KeyEventCommand (this);
572
				break;
573
			
574
		}
575
		
576
		if (command != null)
577
			command.processEvent (event);
578
		return command;
579
	}
580
	
581
	
582
	/**
583
	 *  Handles object-based events
584
	 */
585
	protected AbstractMacroCommand createCommand(Event event)
586
	{	
587
		/* A quick way to get out if we're only getting key up or mouse events that have been detected before */
588
		if ((isKeyPressed && event.type == SWT.KeyUp) || (isMousePressed && event.type == SWT.MouseUp))
589
			return null;
590
		
591
		AbstractMacroCommand lastCommand = getLastCommand();
592
		if (lastEvent != null && lastEvent.widget != null && lastEvent.widget.equals(event.widget))
593
		{
594
			if (lastEvent.type == event.type || (lastEvent.type == SWT.Selection && event.type == SWT.DefaultSelection))
595
			{
596
				if (lastCommand != null && lastCommand.mergeEvent(event))
597
					return null;
598
			}
599
		}
600
				
601
		AbstractMacroCommand command = null;
602
		
603
		/* Check to see if we are a drop-down menu selection */
604
		if (lastCommand != null && lastCommand.getType() == BooleanSelectionCommand.TYPE && 
605
				((BooleanSelectionCommand)lastCommand).getDetail() == SWT.DROP_DOWN)
606
		{
607
			((BooleanSelectionCommand)lastCommand).setItemSelected (event);
608
			return null;
609
		}
610
				
611
		
612
		WidgetIdentifier wi = MacroUtil.getWidgetIdentifier(event.widget);		
613
		if (wi == null)
614
			wi = MacroUtil.getCustomEventIdentifier(event);				
615
		if (wi == null)
616
			return null;
617
		
618
		
619
		switch (event.type)
620
		{
621
			case SWT.Modify:				
622
				if (!isEditable(event.widget))
623
					return null;
624
				
625
				/* This block of code is used to avoid displaying the browse native dialog when the user clicks
626
				 * a browse button - it doesn't cover all cases */
627
				if (lastEvent != null && lastEvent.type == SWT.Selection && lastEvent.widget instanceof Button)
628
				{
629
					String text = ((Button)lastEvent.widget).getText();
630
					if (text != null)
631
					{
632
						text = text.replaceAll("\\&", "");
633
						text = text.toLowerCase();
634
						if (text.indexOf(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BROWSE) != -1)
635
						{
636
							ArrayList commands = this.getCommands();
637
							int size = 0;
638
							if (commands != null && (size = commands.size()) > 0)
639
							{
640
								commands.remove(size - 1);					
641
								command = new ModifyCommand(this, MacroUtil.getWidgetIdentifier(event.widget));
642
								break;
643
							}
644
						}
645
					}				
646
				}
647
				
648
				/* Only acknowledge modifies that are followed by a key up event */
649
				toBeAckEvent = event;								
650
				break;
651
			
652
			case SWT.Selection:
653
			case SWT.DefaultSelection:
654
				command = createSelectionCommand(wi, event);				
655
				break;
656
			
657
			case SWT.FocusIn:
658
				/**
659
				 * Ali M.: While recording, the SWT display listener has the tendency to report
660
				 * focus events on controls that are actually not visible to the user.  When the
661
				 * macro is played back, the control cannot be located.  To avoid this problem
662
				 * we only acknowledge focus events that are followed by a mouse up or key up event (i.e.
663
				 * The user explicitly focuses on the control).
664
				 */
665
				toBeAckEvent = event;
666
				break;
667
			
668
			case SWT.Expand:
669
			case SWT.Collapse:
670
				command = new ExpansionCommand(this, wi);
671
				
672
				break;
673
				
674
			case SWT.KeyUp:
675
				isKeyPressed = true;	
676
				if (toBeAckEvent != null && toBeAckEvent.type == SWT.Modify)
677
				{
678
					command = new ModifyCommand(this, MacroUtil.getWidgetIdentifier(toBeAckEvent.widget));
679
					ackEvent = true;
680
					break;
681
				}
682
				
683
			case SWT.MouseUp:
684
				isMousePressed = true;	
685
				if (toBeAckEvent != null && toBeAckEvent.type == SWT.FocusIn)
686
				{
687
					command = new FocusCommand(this, MacroUtil.getWidgetIdentifier(toBeAckEvent.widget));
688
					ackEvent = true;
689
				}
690
				break;
691
			case Macro.WORKBENCH_PART_CLOSED:
692
				/* 110810 -- Create the close workbench command only if there is only one frame
693
				 * in our shell stack */
694
				if (MacroManager.getInstance().getCurrentMacro().getShellStackSize() == 1)
695
					command = new CloseWorkbenchPartCommand (this, wi); 
696
				break;
697
		}
698
		
699
		if (event.type != SWT.KeyUp)
700
			isKeyPressed = false;
701
		else if (event.type != SWT.MouseUp)
702
			isMousePressed = false;
703
		
704
		
705
		if (command != null)
706
		{
707
			/* Lookup the widget of this command.  If it already exists in our object mine, then
708
			 * have it referenced by setting the reference id of the command. */
709
			IObjectMine objectMine = MacroManager.getInstance().getObjectMine();
710
			IUIObject uiObject = null;
711
			WidgetIdentifier commandWidgetIdentifier = command.getWidgetId();
712
			boolean needsDescriptiveField = false;
713
			try
714
			{
715
				IUIObject activeObject = objectMine.getActiveObject();
716
				uiObject = objectMine.lookupUIObject(activeObject, commandWidgetIdentifier.getContextId() == null ? null : commandWidgetIdentifier.getContextId().toString(), commandWidgetIdentifier.getObjectId().toString());
717
				
718
				/* The object is not registered with the object mine - register it */
719
				if (uiObject == null)
720
				{
721
					needsDescriptiveField = true;
722
					uiObject = UIObject.createInstance(objectMine, command, activeObject);
723
					objectMine.registerObject(uiObject);
724
				}
725
				commandWidgetIdentifier.setReferenceId(uiObject.getReferenceId());				
726
			} 
727
			
728
			/* We can't afford to show an error message in case of an unexpected error during 
729
			 * registeration.  We'll ignore the error and not make use of the object mine. */
730
			catch (UIObjectNotFound e)
731
			{
732
				/* Should not happen */
733
			} catch (IDCollisionException e)
734
			{
735
				/* Should not happen */
736
			} catch (CoreException e)
737
			{
738
				/* Should not happen */
739
			}
740
						
741
			command.processEvent(event);
742
			
743
			if (needsDescriptiveField && uiObject != null)
744
			{
745
				uiObject.setDescriptive(command.getObjectClassName(event.widget) + (command.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING : ": " + command.getDescriptiveField()));
746
			}
747
		}
748
		
749
		/* Ensure that redundant commands are not created */
750
		if (lastCommand != null && command != null && command.isRepeatRedundant() && command.equals(lastCommand))
751
		{
752
			return null;
753
		}
754
		return command;
755
	}
756
757
	private boolean isEditable(Widget widget)
758
	{
759
		if (widget instanceof Control)
760
		{
761
			Control control = (Control) widget;
762
			if (!control.isEnabled())
763
				return false;
764
			if (control instanceof Text)
765
				return ((Text) control).getEditable();
766
			if (control instanceof Combo || control instanceof CCombo)
767
				return ((control.getStyle() & SWT.READ_ONLY) == 0);
768
			if (control instanceof StyledText)
769
				return ((StyledText) control).getEditable();
770
		}
771
		return true;
772
	}
773
774
	private AbstractMacroCommand createSelectionCommand(WidgetIdentifier wid, Event event)
775
	{				
776
		if (event.widget instanceof MenuItem || event.widget instanceof ToolItem || (event.widget instanceof Button
777
				/* A CCombo will cause a button selection followed by a combo selection.  
778
				 * We need to ignore the button selection */
779
				&& !(event.widget instanceof Control && ((Control)event.widget).getParent() instanceof CCombo)))
780
		{						
781
			if (event.x != 0 || event.y != 0 || event.detail != 0)
782
				return new BooleanSelectionCommand(this, wid, new Point (event.x, event.y), event.detail);
783
			return new BooleanSelectionCommand(this, wid);			
784
		}
785
		
786
		if (event.widget instanceof Tree || event.widget instanceof Table || event.widget instanceof List)
787
		{
788
			if (event.detail == SWT.CHECK)
789
				return new CheckCommand(this, wid);
790
			String type = event.type == SWT.DefaultSelection ? StructuredSelectionCommand.DEFAULT_SELECT : StructuredSelectionCommand.ITEM_SELECT;
791
			return new StructuredSelectionCommand(this, wid, type);
792
		}
793
		
794
		if (event.widget instanceof TabFolder || event.widget instanceof CTabFolder)
795
			return new ChoiceSelectionCommand(this, wid);
796
		
797
		if (event.widget instanceof Combo || event.widget instanceof CCombo)
798
			return new ChoiceSelectionCommand(this, wid);
799
		
800
		return null;
801
	}
802
803
804
	private AbstractMacroCommand getLastCommand()
805
	{
806
		if (commands.size() > 0)
807
		{
808
			Object item = commands.get(commands.size() - 1);
809
			if (item instanceof AbstractMacroCommand)
810
				return (AbstractMacroCommand) item;
811
		}
812
		return null;
813
	}
814
815
	public boolean isDisposed()
816
	{
817
		return this.shell != null && this.shell.isDisposed();
818
	}
819
820
	public void close()
821
	{
822
		if (this.shell != null && !this.shell.isDisposed())
823
			this.shell.close();
824
	}
825
826
	public boolean tracks(Shell shell)
827
	{
828
		if (this.shell != null && this.shell.equals(shell))
829
			return true;
830
		return false;
831
	}
832
	
833
	public boolean playback(final Display display, Composite parent, final IProgressMonitor monitor) throws CoreException
834
	{		
835
		if (parent instanceof Shell)
836
		{
837
			this.shell = (Shell) parent;
838
			this.display = display;
839
			hookWindow(true);
840
		}
841
842
		NestedShell nestedShell = null;
843
		int commandSize = commands.size();
844
		monitor.beginTask("", commandSize);
845
		final int commandTimeOut;
846
		
847
		int potentialTimeoutValue = MacroManager.getInstance().getCommandTimeoutThreshold();
848
		if (MacroManager.getInstance().getCommandTimeoutThreshold() > 0)
849
			commandTimeOut = potentialTimeoutValue;
850
		else
851
			commandTimeOut = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD;
852
			
853
		for (int i = 0; i < commandSize; i++)
854
		{
855
			currentCommandInx = i;
856
			checkForInterruptions();							
857
			Object c = commands.get(i);
858
			final IPlayable playable = (IPlayable) c;
859
			
860
			/* If this is the last command of this macro command shell, then take out its entry in the shell queue */	
861
			if (isLastCommand(i))
862
			{
863
				if (getNestedShellQueue() != null && getNestedShellQueue().size() > 0)
864
				{
865
					if (lastNestedShellInx > 0)
866
						lastNestedShellInx--;
867
					removeNestedShell(0);
868
				}
869
			}
870
			
871
			/* If this command is a nested shell, then we need to wait until it completes before proceeding to the next command. */
872
			if (c instanceof MacroCommandShell)
873
			{
874
				MacroCommandShell nestedCommandShell = (MacroCommandShell)c;
875
				//System.out.println("NESTED SHELL WAIT: " + nestedCommandShell.getId());
876
				Object lastNestedCommand = null;
877
				Object currentNestedCommand = null;
878
				synchronized (nestedCommandShell)
879
				{
880
					/* Give each command in the nested shell a maximum of commandTimeOut to execute */
881
					while (!nestedCommandShell.isComplete() && (currentNestedCommand == null || lastNestedCommand != currentNestedCommand) && !interruptProcess)
882
					{
883
						try 
884
						{
885
							nestedCommandShell.wait(commandTimeOut);
886
							lastNestedCommand = currentNestedCommand;
887
							currentNestedCommand = nestedCommandShell.getCommandBeingExecuted();
888
						} catch (InterruptedException e) 
889
						{
890
							/* Handled by next set of code */
891
						}
892
					}
893
					
894
					/* Indicate an error if the nested shell never completed */
895
					if (!nestedCommandShell.isComplete())
896
					{							
897
						synchronized (mutualGlobalLock)
898
						{
899
							interruptProcess = true;
900
							if (interruptedException == null)
901
								interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, 
902
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_NEST_TOUT, nestedCommandShell.getWidgetId().getObjectId().toString()), null));
903
						}
904
						
905
						continue;	/* Interrupt the normal flow */
906
					}
907
					//System.out.println("NESTED SHELL FINISH: " + nestedCommandShell.getId());
908
				}
909
			}
910
			
911
			if (i < commandSize - 1)
912
			{
913
				/* Ali M.: We need to iterate through all the shell commands and register listeners
914
				 * before it's too late.  It's not sufficient to just register a listener with the 
915
				 * next command */
916
				int counter = 1;
917
				IPlayable next = (IPlayable) commands.get(i + counter);
918
				while (next instanceof MacroCommandShell)
919
				{					
920
					/* This command will open a new shell.  Add a listener before it is too late */
921
					MacroCommandShell nestedCommand = (MacroCommandShell) next;
922
					
923
					if (!nestedCommand.isListenerRegistered())
924
					{
925
						nestedShell = new NestedShell(display, nestedCommand, new SubProgressMonitor(monitor, 1));
926
						final NestedShell fnestedShell = nestedShell;
927
928
						
929
						/* If this is a child of the previous shell, then it takes precedence.  If it's a sibling, then it
930
						 * should go to the end of the queue. */
931
						nestedCommand.setListenerRegistered(true);
932
						if (nestedShellQueue.size() > 0 && ((NestedShell)nestedShellQueue.get(0)).isParent(nestedCommand))
933
						{
934
							addNestedShell(0, fnestedShell);
935
							lastNestedShellInx = 0;
936
						}
937
						else
938
						{
939
							if (nestedShellQueue.size() > 0)
940
								addNestedShell(++lastNestedShellInx, fnestedShell);
941
							else
942
								addNestedShell(fnestedShell);							
943
						}
944
						
945
						display.syncExec(new Runnable()
946
								{
947
									public void run()
948
									{
949
										//System.out.println("ADDED");
950
										display.addFilter(SWT.Activate, fnestedShell);
951
									}
952
								});						
953
					}
954
					counter++;
955
					next = (i + counter <= commandSize - 1 ? (IPlayable) commands.get(i + counter) : null);					
956
				}
957
			}
958
			if (playable instanceof AbstractMacroCommand)
959
			{			
960
				final boolean last = i == commandSize - 1;	
961
				
962
				
963
				class WakeUpOperaion implements Runnable
964
				{
965
					private AbstractMacroCommand command;
966
					private boolean invalidate;
967
					
968
					public WakeUpOperaion (AbstractMacroCommand command)
969
					{
970
						this.command = command;
971
						invalidate = false;
972
					}
973
					
974
					public void run() 
975
					{
976
						if (!invalidate && MacroCommandShell.lastCommandLineExecuted == command.getStartLine())
977
						{
978
							/* Ali M.: A command just timed-out.  We need to indicate the error 
979
							 * and wakeup the thread */
980
							synchronized (mutualGlobalLock)
981
							{
982
								interruptProcess = true;								
983
								if (interruptedException == null)
984
									interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, 
985
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, command.toString()), null));
986
							}
987
							
988
							synchronized (mutualLock)
989
							{
990
								mutualLock.notify();
991
							}
992
						}
993
					}
994
					
995
					public void invalidate()
996
					{
997
						this.invalidate = true;
998
					}
999
1000
				}					
1001
				WakeUpOperaion wakeupOpt = null;
1002
				if (i < commandSize - 1)
1003
				{				
1004
					wakeupOpt = new WakeUpOperaion ((AbstractMacroCommand)playable);
1005
					final Runnable wakeupOperation = wakeupOpt;					
1006
					display.asyncExec(
1007
						new Runnable()
1008
						{
1009
							public void run() 
1010
							{
1011
								display.timerExec(commandTimeOut, wakeupOperation);
1012
							};
1013
							
1014
						}	
1015
					);
1016
				}
1017
					
1018
				
1019
				class RunCommandOperation implements Runnable
1020
				{
1021
					private boolean isComplete;
1022
					
1023
					public void run()
1024
					{ 
1025
						try 
1026
						{						
1027
							if (!macroCommandsBeingPlayed.contains(this))
1028
								macroCommandsBeingPlayed.add(this);
1029
							
1030
							lastCommandLineExecuted = ((AbstractMacroCommand)playable).getStartLine();
1031
							playInGUIThread(display, playable, last, monitor);	
1032
							
1033
							macroCommandsBeingPlayed.remove(this);
1034
							isComplete = true;
1035
							synchronized (mutualLock) 
1036
							{
1037
								mutualLock.notify();
1038
							}
1039
						}
1040
						catch (Throwable e) 
1041
						{					
1042
							macroCommandsBeingPlayed.remove(this);
1043
							synchronized (mutualGlobalLock)
1044
							{
1045
								interruptProcess = true;
1046
								if (interruptedException == null)
1047
									interruptedException = e;
1048
							}
1049
							isComplete = true;
1050
							synchronized (mutualLock)
1051
							{
1052
								mutualLock.notify();
1053
							}
1054
						} 
1055
					} 
1056
					
1057
					public boolean isComplete()
1058
					{
1059
						return isComplete;
1060
					}
1061
1062
				}
1063
				
1064
				RunCommandOperation runCommandOpt = new RunCommandOperation();
1065
				
1066
1067
				/* Run the command */
1068
				synchronized (mutualLock)
1069
				{					
1070
					new Thread(runCommandOpt).start();
1071
					long start = System.currentTimeMillis();
1072
					long wakeUpTime = start;
1073
					long timeToSleep = commandTimeOut;
1074
					try 
1075
					{
1076
						while (!runCommandOpt.isComplete() && timeToSleep > 0 && !interruptProcess)
1077
						{
1078
							//System.out.println("WAITING on command: " + playable);
1079
							mutualLock.wait(timeToSleep);
1080
							wakeUpTime = System.currentTimeMillis();
1081
							timeToSleep = timeToSleep - (wakeUpTime - start);
1082
						}
1083
					} catch (InterruptedException e) 
1084
					{
1085
						/* Doesn't need to be handled */
1086
					}
1087
					
1088
					/* Indicate an error if command didn't complete */
1089
					if (!runCommandOpt.isComplete())
1090
					{	
1091
						synchronized (mutualGlobalLock)
1092
						{
1093
							interruptProcess = true;
1094
							if (interruptedException == null)
1095
								interruptedException = new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, 
1096
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT, playable.toString()), null));							
1097
						}
1098
					}	
1099
					/* Otherwise invalidate the wake up operation that was suppose to wake this
1100
					command up */
1101
					else if (wakeupOpt != null)
1102
						wakeupOpt.invalidate();
1103
					
1104
					//System.out.println("FINISHED WAITING on command: " + playable);
1105
				}
1106
								
1107
				monitor.worked(1);
1108
			} 			
1109
		}
1110
		
1111
		checkForInterruptions();
1112
		shell = null;
1113
		
1114
		/* We made it out alive -- mark this as complete and wake any parents that are waiting upon our completion */
1115
		isComplete = true;
1116
		synchronized(this)
1117
		{
1118
			this.notify();
1119
		}
1120
		
1121
		macroCommandShellContainer.remove(this);
1122
		return true;
1123
	}
1124
1125
1126
	private boolean isComplete() 
1127
	{	
1128
		return isComplete;
1129
	}
1130
1131
	private Object getCommandBeingExecuted() 
1132
	{
1133
		if (commands == null || currentCommandInx >= commands.size())
1134
			return null;
1135
		return commands.get(currentCommandInx);
1136
	}
1137
1138
	private void checkForInterruptions() throws CoreException
1139
	{
1140
		if (interruptProcess)
1141
		{	
1142
			/* Wake up all threads in case they are asleep */
1143
			if (!processTerminated)
1144
			{
1145
				processTerminated = true;
1146
				interruptOperation();				
1147
				MacroCommandShell.macroStopped();
1148
				MacroUtil.closeSecondaryShells(display);			
1149
			}
1150
						
1151
			for (int i = 0; i < macroCommandShellContainer.size(); i++)
1152
			{
1153
				synchronized (mutualLock)
1154
				{
1155
					mutualLock.notify();
1156
				}
1157
				
1158
				synchronized (macroCommandShellContainer.get(i))
1159
				{
1160
					macroCommandShellContainer.get(i).notify();
1161
				}
1162
			}
1163
			
1164
			/* Try to close all nested shells */
1165
			synchronized (mutualGlobalLock)
1166
			{
1167
				if (interruptedException instanceof CoreException)
1168
					throw (CoreException)interruptedException;
1169
				throw new CoreException (new Status(IStatus.ERROR, GuiPlugin.getID(), 0, interruptedException.getLocalizedMessage(), interruptedException));
1170
			}
1171
		}
1172
		
1173
	}
1174
1175
	/**
1176
	 * A helper method that walks through all macro command shells and 
1177
	 * interrupts their normal flow.
1178
	 */
1179
	private void interruptOperation() 
1180
	{
1181
		MacroCommandShell currentMacroShell = this;
1182
		while (currentMacroShell != null)
1183
		{
1184
			Boolean lock = currentMacroShell.mutualLock;
1185
			synchronized(lock)
1186
			{
1187
				lock.notify();
1188
			}
1189
			
1190
			currentMacroShell = currentMacroShell.getParent();
1191
		}
1192
		
1193
	}
1194
1195
	private boolean isLastCommand(int index) 
1196
	{
1197
		for (int i = index + 1; i < commands.size(); i++)
1198
		{
1199
			if (commands.get(i) instanceof AbstractMacroCommand)
1200
				return false;
1201
		}
1202
		return true;
1203
	}
1204
1205
	private void playInGUIThread(final Display display, final IPlayable playable, boolean last, final IProgressMonitor monitor) throws CoreException
1206
	{
1207
		final CoreException[] ex = new CoreException[1];
1208
1209
		Runnable runnable = new Runnable()
1210
		{
1211
			public void run()
1212
			{
1213
				try
1214
				{						
1215
					boolean status = playable.playback(display, MacroCommandShell.this.shell, monitor);
1216
					
1217
					/* Something went wrong playing this item */
1218
					if (!status)
1219
						ex[0] = createPlaybackException(playable, null);
1220
					else
1221
						MacroUtil.processDisplayEvents(display);
1222
				} 
1223
				catch (ClassCastException e)
1224
				{
1225
					ex[0] = createPlaybackException(playable, e);
1226
				} 
1227
				catch (CoreException e)
1228
				{
1229
					ex[0] = e;
1230
				}
1231
				catch (SWTException e)
1232
				{
1233
					/* Don't handle */
1234
				}
1235
				catch (Throwable error)
1236
				{
1237
					ex[0] = createPlaybackException(playable, error);
1238
				}
1239
			}
1240
		};
1241
1242
		if (playable instanceof WaitCommand)
1243
		{
1244
			playable.playback(display, this.shell, monitor);
1245
		} 
1246
		else
1247
		{
1248
			display.syncExec(runnable);			
1249
		}
1250
					
1251
		try
1252
		{
1253
			Thread.sleep(100);
1254
		} catch (InterruptedException e)
1255
		{
1256
		}
1257
1258
		if (ex[0] != null)
1259
			throw ex[0];
1260
				
1261
	}
1262
1263
	private CoreException createPlaybackException(IPlayable playable, Throwable th)
1264
	{
1265
		IStatus status = new Status(IStatus.ERROR, "org.eclipse.pde.ui.tests", IStatus.OK, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_COMMAND, playable.toString()), th);
1266
		return new CoreException(status);
1267
	}
1268
	
1269
	
1270
	public ArrayList getCommands()
1271
	{
1272
		return commands;
1273
	}
1274
1275
	public boolean isListenerRegistered() {
1276
		return isListenerRegistered;
1277
	}
1278
1279
	public void setListenerRegistered(boolean isListenerRegistered) {
1280
		this.isListenerRegistered = isListenerRegistered;
1281
	}
1282
1283
	public static Vector getNestedShellQueue() 
1284
	{
1285
		return nestedShellQueue;
1286
	}
1287
	
1288
	public static void addNestedShell(int inx, NestedShell nestedShell)
1289
	{
1290
		synchronized (nestedShellQueue)
1291
		{
1292
			if (inx >= 0)
1293
				nestedShellQueue.add(inx, nestedShell);
1294
			else
1295
				nestedShellQueue.add(nestedShell);
1296
		}
1297
	}
1298
	
1299
	private static void addNestedShell(NestedShell fnestedShell) 
1300
	{
1301
		addNestedShell (-1, fnestedShell);		
1302
	}
1303
	
1304
	
1305
	public static void removeNestedShell(int inx)
1306
	{
1307
		synchronized (nestedShellQueue)
1308
		{
1309
			nestedShellQueue.remove(inx);
1310
		}
1311
	}
1312
	
1313
	
1314
	public static void initializeForNewPlay()
1315
	{
1316
		nestedShellQueue.clear();
1317
		lastNestedShellInx = 0;
1318
		interruptProcess = false;
1319
		processTerminated = false;
1320
		interruptedException = null;
1321
		MouseEventCommand.init();
1322
		macroCommandsBeingPlayed.clear();
1323
		macroCommandShellContainer.clear();
1324
	}
1325
1326
	public Shell getShell() {
1327
		return shell;
1328
	}
1329
	
1330
	public void writeStart(int indent, StringBuffer sb)
1331
	{
1332
		/* Doesn't need to be implemented */		
1333
	}
1334
1335
	public void writeFinish(int indent, StringBuffer sb)
1336
	{
1337
		/* Doesn't need to be implemented */	
1338
	}
1339
1340
	public MacroCommandShell getParent() {
1341
		return parent;
1342
	}
1343
1344
	public void setParent(MacroCommandShell parent) {
1345
		this.parent = parent;
1346
	}
1347
1348
	public static void macroStopped() 
1349
	{
1350
		/* Walk through nested shell listeners and remove them if any exists */
1351
		final Display display = GuiPlugin.getDefault().getWorkbench().getDisplay();
1352
		display.syncExec(new Runnable(){
1353
1354
			public void run() {
1355
				for (int i = 0, nestedShellListenerSize = nestedShellQueue.size(); i < nestedShellListenerSize; i++)
1356
				{
1357
					display.removeFilter(SWT.Activate, (NestedShell)nestedShellQueue.get(i));	
1358
				}				
1359
			}
1360
		});					
1361
	}
1362
1363
	public static Vector getMacroCommandsBeingPlayed() {
1364
		return macroCommandsBeingPlayed;
1365
	}
1366
		
1367
	public String getReferenceId()
1368
	{
1369
		return referenceId;
1370
	}
1371
1372
	public void setReferenceId(String referenceId)
1373
	{
1374
		this.referenceId = referenceId;
1375
	}
1376
	
1377
	
1378
	private static class NestedShell implements Listener, Runnable
1379
	{
1380
		private MacroCommandShell cshell;
1381
1382
		private Display display;
1383
1384
		private Shell nshell;
1385
1386
		private IProgressMonitor monitor;
1387
1388
		private boolean served;		
1389
				
1390
		public NestedShell(Display display, MacroCommandShell cshell, IProgressMonitor monitor)
1391
		{
1392
			this.display = display;
1393
			this.cshell = cshell;
1394
			this.monitor = monitor;
1395
		}
1396
1397
		public void handleEvent(Event e)
1398
		{
1399
			try
1400
			{
1401
				if (e.widget instanceof Shell)
1402
				{
1403
					// shell activated
1404
					Shell shell = (Shell) e.widget;
1405
					IPath path = new Path(MacroUtil.getShellId(shell, null).toString());
1406
					String sid = path.toString();
1407
					
1408
					/* Debug */
1409
					//System.out.println();
1410
					//System.out.println(sid + " : " + cshell.getId());
1411
					//if (MacroCommandShell.getNestedShellQueue() != null && MacroCommandShell.getNestedShellQueue().size() > 0)
1412
						//System.out.println("Is Served: " + ((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed());
1413
					//System.out.println(this + " : " + MacroCommandShell.getNestedShellQueue().get(0));
1414
					//System.out.println();  
1415
					
1416
					if (sid.equals(cshell.getWidgetId().getObjectId().toString()) && 
1417
									(MacroCommandShell.getNestedShellQueue() == null || 
1418
									MacroCommandShell.getNestedShellQueue().size() <= 0 || 
1419
									(!((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed() && this.equals(MacroCommandShell.getNestedShellQueue().get(0)))))
1420
					{
1421
						//System.out.println("REMOVED FILTER: " + cshell.getId());
1422
						shell.getDisplay().removeFilter(SWT.Activate, this);
1423
						this.nshell = shell;
1424
						
1425
						/* We need to start this in a separate thread.  MacroCommandShells should not be played in UI threads (otherwise wait commands
1426
						 * will not work properly) */					
1427
						this.setServed(true);
1428
						new Thread(this).start();					
1429
					}
1430
				}
1431
			}
1432
			catch (Throwable t)
1433
			{
1434
				//System.out.println("REMOVED filter");
1435
				/* Something unexpected has happened -- Remove this listener */
1436
				e.display.removeFilter(SWT.Activate, this);
1437
			}
1438
		}
1439
1440
		public void setServed(boolean served) 
1441
		{
1442
			this.served = served;			
1443
		}
1444
		
1445
		public boolean isServed()
1446
		{
1447
			return served;
1448
		}
1449
1450
		public void run()
1451
		{
1452
			try
1453
			{				
1454
				cshell.playback(display, nshell, monitor);					
1455
			} 
1456
			catch (CoreException e)
1457
			{
1458
				synchronized (mutualGlobalLock)
1459
				{
1460
					interruptProcess = true;
1461
					if (interruptedException == null)
1462
						interruptedException = e;
1463
				}
1464
				
1465
				synchronized (cshell.mutualLock)
1466
				{
1467
					cshell.mutualLock.notify();
1468
				}
1469
			}
1470
		}
1471
1472
		public boolean isParent(MacroCommandShell macroCommandShell) 
1473
		{
1474
			return macroCommandShell.getParent().equals(cshell);			
1475
		}
1476
	}
1477
	
1478
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/CommandTarget.java (-43 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import org.eclipse.swt.widgets.*;
14
import org.eclipse.swt.widgets.Widget;
15
16
public class CommandTarget {
17
	private Widget widget;
18
	private Object context;
19
	
20
	public CommandTarget(Widget widget, Object context) {
21
		this.widget = widget;
22
		this.context = context;
23
	}
24
25
	public void ensureVisible() {
26
	}
27
	
28
	public Widget getWidget() {
29
		return widget;
30
	}
31
	public Object getContext() {
32
		return context;
33
	}
34
	public void setFocus() {
35
		ensureVisible();
36
		Display display = widget.getDisplay();
37
		if (widget instanceof Control) {
38
			Control c = (Control)widget;
39
			if (!c.equals(display.getFocusControl()))
40
				c.setFocus();
41
		}
42
	}
43
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/WindowCommandTarget.java (-36 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
13
import org.eclipse.jface.window.Window;
14
import org.eclipse.swt.widgets.Widget;
15
16
public class WindowCommandTarget extends CommandTarget {
17
	/**
18
	 * @param widget
19
	 * @param context
20
	 */
21
	public WindowCommandTarget(Widget widget, Window window) {
22
		super(widget, window);
23
	}
24
	
25
	Window getWindow() {
26
		return (Window)getContext();
27
	}
28
29
	/* (non-Javadoc)
30
	 * @see org.eclipse.ui.macro.CommandTarget#ensureVisible()
31
	 */
32
	public void ensureVisible() {
33
		Window window = getWindow();
34
		window.getShell().setActive();
35
	}
36
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/StructuredSelectionCommand.java (-162 / +128 lines)
Lines 1-163 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
11
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
12
13
13
import java.util.ArrayList;
14
import java.util.ArrayList;
14
import java.util.Iterator;
15
import java.util.Iterator;
15
import java.util.Map;
16
import java.util.Map;
16
17
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.List;
20
import org.eclipse.swt.widgets.List;
20
import org.eclipse.swt.widgets.Table;
21
import org.eclipse.swt.widgets.Table;
21
import org.eclipse.swt.widgets.TableItem;
22
import org.eclipse.swt.widgets.TableItem;
22
import org.eclipse.swt.widgets.Tree;
23
import org.eclipse.swt.widgets.Tree;
23
import org.eclipse.swt.widgets.TreeItem;
24
import org.eclipse.swt.widgets.TreeItem;
24
import org.eclipse.swt.widgets.Widget;
25
import org.eclipse.swt.widgets.Widget;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
26
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
26
27
import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId;
27
public class StructuredSelectionCommand extends AbstractStructuredCommand {
28
28
29
public class StructuredSelectionCommand extends AbstractStructuredCommand 
29
	private String type;
30
{
30
	
31
	private String type;
31
	public StructuredSelectionCommand(MacroCommandShell parent, String type) {
32
	public static final String DEFAULT_SELECT="default-select";
32
		super(parent);
33
	public static final String ITEM_SELECT="item-select";
33
		items = new ArrayList();
34
	
34
		this.type = type;
35
	public StructuredSelectionCommand(MacroCommandShell parent, WidgetIdentifier wid, String type) {
35
	}
36
		super(parent, wid);
36
37
		items = new ArrayList();
37
	public boolean mergeEvent(Event e) throws Exception {
38
		this.type = type;
38
		if (e.detail == SWT.CHECK)
39
	}
39
			return false;
40
40
41
	public boolean mergeEvent(Event e) 
41
		if (e.type == SWT.DefaultSelection) {
42
	{
42
			this.type = DEFAULT_SELECT;
43
		if (e.detail == SWT.CHECK)
43
		}
44
			return false;
44
		return super.mergeEvent(e);
45
		
45
	}
46
		if (e.type==SWT.DefaultSelection) 
46
47
		{
47
	public String getType() {
48
			this.type = DEFAULT_SELECT;
48
		return type;
49
		}
49
	}
50
		
50
51
		// If the selected item number is 1, and the old and new item are the same, then merge.
51
	public Object[] getItemsForEvent(Event event) {
52
		// Otherwise, do not merge, so that different command of selecting different items
52
		if (event.widget instanceof Tree) {
53
		// can be generated.
53
			return ((Tree) event.widget).getSelection();
54
		Object[] eventItems = getItemsForEvent(e);
54
		}
55
		if (eventItems.length == 1)
55
		else if (event.widget instanceof Table) {
56
		{
56
			return ((Table) event.widget).getSelection();
57
			ArrayList newItems = new ArrayList();
57
		}
58
			Map attributeValuePairs = null;
58
		else if (event.widget instanceof List) {
59
			
59
			return ((List) event.widget).getSelection();
60
			if (eventItems[0] instanceof Widget)
60
		}
61
				attributeValuePairs = getItemAttributes((Widget)eventItems[0]);
61
		return super.getItemsForEvent(event);
62
			else
62
	}
63
				attributeValuePairs = getItemAttributes(null, new PrimitiveWidgetId((String)eventItems[0]));
63
64
			
64
	protected void playStructuredCommand(Widget widget, Object[] matches) {
65
			if (attributeValuePairs != null)
65
66
				newItems.add(attributeValuePairs);
66
		if (widget instanceof Tree)
67
			
67
			((Tree) widget).setSelection((TreeItem[]) matches);
68
			if (!isSameList(items, newItems))
68
		else if (widget instanceof Table)
69
				return false;
69
			((Table) widget).setSelection((TableItem[]) matches);
70
		}
70
		else if (widget instanceof List)
71
		
71
			((List) widget).setSelection((String[]) matches);
72
		return super.mergeEvent(e);
72
73
	}
73
		fireEvent(widget,
74
	
74
			matches);
75
	public String getType() {
75
	}
76
		return type;
76
77
	}
77
	private void fireEvent(Widget widget, Object[] items) {
78
78
		Event e = new Event();
79
	protected Object[] getItemsForEvent(Event event) 
79
		e.widget = widget;
80
	{
80
		e.type = type.equals(ITEM_SELECT)
81
		if (event.widget instanceof Tree) 
81
			? SWT.Selection
82
		{
82
			: SWT.DefaultSelection;
83
			return ((Tree)event.widget).getSelection();
83
		e.item = (items.length > 0 && items instanceof Widget[]
84
		}
84
			? (Widget) items[0]
85
		else if (event.widget instanceof Table) 
85
			: null);
86
		{
86
		widget.notifyListeners(e.type,
87
			return ((Table)event.widget).getSelection();
87
			e);
88
		}
88
	}
89
		else if (event.widget instanceof List)
89
90
		{
90
	/**
91
			return ((List)event.widget).getSelection();
91
	 * Overwrite this method in order to indicate that two item selection commands that have different items are not the same
92
		}
92
	 */
93
		return super.getItemsForEvent(event);
93
	public boolean equals(Object obj) {
94
	}
94
		if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj))
95
95
			return false;
96
	protected void playStructuredCommand(Widget widget, Object[] matches) 
96
97
	{
97
		StructuredSelectionCommand compareWithObj = (StructuredSelectionCommand) obj;
98
		
98
		if (compareWithObj.items.size() == this.items.size() && isSameList(compareWithObj.items,
99
		if (widget instanceof Tree)
99
			this.items))
100
			((Tree)widget).setSelection((TreeItem[])matches);
100
			return true;
101
		else if (widget instanceof Table)
101
102
			((Table)widget).setSelection((TableItem[])matches);
102
		return false;
103
		else if (widget instanceof List)
103
	}
104
			((List)widget).setSelection((String[])matches);
104
105
		
105
	private boolean isSameList(ArrayList listA, ArrayList listB) {
106
		fireEvent(widget, matches);
106
		if (listA.size() != listB.size())
107
	}
107
			return false;
108
	
108
109
	private void fireEvent(Widget widget, Object[] items)
109
		for (int i = 0, listSize = listA.size(); i < listSize; i++) {
110
	{
110
			Map itemDataA = (Map) listA.get(i);
111
		Event e = new Event();
111
			Map itemDataB = (Map) listB.get(i);
112
		e.widget = widget;
112
113
		e.type = type.equals(ITEM_SELECT)?SWT.Selection:SWT.DefaultSelection;
113
			if (itemDataA.size() != itemDataB.size())
114
		e.item = (items.length>0 && items instanceof Widget[] ? (Widget)items[0] : null);		
114
				return false;
115
		widget.notifyListeners(e.type, e);
115
116
	}
116
			for (Iterator keys = itemDataA.keySet().iterator(); keys.hasNext();) {
117
	
117
				Object currentKey = keys.next();
118
	/**
118
				if (!itemDataA.get(currentKey).equals(itemDataB.get(currentKey)))
119
	 * Overwrite this method in order to indicate that two item selection commands that have
119
					return false;
120
	 * different items are not the same
120
			}
121
	 */
121
		}
122
	public boolean equals (Object obj)
122
123
	{
123
		return true;
124
		if (!(obj instanceof ChoiceSelectionCommand) || !super.equals(obj))
124
	}
125
			return false;
125
126
		
126
	protected void playStructuredCommandForFoundMatch(Widget widget, Object match) {
127
		StructuredSelectionCommand compareWithObj = (StructuredSelectionCommand)obj;
127
		/* Doesn't need to be implemented */
128
		if (compareWithObj.items.size() == this.items.size() && isSameList(compareWithObj.items, this.items))
128
	}
129
			return true;
130
		
131
		return false;
132
	}
133
134
	private boolean isSameList(ArrayList listA, ArrayList listB) 
135
	{
136
		if (listA.size() != listB.size())
137
			return false;
138
		
139
		for (int i = 0, listSize = listA.size(); i < listSize; i++)
140
		{
141
			Map itemDataA = (Map)listA.get(i);
142
			Map itemDataB = (Map)listB.get(i);
143
			
144
			
145
			if (itemDataA.size() != itemDataB.size())
146
				return false;
147
			
148
			for(Iterator keys = itemDataA.keySet().iterator(); keys.hasNext();)
149
			{
150
				Object currentKey = keys.next();
151
				if (!itemDataA.get(currentKey).equals(itemDataB.get(currentKey)))
152
					return false;
153
			}
154
		}
155
		
156
		return true;
157
	}
158
159
	protected void playStructuredCommandForFoundMatch(Widget widget, Object match) 
160
	{
161
		/* Doesn't need to be implemented */
162
	}
163
}
129
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/KeyEventCommand.java (-172 / +150 lines)
Lines 1-172 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: KeyEventCommand.java,v 1.2 2006/10/27 14:39:12 amehregani Exp $
7
 * $Id: KeyEventCommand.java,v 1.2 2006/10/27 14:39:12 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
13
14
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Hashtable;
15
16
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
21
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
22
import org.w3c.dom.Node;
22
import org.w3c.dom.Node;
23
23
24
/**
24
/**
25
 * A concrete extension of PositionBasedCommand that is used to represent SWT.KeyUp
25
 * A concrete extension of PositionBasedCommand that is used to represent
26
 * and SWT.KeyDown events.
26
 * SWT.KeyUp and SWT.KeyDown events.
27
 * 
27
 * 
28
 * @author Ali Mehregani
28
 * @author Ali Mehregani
29
 */
29
 * @author Alexander Nyssen (refactoring)
30
public class KeyEventCommand extends PositionBasedCommand 
30
 */
31
{
31
public class KeyEventCommand extends PositionBasedCommand {
32
	public static String TYPE0 = "key-up";
32
33
	public static String TYPE1 = "key-down";
33
	private boolean isCharSet; /*
34
	public static String TYPE2 = "key-press";
34
								 * Set when the character field of event is used
35
	
35
								 * as opposed to the keyCode
36
	private String type; 		/* The type of the event (either TYPE0 or TYPE1) */
36
								 */
37
	private int button;			/* The key pressed or released */ 
37
38
	private boolean isCharSet;	/* Set when the character field of event is used as opposed to 
38
	public KeyEventCommand(MacroCommandShell parent) {
39
								   the keyCode */
39
		super(parent);
40
	public KeyEventCommand(MacroCommandShell parent) 
40
	}
41
	{
41
42
		super(parent, null);
42
	public String getType() {
43
	}
43
		return type;
44
44
	}
45
	public String getType()
45
46
	{
46
	public boolean mergeEvent(Event e) throws Exception {
47
		return type;
47
		/*
48
	}
48
		 * Defect #: 110726 -- Make the key events consistent with the mouse
49
49
		 * event and introduce a notion of key-press
50
	public void processEvent(Event e) 
50
		 */
51
	{
51
		if (e.type == SWT.KeyUp && type != null && type.equals(KEY_DOWN)
52
		if (e.character > 0)
52
				&& isCharSet(e) ? isCharSet && detail.intValue() == e.character
53
		{
53
				: !isCharSet && detail.intValue() == e.keyCode) {
54
			button =  e.character;
54
55
			isCharSet = true;
55
			type = KEY_PRESS;
56
		}
56
			return true;
57
		else if (e.keyCode > 0)
57
		}
58
			button = e.keyCode;
58
		return false;
59
		
59
	}
60
		if (e.type == SWT.KeyUp)
60
61
		{
61
	private boolean isCharSet(Event e) {
62
			/* Defect #: 110726 -- Make the key events consistent with the mouse event and 
62
		return e.character > 0;
63
			 * introduce a notion of key-press */			
63
	}
64
			ArrayList commands = getParent().getCommands();
64
65
			int commandSize;
65
	protected Integer determineDetail(Event e) {
66
			if (commands != null && (commandSize = commands.size()) > 0)
66
		Integer detail = null;
67
			{
67
		if (e.character > 0) {
68
				Object lastCommand = commands.get(commandSize - 1);
68
			detail = new Integer(e.character);
69
				if (lastCommand instanceof KeyEventCommand)
69
70
				{
70
		} else if (e.keyCode > 0) {
71
					int lastButton = ((KeyEventCommand)lastCommand).getButton();
71
			detail = new Integer(e.keyCode);
72
					boolean lastIsCharSet = ((KeyEventCommand)lastCommand).isCharSet();
72
		}
73
					if (button == lastButton && isCharSet == lastIsCharSet)
73
		return detail;
74
					{
74
	}
75
						type = TYPE2;
75
76
						commands.remove(commandSize - 1);
76
	protected String determineType(Event e) {
77
						return;
77
		String type = null;
78
					}
78
		if (e.type == SWT.KeyUp) {
79
				}				
79
			type = KEY_UP;
80
			}
80
		} else if (e.type == SWT.KeyDown) {
81
			
81
			type = KEY_DOWN;
82
			type = TYPE0;
82
		}
83
			type = TYPE0;
83
		return type;
84
		}
84
	}
85
		else if (e.type == SWT.KeyDown)
85
86
			type = TYPE1;
86
	public void processEvent(Event e) throws Exception {
87
	}
87
		super.processEvent(e);
88
	
88
89
	public void load(Node node, Hashtable lineTable) throws CoreException
89
		isCharSet = e.character > 0;
90
	{
90
	}
91
		super.load(node, lineTable);
91
92
		
92
	public void load(Node node, Hashtable lineTable) throws CoreException {
93
		type = MacroUtil.getAttribute(node, "type");
93
		super.load(node, lineTable);
94
		button = Integer.parseInt(MacroUtil.getAttribute(node, "detail"));
94
95
		if (MacroConstants.TRUE_VALUE.equals(MacroUtil.getAttribute(node, "ischarset")))
95
		if (MacroConstants.TRUE_VALUE.equals(MacroUtil.getAttribute(node,
96
			isCharSet = true;
96
				"ischarset")))
97
	}
97
			isCharSet = true;
98
	
98
	}
99
	public void write(int indent, StringBuffer sb, boolean close, boolean end)
99
100
	{		
100
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
101
		super.write(indent, sb, close, end);
101
		super.write(indent, sb, false, false);
102
		MacroUtil.addAttribute(sb, 
102
		MacroUtil.addAttribute(sb,
103
				new String[] {MacroConstants.IS_CHAR_SET_ATTRIBUTE}, 
103
				new String[] { MacroConstants.IS_CHAR_SET_ATTRIBUTE },
104
				new String[] {String.valueOf(isCharSet)}, true, true);		
104
				new String[] { String.valueOf(isCharSet) }, true, true);
105
	}
105
	}
106
	
106
107
107
	public Event[] constructSWTEvents() {
108
	public int getDetail()
108
		Event[] events;
109
	{
109
110
		return button;
110
		if (type.equals(KEY_PRESS))
111
	}
111
			events = new Event[2];
112
112
		else
113
	public Event[] constructSWTEvents() 
113
			events = new Event[1];
114
	{
114
115
		Event[] events;
115
		Event keyUpEvent = new Event(), keyDownEvent = new Event();
116
		
116
		keyUpEvent.type = SWT.KeyUp;
117
		if (type.equals(TYPE2))
117
		keyDownEvent.type = SWT.KeyDown;
118
			events = new Event[2];
118
119
		else
119
		if (isCharSet) {
120
			events = new Event[1];
120
			keyUpEvent.character = (char) detail.intValue();
121
		
121
			keyDownEvent.character = (char) detail.intValue();
122
		Event keyUpEvent = new Event(), keyDownEvent = new Event();
122
		} else {
123
		keyUpEvent.type = SWT.KeyUp;
123
			keyUpEvent.keyCode = detail.intValue();
124
		keyDownEvent.type = SWT.KeyDown;
124
			keyDownEvent.keyCode = detail.intValue();
125
		
125
		}
126
		if (isCharSet)
126
127
		{
127
		if (type.equals(KEY_UP))
128
			keyUpEvent.character = (char) button;
128
			events[0] = keyUpEvent;
129
			keyDownEvent.character = (char) button;
129
		else if (type.equals(KEY_DOWN))
130
		}
130
			events[0] = keyDownEvent;
131
		else
131
		else if (type.equals(KEY_PRESS)) {
132
		{
132
			events[0] = keyDownEvent;
133
			keyUpEvent.keyCode = button;
133
			events[1] = keyUpEvent;
134
			keyDownEvent.keyCode = button;			
134
		}
135
		}
135
136
		
136
		return events;
137
		
137
	}
138
		if (type.equals(TYPE0))
138
139
			events[0] = keyUpEvent;
139
	public boolean equals(Object obj) {
140
		else if (type.equals(TYPE1))
140
		if (!(obj instanceof KeyEventCommand))
141
			events[0] = keyDownEvent;		
141
			return false;
142
		else if (type.equals(TYPE2))
142
143
		{
143
		KeyEventCommand keyEvent = (KeyEventCommand) obj;
144
			events[0] = keyDownEvent;
144
		if (this.type.equals(keyEvent.getType())
145
			events[1] = keyUpEvent;
145
				&& this.detail == keyEvent.getDetail())
146
		}
146
			return true;
147
		
147
		return false;
148
		return events;		
148
	}
149
	}
149
150
	
150
}
151
	public boolean equals (Object obj)
152
	{
153
		if (!(obj instanceof KeyEventCommand))
154
			return false;
155
		
156
		KeyEventCommand keyEvent = (KeyEventCommand)obj;
157
		if (this.type.equals(keyEvent.getType()) && this.button == keyEvent.getButton())
158
			return true;
159
		return false;
160
	}
161
162
	private int getButton() 
163
	{
164
		return button;
165
	}
166
	
167
	private boolean isCharSet()
168
	{
169
		return isCharSet;
170
	}
171
172
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IUIObject.java (-226 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
import java.util.LinkedList;
14
import java.util.Map;
15
16
import org.eclipse.core.runtime.CoreException;
17
18
19
/**
20
 * Represents a UI object such as a widget.
21
 * 
22
 * @author Ali Mehregani
23
 */
24
public interface IUIObject
25
{
26
	/**
27
	 * Returns the hierarchical relationshipt of this object relative to its parents.
28
	 * A linked list is returned whose first element is the child of the root UI object node and
29
	 * its last node is this UI object.  An object directly above a node is the parent of that
30
	 * node.
31
	 *  
32
	 * @return A linked list indicating the hierarchical relationship between this node and
33
	 * its parents.
34
	 */
35
	public LinkedList getHierarchicalRelation();
36
37
	
38
	/**
39
	 * Set the reference id of this object.
40
	 * 
41
	 * @param referenceId The reference id
42
	 */
43
	public void setReferenceId(String referenceId);
44
	
45
	
46
	/**
47
	 * Return the reference id of this object
48
	 * 
49
	 * @return reference id
50
	 */
51
	public String getReferenceId();
52
53
	
54
	/**
55
	 * Sets the context id of this object
56
	 * 
57
	 * @param contextId The context id of this object
58
	 */
59
	public void setContextId(String contextId);
60
	
61
	
62
	/**
63
	 * Returns the context id of this object
64
	 * 
65
	 * @return The context id
66
	 */
67
	public String getContextId();
68
69
	
70
	/**
71
	 * Sets the id of this object.  This is the id used by the playback operations to
72
	 * identify the UI object.
73
	 * 
74
	 * @param id The id of this UI object
75
	 */
76
	public void setObjectId(String objectId);
77
	
78
	
79
	/**
80
	 * Returns the id of this object.  This is the id used by the playback operations to
81
	 * identify the UI object.
82
	 * 
83
	 * @return object id
84
	 */
85
	public String getObjectId();
86
87
	
88
	/**
89
	 * Returns the descriptive field of this object.  The descriptive field is human readable
90
	 * label that is used to easily recognize the object.
91
	 * 
92
	 * @param descriptive field
93
	 */
94
	public void setDescriptive(String descriptive);
95
96
	
97
	/**
98
	 * Returns the descriptive field of this object.  The descriptive field is human readable
99
	 * label that is used to easily recognize the object.
100
	 * 
101
	 * @return descriptive field
102
	 */
103
	public String getDescriptive();
104
	
105
	
106
	/**
107
	 * Add a property to this UI object.
108
	 * 
109
	 * @param name The name of the property 
110
	 * @param value The value of the property
111
	 */
112
	public void addProperty (String name, String value);
113
114
	
115
	/**
116
	 * Returns the property of this object
117
	 * 
118
	 * @param name The name of the property.
119
	 * @return The value of the property with the name passed in.  null is returned if the
120
	 * property can't be found.
121
	 */
122
	public String getProperty (String name);
123
	
124
	
125
	/**
126
	 * Returns the properties of this UI object.
127
	 * 
128
	 * @return The properties of this UI object
129
	 */
130
	public Map getProperties ();
131
	
132
	
133
	/**
134
	 * Set the parent of this UI object 
135
	 * 
136
	 * @param parent The parent
137
	 */
138
	public void setParent(IUIObject parent);
139
	
140
	
141
	/**
142
	 * Returns the parent of this UI object
143
	 * 
144
	 * @return The parent
145
	 */
146
	public IUIObject getParent();
147
148
149
	/**
150
	 * Sets the resolver id for this object.
151
	 * 
152
	 * @param resolverId The resolver id.
153
	 */
154
	public void setResolver(String resolverId);
155
	
156
	
157
	/**
158
	 * Returns the resolver id that has resolved this object 
159
	 * 
160
	 * @return A resolver id
161
	 */
162
	public String getResolverId();
163
	
164
	
165
	/**
166
	 * Returns the number of children that this UI object has
167
	 * 
168
	 * @return the number of children of this object
169
	 */
170
	public int childCount();
171
	
172
	
173
	/**
174
	 * Returns the children of this UI object
175
	 * 
176
	 * @return The children of this UI object
177
	 */
178
	public IUIObject[] getChildren();
179
	
180
	
181
	/**
182
	 * Adds a child to this object.  Has no effects if child is already
183
	 * part of this object's children
184
	 * 
185
	 * @param child The child to add
186
	 * @throws CoreException In case of any unexpected error
187
	 */
188
	public void addChild(IUIObject child) throws CoreException;
189
	
190
	
191
	/**
192
	 * Removes a  child from this object
193
	 * 
194
	 * @param child The child to remove
195
	 * @return The child removed
196
	 */
197
	public IUIObject removeChild(IUIObject child);
198
	
199
	
200
	/**
201
	 * Returns the data associated with this object.
202
	 * 
203
	 * @return The associated data
204
	 */
205
	public Object getData();
206
	
207
	
208
	/**
209
	 * Can be used to associate a general data object with this object.
210
	 * 
211
	 * @param data The data
212
	 */
213
	public void setData(Object data);
214
	
215
	
216
	/**
217
	 * Returns the child with a matching reference id passed in; null if none is found
218
	 * 
219
	 * @param referenceId The reference id of the child
220
	 * @return A IUIObject with a matching referenceId or null if none is found.
221
	 */
222
	public IUIObject findChild(String referenceId);
223
	
224
}
225
226
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IMacroInstruction.java (-88 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
import java.util.Hashtable;
14
15
import org.eclipse.core.runtime.CoreException;
16
import org.w3c.dom.Node;
17
18
19
/**
20
 * Represents a macro instruction.  The instruction is expected to  
21
 * both be writable and playable.  
22
 * 
23
 * @author Ali Mehregani
24
 */
25
public interface IMacroInstruction extends IWritable, IPlayable
26
{
27
	/**
28
	 * Invoked to load the macro instruction based on its corresponding
29
	 * XML node.
30
	 * 
31
	 * @param node The XML node representing this macro instruction
32
	 * @param lineTable Contains line level information
33
	 * 
34
	 * @throws CoreException In case of an unexpected error
35
	 */
36
	public void load(Node node, Hashtable lineTable) throws CoreException;
37
	
38
	
39
	/**
40
	 * Returns the corresponding widget id of this instruction
41
	 *  
42
	 * @return The widget id
43
	 */
44
	public WidgetIdentifier getWidgetId();
45
		
46
	
47
	/**
48
	 * Sets the widget identifier for this macro instruction
49
	 *  
50
	 * @return widgetIdentifier The widget identifier
51
	 */
52
	public void setWidgetId(WidgetIdentifier widgetIdentifier);
53
	
54
	
55
	/**
56
	 * Returns the corresponding IUIObject of this macro instruction.
57
	 * If an object is not supported then null will be returned.
58
	 * 
59
	 * @return The corresponding object of this instruction
60
	 */
61
	public IUIObject getCorrespondingObject();
62
	
63
	
64
	/**
65
	 * Sets the UI object for this macro instruction.
66
	 * 
67
	 * @param uiObject The corresponding object
68
	 */
69
	public void setCorrespondingObject(IUIObject uiObject);
70
	
71
	
72
	/**
73
	 * Returns the starting line number of this macro instruction in the
74
	 * macro script that it belongs to.
75
	 * 
76
	 * @return The starting line
77
	 */
78
	public int getStartLine();
79
	
80
		
81
	/**
82
	 * Returns the last line number of this macro instruction in the
83
	 * macro script that it belongs to.
84
	 * 
85
	 * @return The last line
86
	 */
87
	public int getStopLine();
88
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IWritable.java (-53 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
14
/**
15
 * A writable object is capable of serializing itself to string and writing the string
16
 * version to a PrintWriter that is passed to parameters to the methods that are described
17
 * below.
18
 * <br/>
19
 * The ideal order of the method invocations are:
20
 * <ul>
21
 * 	<li> writeStart(String indent, gPrintWriter writer) </li>
22
 * 	<li> write(String indent, PrintWriter writer) </li>
23
 * 	<li> writeFinish(String indent, PrintWriter writer) </li>
24
 * </ul>
25
 */
26
public interface IWritable 
27
{
28
	/**
29
	 * Invoked at start of the write of a writable object
30
	 * 
31
	 * @param indent The indents
32
	 * @param sb The buffer that the string serialization should be written to
33
	 */
34
	public void writeStart(int indent, StringBuffer sb);
35
	
36
	
37
	/**
38
	 * Invoked after writeStart
39
	 * 
40
	 * @param indent The indents
41
	 * @param sb The buffer that the string serialization should be written to
42
	 */
43
	public void write(int indent, StringBuffer sb);
44
	
45
	
46
	/**
47
	 * Invoked in the end of the write of a writable object
48
	 * 
49
	 * @param indent The indents
50
	 * @param sb The buffer that the string serialization should be written to
51
	 */
52
	public void writeFinish(int indent, StringBuffer sb);
53
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IPlayable.java (-20 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
import org.eclipse.core.runtime.*;
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.swt.widgets.*;
16
import org.eclipse.swt.widgets.Composite;
17
18
public interface IPlayable {
19
	boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException;
20
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoader.java (-102 / +184 lines)
Lines 1-102 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
12
13
import org.eclipse.core.runtime.CoreException;
13
import java.util.Hashtable;
14
import org.eclipse.core.runtime.IConfigurationElement;
14
import java.util.Vector;
15
15
16
/**
16
import org.eclipse.core.runtime.CoreException;
17
 * Represents each widgetResolver element that appears under a 
17
import org.eclipse.core.runtime.IConfigurationElement;
18
 * widgetResolver extension
18
import org.eclipse.core.runtime.Platform;
19
 * 
19
20
 * @author Ali Mehregani
20
/**
21
 */
21
 * Represents each widgetResolver element that appears under a widgetResolver
22
public class WidgetResolverLoader 
22
 * extension
23
{
23
 * 
24
	/** The id of the widget resolver */
24
 * @author Ali Mehregani
25
	private String id;
25
 * @deprecated
26
	
26
 */
27
	/** The widget resolver class */
27
public class WidgetResolverLoader {
28
	private IWidgetResolver widgetResolver;
28
	private static final String EXTENSION_POINT = "widgetResolver";
29
	
29
30
	/** The priority of this widget resolver registeration */
30
	/** The id of the widget resolver */
31
	private int priority;
31
	private String id;
32
	
32
33
	
33
	/** The widget resolver class */
34
	/**
34
	private IWidgetResolver widgetResolver;
35
	 * Limit the visibility of the constructor
35
36
	 */
36
	/** The priority of this widget resolver registeration */
37
	private WidgetResolverLoader(String id, IWidgetResolver resolver, int priority)
37
	private int priority;
38
	{
38
39
		this.id = id;
39
	/* Keeps an ordered list of the resolver ids */
40
		this.widgetResolver = resolver;
40
	private static String[] resolverIds;
41
		this.priority = priority;
41
42
	}
42
	/*
43
	
43
	 * The widget resolver: KEY = resolver id VALUE = A class of type
44
	
44
	 * WidgetResolverLoader
45
	/**
45
	 */
46
	 * Constructs an instance of this class based on the configuration
46
	private static Hashtable widgetResolvers = new Hashtable();
47
	 * element passed in
47
48
	 * 
48
	/**
49
	 * @param confiugrationElement The configuration element to be loaded
49
	 * Limit the visibility of the constructor
50
	 * @return An instance of this class based on the configuration element passed in.
50
	 */
51
	 * null will be returned if there is an error loading the configuration element.
51
	private WidgetResolverLoader(String id, IWidgetResolver resolver,
52
	 */
52
			int priority) {
53
	public static WidgetResolverLoader constructInstance(IConfigurationElement configuraitonElement)
53
		this.id = id;
54
	{
54
		this.widgetResolver = resolver;
55
		if (!"widgetResolver".equals(configuraitonElement.getName()))
55
		this.priority = priority;
56
			return null;
56
	}
57
		
57
58
		try
58
	/**
59
		{
59
	 * Constructs an instance of this class based on the configuration element
60
			String id = configuraitonElement.getAttribute("id");
60
	 * passed in
61
			IWidgetResolver widgetResolver = (IWidgetResolver) configuraitonElement.createExecutableExtension("class");
61
	 * 
62
			int priority = Integer.parseInt(configuraitonElement.getAttribute("priority"));
62
	 * @param confiugrationElement
63
			
63
	 *            The configuration element to be loaded
64
			if (id == null || widgetResolver == null)
64
	 * @return An instance of this class based on the configuration element
65
				return null;
65
	 *         passed in. null will be returned if there is an error loading the
66
			
66
	 *         configuration element.
67
			return new WidgetResolverLoader (id, widgetResolver, priority);
67
	 */
68
68
	public static WidgetResolverLoader constructInstance(
69
		}
69
			IConfigurationElement configuraitonElement) {
70
		catch (CoreException e)
70
		if (!EXTENSION_POINT.equals(configuraitonElement.getName()))
71
		{			
71
			return null;
72
		}
72
73
				
73
		try {
74
		return null;
74
			String id = configuraitonElement.getAttribute("id");
75
	}
75
			IWidgetResolver widgetResolver = (IWidgetResolver) configuraitonElement
76
76
					.createExecutableExtension("class");
77
77
			int priority = Integer.parseInt(configuraitonElement
78
	/**
78
					.getAttribute("priority"));
79
	 * @return the id
79
80
	 */
80
			if (id == null || widgetResolver == null)
81
	public String getId() {
81
				return null;
82
		return id;
82
83
	}
83
			return new WidgetResolverLoader(id, widgetResolver, priority);
84
84
85
85
		} catch (CoreException e) {
86
	/**
86
		}
87
	 * @return the priority
87
88
	 */
88
		return null;
89
	public int getPriority() {
89
	}
90
		return priority;
90
91
	}
91
	/**
92
92
	 * @return the id
93
93
	 */
94
	/**
94
	public String getId() {
95
	 * @return the widgetResolver
95
		return id;
96
	 */
96
	}
97
	public IWidgetResolver getWidgetResolver() {
97
98
		return widgetResolver;
98
	/**
99
	}
99
	 * @return the priority
100
	
100
	 */
101
101
	public int getPriority() {
102
}
102
		return priority;
103
	}
104
105
	/**
106
	 * @return the widgetResolver
107
	 */
108
	public IWidgetResolver getWidgetResolver() {
109
		return widgetResolver;
110
	}
111
112
	public static WidgetResolverLoader[] getWidgetResolverLoaders() {
113
		if (resolverIds == null) {
114
			loadWidgetResolvers();
115
		}
116
117
		WidgetResolverLoader[] resolvers = new WidgetResolverLoader[resolverIds.length];
118
		for (int i = 0; i < resolverIds.length; i++) {
119
			resolvers[i] = ((WidgetResolverLoader) widgetResolvers
120
					.get(resolverIds[i]));
121
		}
122
		return resolvers;
123
	}
124
125
	private static void loadWidgetResolvers() {
126
		IConfigurationElement[] elements = Platform.getExtensionRegistry()
127
				.getConfigurationElementsFor(
128
						"org.eclipse.tptp.test.auto.gui.widgetResolver");
129
		Vector tempContainer = new Vector(elements.length);
130
131
		for (int i = 0; i < elements.length; i++) {
132
			WidgetResolverLoader widgetResolverLoader = WidgetResolverLoader
133
					.constructInstance(elements[i]);
134
			if (widgetResolverLoader != null) {
135
				tempContainer.add(findIndex(widgetResolverLoader.getPriority(),
136
						tempContainer), widgetResolverLoader);
137
				widgetResolvers.put(widgetResolverLoader.getId(),
138
						widgetResolverLoader);
139
			}
140
		}
141
142
		resolverIds = new String[tempContainer.size()];
143
		for (int i = 0; i < resolverIds.length; i++) {
144
			resolverIds[i] = ((WidgetResolverLoader) tempContainer.get(i))
145
					.getId();
146
		}
147
	}
148
149
	private static int findIndex(int desiredPriority, Vector container,
150
			int startIntervalInx, int endIntervalInx, int length) {
151
		if (startIntervalInx == endIntervalInx
152
				|| startIntervalInx == endIntervalInx - 1) {
153
			if (length > 0) {
154
				WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader) container
155
						.get(startIntervalInx);
156
				int priority = widgetResolverReg.getPriority();
157
				if (desiredPriority < priority)
158
					return startIntervalInx;
159
			}
160
			return endIntervalInx;
161
		}
162
163
		/* What's in the middle? */
164
		int middleInx = startIntervalInx
165
				+ (int) Math.ceil((endIntervalInx - startIntervalInx) / 2);
166
		WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader) container
167
				.get(middleInx);
168
		int middleElementPriority = widgetResolverReg.getPriority();
169
170
		if (middleElementPriority > desiredPriority)
171
			endIntervalInx = middleInx;
172
		else if (middleElementPriority < desiredPriority)
173
			startIntervalInx = middleInx;
174
		else
175
			return middleInx;
176
		return findIndex(desiredPriority, container, startIntervalInx,
177
				endIntervalInx, length);
178
	}
179
180
	private static int findIndex(int priority, Vector container) {
181
		int length = container.size();
182
		return findIndex(priority, container, 0, length, length);
183
	}
184
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetResolver.java (-49 / +58 lines)
Lines 1-50 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
12
13
import org.eclipse.swt.widgets.Widget;
13
import org.eclipse.swt.widgets.Widget;
14
14
15
/**
15
/**
16
 * This interface is registered using extension point <code>org.eclipse.tptp.test.auto.gui.widgetResolver</code> 
16
 * This interface is registered using extension point
17
 * which is expected to return a unique identifier from a provided widget. The identifier must be reproducable 
17
 * <code>org.eclipse.tptp.test.auto.gui.widgetResolver</code> which is expected
18
 * between sessions so that it can be used to locate the widget on playback.
18
 * to return a unique identifier from a provided widget. The identifier must be
19
 * 
19
 * reproducable between sessions so that it can be used to locate the widget on
20
 * @since 3.1
20
 * playback.
21
 */
21
 * 
22
public interface IWidgetResolver
22
 * @since 3.1
23
{
23
 * @deprecated
24
	/**
24
 */
25
	 * Returns a unique identifier for the provided widget.
25
public interface IWidgetResolver {
26
	 * 
26
	/**
27
	 * @param widget The parent object.  The value of this parameter can be null if the parent
27
	 * Returns a unique identifier for the provided widget.
28
	 * of object cannot be resolved.
28
	 * 
29
	 * @param object The object whose id is suppose to be resolved.  The type of this object is 
29
	 * @param widget
30
	 * <b>usually</b> a widget, but it can also be a <code>java.lang.String</code> or any other
30
	 *            The parent object. The value of this parameter can be null if
31
	 * arbitrary type depending on the implementation of the widget.  For example, when attempting
31
	 *            the parent of object cannot be resolved.
32
	 * to resolve a combo box item, parent will point to the combo box and object will point to 
32
	 * @param object
33
	 * a <code>java.lang.String</code> item representing the item selected.
33
	 *            The object whose id is suppose to be resolved. The type of
34
	 *   
34
	 *            this object is <b>usually</b> a widget, but it can also be a
35
	 * @return unique identifier that can be used to locate the widget or
35
	 *            <code>java.lang.String</code> or any other arbitrary type
36
	 *         <code>null</code> if none can be found.
36
	 *            depending on the implementation of the widget. For example,
37
	 */
37
	 *            when attempting to resolve a combo box item, parent will point
38
	public IWidgetId getUniqueId(Widget parent, Object object);
38
	 *            to the combo box and object will point to a
39
39
	 *            <code>java.lang.String</code> item representing the item
40
	
40
	 *            selected.
41
	/**
41
	 * 
42
	 * Given an object and an id, this method should return true if and only if the id
42
	 * @return unique identifier that can be used to locate the widget or
43
	 * of object as determined by this resolver equals the 'id' passed in.
43
	 *         <code>null</code> if none can be found.
44
	 *  
44
	 */
45
	 * @param object An object 
45
	public IWidgetId getUniqueId(Widget parent, Object object);
46
	 * @param id The being searched for
46
47
	 * @return true iff object's id is equalled to 'id'
47
	/**
48
	 */
48
	 * Given an object and an id, this method should return true if and only if
49
	public boolean foundWidget(Object object, Object id);
49
	 * the id of object as determined by this resolver equals the 'id' passed
50
	 * in.
51
	 * 
52
	 * @param object
53
	 *            An object
54
	 * @param id
55
	 *            The being searched for
56
	 * @return true iff object's id is equalled to 'id'
57
	 */
58
	public boolean foundWidget(Object object, Object id);
50
}
59
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IObjectMine.java (-244 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
import java.util.List;
14
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
17
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException;
18
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound;
19
import org.w3c.dom.Node;
20
21
22
/**
23
 * Represents an object mine that belongs to a particular test suite.  The mine
24
 * keeps track of the objects that the test cases depends on.  Object mines
25
 * can be shared among multiple test suites, allowing users to centralize the objects
26
 * identified by test cases spanning multiple test suites.  The output source of an object 
27
 * mine can be different from the test suite that owns the mine.  
28
 * 
29
 * <p>
30
 * The inclusion and output source options introduce some ambiguities in registering a new 
31
 * object with an object mine.  The general contract when registering a new object is outlined below.
32
 * </p>
33
 * 
34
 * <p>
35
 * 	Assume object mine om1 includes om2 and outputs to om3:
36
 * </p>
37
 *    
38
 * <ul>
39
 * 	<li> If object o is infant, then it is registered with om3 </li>
40
 *  <li> If object o has a parent that belongs to om1, then it is registered with om1 </li>
41
 * 	<li> If object o has a parent that belongs to om2, then it is registered with om2 </li>
42
 *  <li> If object o has a parent that belongs to om3, then it is registered with om3 </li>
43
 * </ul>
44
 * 
45
 * Changing the output source of an object mine to an alternative test suite does not guarantee
46
 * that new objects will be written to the set test suite's object mine.
47
 * 
48
 * @author Ali Mehregani
49
 */
50
public interface IObjectMine 
51
{
52
53
	/**
54
	 * The test suite that owns this object mine.  The owner and the output source
55
	 * can be different.
56
	 * 
57
	 * @return The owner
58
	 */
59
	public ITestSuite getOwner();
60
	
61
	
62
	/**
63
	 * Sets the owner of this test suite.  The owner and the output source
64
	 * can be different.
65
	 * 
66
	 * @param testSuite The owner
67
	 */
68
	public void setOwner(ITestSuite testSuite);
69
	
70
	
71
	/**
72
	 * Set the output source to the object mine that is passed in.  If
73
	 * the user uses the test suite that is the owner of this mine to
74
	 * record a test case that results in finding a new object, then the
75
	 * object will be contributed to the object mine of the output source, not
76
	 * the owner of this object mine (some exceptions apply - see class comment).
77
	 * 
78
	 * @param objectMine The object mine that will act as the output source
79
	 * for this mine 
80
	 */
81
	public void setOutputSource(IObjectMine objectMine);
82
83
	
84
	/**
85
	 * Returns the output of this object mine
86
	 * 
87
	 * @return The output source
88
	 */
89
	public IObjectMine getOutputSource();
90
	
91
	
92
	/**
93
	 * Includes another object mine as part of this mine.  The lookup method for
94
	 * an object is required to walk through the registered objects of this object
95
	 * mine and the registered objects of included object mines.
96
	 * 
97
	 * @param objectMine The object mine to include
98
	 */
99
	public void addInclude(IObjectMine objectMine);
100
101
	
102
	/**
103
	 * Returns the external object mines that have been added to this 
104
	 * object mine
105
	 * 
106
	 * @return The added external object mines
107
	 */
108
	public List getIncludes();
109
	
110
	
111
	/**
112
	 * Looks up the UI object with the reference id passed in.  null should be 
113
	 * returned if the objct can't be found.  Time complexity = T(h) = h (where h is the height of the 
114
	 * object mine tree)
115
	 * 
116
	 * @param parent The parent of the object
117
	 * @param referenceId The reference id of the object
118
	 * 
119
	 * @return The object with the reference id passed in; or null if none is found.
120
	 * 
121
	 * @throws UIObjectNotFound If the parent object is not found
122
	 */
123
	public IUIObject lookupUIObject(IUIObject parent, String referenceId);
124
	
125
	
126
	/**
127
	 * Looks up the UI object based on the context id and the object id that is passed in.  This
128
	 * lookup operation is more expensive than lookup(parent, referenceId).  The latter should be
129
	 * used where possible.  Time complexity = T(h, n) = h + n (where h is the height of the 
130
	 * object mine tree and n is the number of nodes owned by the parent node)
131
	 * 
132
	 * @param parent The parent of the object
133
	 * @param contextId The context id of the object
134
	 * @param objectId The object id of the object
135
	 * 
136
	 * @return The object with the matching context and object id; or null if none is found.
137
	 * 
138
	 * @throws UIObjectNotFound If the parent object is not found
139
	 */
140
	public IUIObject lookupUIObject(IUIObject parent, String contextId, String objectId);
141
	
142
	
143
	/**
144
	 * Returns the direct children of the root object that this object mine points to
145
	 * 
146
	 * @return The children of the root object 
147
	 */
148
	public IUIObject[] getChildren();
149
150
	
151
	/**
152
	 * Register the object embedded in the node passed in.  The parent of the
153
	 * registered object should be set to the parent argument.  If the object is already
154
	 * registered, then this method will not have any effects.
155
	 * 
156
	 * @param parent The parent of the object to be registered
157
	 * @param node The node containing the object information to be registered
158
	 * 
159
	 * @return The object that gets registered.
160
	 * 
161
	 * @throws IDCollisionException If there is a reference id collision
162
	 * @throws UIObjectNotFound If the parent object is not found
163
	 * @throws CoreException Wraps any unexpected error 
164
	 */
165
	public IUIObject registerObject(IUIObject parent, Node currentNode) throws IDCollisionException, UIObjectNotFound, CoreException;
166
167
168
	/**
169
	 * Registers uiObject under the parent object passed in.  If the object is already
170
	 * registered, then this method will not have any effects.
171
	 * 
172
	 * @param uiObject The object to be registered
173
	 * @return The object that gets registered (i.e. uiObject).
174
	 * 
175
	 * @throws IDCollisionException If there is a reference id collision
176
	 * @throws UIObjectNotFound If the parent object of uiObject is not found
177
	 * @throws CoreException Wraps any unexpected error 
178
	 */
179
	public IUIObject registerObject(IUIObject uiObject) throws IDCollisionException, UIObjectNotFound, CoreException;
180
	
181
	
182
	/**
183
	 * Serializes this object mine to a string representation that can be stored
184
	 * and retrieved for later use.  This is often the result of <code>serializeHeaderToString()</code>
185
	 * appended to the result of <code>serializeObjetsToString()</code>.
186
	 * 
187
	 * @return The string representation of this object mine
188
	 */
189
	public String serializeToString();
190
	
191
	
192
	/**
193
	 * Serializes only the header of this object mine to a string representation that
194
	 * can be stored and retrieved for later use.
195
	 * 
196
	 * @return The string representation of the header of this object mine
197
	 */
198
	public String serializeHeaderToString();
199
	
200
	
201
	/**
202
	 * Serializes only the objects of this object mine to a string representation that
203
	 * can be stored and retrieved for later use.
204
	 * 
205
	 * @return The string representation of the object directly owned by this object mine
206
	 */
207
	public String serializeObjetsToString();
208
	
209
	
210
	/**
211
	 * Sets the active object of this object mine.  This is commonly used to determine the active
212
	 * object corresponding to the active shell.
213
	 * 
214
	 * @param activeObject The active object.
215
	 */
216
	public void setActiveObject(IUIObject activeObject);
217
	
218
	
219
	/**
220
	 * Returns the active object of this object mine.  This is commonly used to determine the active
221
	 * object corresponding to the active shell.
222
	 * 
223
	 * @return The active object.
224
	 */	
225
	public IUIObject getActiveObject();
226
227
228
	/**
229
	 * Returns the next available unique reference id that can be used.  The id's returned will be an
230
	 * integer even though the type is set to String.
231
	 * 
232
	 * @return The next available reference id.
233
	 */
234
	public String getUniqueReferenceId();
235
	
236
	
237
	/**
238
	 * Returns the roo object
239
	 * 
240
	 * @return The root object
241
	 */
242
	public IUIObject getRoot();
243
244
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IRecorderListener.java (-26 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
public interface IRecorderListener {
14
	int STOP = 1;
15
	int INDEX = 2;
16
	void recordingStarted();
17
	void recordingStopped();
18
/**
19
 * Called when the user pressed Ctrl+Shift+F10 (index)
20
 * or Ctrl+Shift+F11 (stop) to interrupt
21
 * the recording process. Clients may use this event
22
 * to insert named indexes, stop the recording etc.
23
 * @param type <code>STOP</code> or <code>INDEX</code>
24
 */
25
	void recordingInterrupted(int type);
26
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/IWidgetId.java (-40 / +41 lines)
Lines 1-40 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
12
13
13
14
/**
14
/**
15
 * A widget resolver is expected to return a class that implements this interface
15
 * A widget resolver is expected to return a class that implements this interface
16
 * when the id of a passed widget is successfully resolved.  <b> **Note:</b> In addition to 
16
 * when the id of a passed widget is successfully resolved.  <b> **Note:</b> In addition to 
17
 * the methods of this interface, a contributor is also expected to implement {@link java.lang.Object#equals(Object)} 
17
 * the methods of this interface, a contributor is also expected to implement {@link java.lang.Object#equals(Object)} 
18
 * and {@link java.lang.Object#toString()}.
18
 * and {@link java.lang.Object#toString()}.
19
 * 
19
 * 
20
 * @since 4.3
20
 * @since 4.3
21
 * @author Ali Mehregani
21
 * @deprecated 
22
 */
22
 * @author Ali Mehregani
23
public interface IWidgetId
23
 */
24
{
24
public interface IWidgetId
25
	/**
25
{
26
	 * Returns the id of the widget resolver that resolved this widget id.
26
	/**
27
	 * 
27
	 * Returns the id of the widget resolver that resolved this widget id.
28
	 * @return The id of the widget resolver that generated this widget id
28
	 * 
29
	 */
29
	 * @return The id of the widget resolver that generated this widget id
30
	public String getResolverId ();
30
	 */
31
	
31
	public String getResolverId ();
32
	
32
	
33
	/**
33
	
34
	 * Sets the id of the widget resolver that generated this widget
34
	/**
35
	 * id.
35
	 * Sets the id of the widget resolver that generated this widget
36
	 *
36
	 * id.
37
	 * @param resolverId The id of the widget resolver
37
	 *
38
	 */
38
	 * @param resolverId The id of the widget resolver
39
	public void setResolverId(String resolverId);
39
	 */
40
}
40
	public void setResolverId(String resolverId);
41
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/VerificationMetaData.java (-103 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: VerificationMetaData.java,v 1.2 2006/10/27 14:39:10 amehregani Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.core;
13
14
15
/**
16
 * A container class for the data that the verificaiton command will need 
17
 * 
18
 * @author Ali Mehregani
19
 */
20
public class VerificationMetaData
21
{
22
	/* The possible types */
23
	public static final byte EDITOR 	= 0x01;
24
	public static final byte VIEW 		= 0x02;
25
	public static final byte SHELL		= 0x03;
26
	
27
	
28
	/* The context id is the id of the editor, viewer, etc... that will be used to retrieve it */
29
	private String contextId;
30
	
31
	/* The location is the plugin that contains the hook source code */
32
	private String location;
33
	
34
	/* The resource is the class name containing the hook */
35
	private String resource;
36
	
37
	/* The hook is the method name representing the verification point */
38
	private String hook;
39
	
40
	/* The focus type indicates whether the type of context being retrieved */ 
41
	private byte focusType;
42
43
	public VerificationMetaData()
44
	{
45
		focusType = -1;
46
	}
47
			
48
	public String getContextId()
49
	{
50
		return contextId;
51
	}
52
53
	public void setContextId(String contextId)
54
	{
55
		this.contextId = contextId;
56
	}
57
58
	public byte getFocusType()
59
	{
60
		return focusType;
61
	}
62
63
	public void setFocusType(byte focusType)
64
	{
65
		this.focusType = focusType;
66
	}
67
68
	public String getHook()
69
	{
70
		return hook;
71
	}
72
73
	public void setHook(String hook)
74
	{
75
		this.hook = hook;
76
	}
77
78
	public String getLocation()
79
	{
80
		return location;
81
	}
82
83
	public void setLocation(String location)
84
	{
85
		this.location = location;
86
	}
87
88
	public String getResource()
89
	{
90
		return resource;
91
	}
92
93
	public void setResource(String resource)
94
	{
95
		this.resource = resource;
96
	}
97
	
98
	public boolean isComplete()
99
	{
100
		return contextId != null && location != null &&  resource != null && hook != null && focusType != -1; 
101
	}
102
	
103
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetIdentifier.java (-177 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.core;
12
13
import org.eclipse.core.runtime.IPath;
14
import org.eclipse.core.runtime.Path;
15
16
17
/**
18
 * Used as an identifier for widgets.  At a minimum, a context id and a widget id
19
 * is required as part of a widget identifier.
20
 * 
21
 * @author Ali Mehregani
22
 */
23
public class WidgetIdentifier
24
{
25
	/** A null identifier */
26
	public static final WidgetIdentifier NULL_IDENTIFIER = new WidgetIdentifier(new Path(""), new Path(""), null);
27
	
28
	/** The context id */
29
	private IPath contextId;
30
31
	/** The widget id */
32
	private IPath objectId;
33
34
	/** The id that is used to reference this widget in the object mine */
35
	private String referenceId;
36
	
37
	/** The resolver id that resovled this widget */
38
	private String resolverId;
39
	
40
	
41
	/**
42
	 * Constructor 
43
	 * 
44
	 * @param contextId The context id
45
	 * @param widgetId The widget id
46
	 */
47
	public WidgetIdentifier(IPath contextId, IPath widgetId, String resolverId)
48
	{
49
		this.contextId = contextId;
50
		this.objectId = widgetId;
51
		this.resolverId = resolverId;
52
	}
53
54
	
55
	/**
56
	 * Returns the fully qualified path of this widget id.  The fully qualified
57
	 * path is the context id/path appended with the widget path/id.
58
	 *  
59
	 * @return The fully qualified path of this identifier.
60
	 */
61
	public IPath getFullyQualifiedPath()
62
	{
63
		return contextId.append(objectId);
64
	}
65
66
	
67
	/**
68
	 * Equivalent to getFullyQualifiedPath().toString().
69
	 * 
70
	 * @return The fully qualified id
71
	 */
72
	public String getFullyQualifiedId()
73
	{
74
		return getFullyQualifiedPath().toString();
75
	}
76
77
	
78
	/**
79
	 * An object in question is equalled to this object iff the object is of the same type and
80
	 * the context and the widget ids are the same.
81
	 * 
82
	 * @param object The object in question
83
	 * 
84
	 * @return A boolean indicating whether object is equalled to this object or not.
85
	 */
86
	public boolean equals(Object object)
87
	{
88
		if (object == null)
89
			return false;
90
		if (object == this)
91
			return true;
92
		if (object instanceof WidgetIdentifier)
93
		{
94
			WidgetIdentifier wid = (WidgetIdentifier) object;
95
			return wid.contextId.equals(contextId) && wid.objectId.equals(objectId);
96
		}
97
		return false;
98
	}
99
100
101
	/**
102
	 * Returns the context id of this identifier
103
	 * 
104
	 * @return The context id
105
	 */
106
	public IPath getContextId()
107
	{
108
		return contextId;
109
	}
110
	
111
	
112
113
	/**
114
	 * @param contextId the contextId to set
115
	 */
116
	public void setContextId(IPath contextId)
117
	{
118
		this.contextId = contextId;
119
	}
120
121
122
	/**
123
	 * Returns the widget id of this identifier
124
	 * 
125
	 * @return The widget id
126
	 */
127
	public IPath getObjectId()
128
	{
129
		return objectId;
130
	}
131
	
132
	
133
	/**
134
	 * @param objectId the objectId to set
135
	 */
136
	public void setObjectId(IPath objectId)
137
	{
138
		this.objectId = objectId;
139
	}
140
141
142
	/**
143
	 * @return the referenceId
144
	 */
145
	public String getReferenceId()
146
	{
147
		return referenceId;
148
	}
149
150
151
	/**
152
	 * @param referenceId the referenceId to set
153
	 */
154
	public void setReferenceId(String referenceId)
155
	{
156
		this.referenceId = referenceId;
157
	}
158
159
160
	/**
161
	 * @return the resolverId
162
	 */
163
	public String getResolverId()
164
	{
165
		return resolverId;
166
	}
167
168
169
	/**
170
	 * @param resolverId the resolverId to set
171
	 */
172
	public void setResolverId(String resolverId)
173
	{
174
		this.resolverId = resolverId;
175
	}
176
	
177
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/VerifHookClassLoader.java (-104 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: VerifHookClassLoader.java,v 1.2 2006/07/14 23:17:02 amehregani Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.core;
13
14
import java.net.URL;
15
import java.net.URLClassLoader;
16
import java.util.Vector;
17
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.osgi.util.NLS;
20
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
21
22
/**
23
 * A custom class loader that is used to resolve a class that the verificaiton hook is in along
24
 * with any other classes that are imported by the verification class.
25
 * 
26
 * @author Ali Mehregani
27
 */
28
public class VerifHookClassLoader extends URLClassLoader
29
{
30
	/* The plugins that the verification plugin requires */
31
	private Vector reqPluginNames;
32
	
33
	public VerifHookClassLoader (URL[] urls, ClassLoader parent, Vector requiredPluginNames)
34
	{
35
		super (urls, parent);		
36
		reqPluginNames = requiredPluginNames;
37
	}
38
	
39
   
40
	/**
41
	 * Invoked when a class can't be resolved by the upper level class loaders associated with
42
	 * this class.
43
	 */
44
	protected Class findClass(final String name) 
45
	 throws ClassNotFoundException 			 
46
    {  	
47
		
48
    	/* Try and walk through the required plugins of the plugin
49
    	 * containing the test suite */
50
    	try
51
    	{			
52
    		Class classFile = loadFromReqPlugins(name, 0);
53
    		if (classFile != null)
54
    			return classFile;
55
    	}
56
    	catch (Throwable t)
57
    	{
58
    		/* Doesn't need to be handled */
59
    	}
60
    	
61
		
62
		try
63
		{
64
			Class classFile = super.findClass(name);
65
			if (classFile != null)
66
				return classFile;
67
		}
68
		catch (Throwable t)
69
		{
70
			/* Doesn't need to be handled */
71
		}
72
		
73
	    		    	
74
    	
75
    	throw new ClassNotFoundException (NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_FS, name));
76
    }
77
78
79
	/**
80
	 * Attempt to load the class from the required plugins.
81
	 * 
82
	 * @param name
83
	 * @param inx
84
	 * @return
85
	 */
86
	private Class loadFromReqPlugins(String name, int inx)
87
	{
88
		try
89
		{
90
			if (reqPluginNames == null || inx >= reqPluginNames.size())
91
				return null;
92
			
93
			Class classFile = Platform.getBundle(((String)reqPluginNames.get(inx))).loadClass(name);				
94
			if (classFile != null)
95
				return classFile;
96
		}
97
		catch (Throwable t)
98
		{
99
			/* Handled by next statement */
100
		}
101
		
102
		return loadFromReqPlugins(name, inx + 1);
103
	}
104
}
(-)plugin.properties (-30 / +32 lines)
Lines 1-30 Link Here
1
############################################################################### 
1
############################################################################### 
2
# Copyright (c) 2005, 2008 IBM Corporation and others. 
2
# Copyright (c) 2005, 2008 IBM Corporation and others. 
3
# All rights reserved. This program and the accompanying materials 
3
# All rights reserved. This program and the accompanying materials 
4
# are made available under the terms of the Eclipse Public License v1.0 
4
# are made available under the terms of the Eclipse Public License v1.0 
5
# which accompanies this distribution, and is available at 
5
# which accompanies this distribution, and is available at 
6
# http://www.eclipse.org/legal/epl-v10.html
6
# http://www.eclipse.org/legal/epl-v10.html
7
# $Id: plugin.properties,v 1.11 2008/04/16 14:58:24 jkubasta Exp $ 
7
# $Id: plugin.properties,v 1.11 2008/04/16 14:58:24 jkubasta Exp $ 
8
# 
8
# 
9
# Contributors: 
9
# Contributors: 
10
# IBM Corporation - initial API and implementation 
10
# IBM Corporation - initial API and implementation 
11
############################################################################### 
11
############################################################################### 
12
#
12
#
13
# plugin.properties
13
# plugin.properties
14
#
14
#
15
# This property file ONLY contains messages for the this plug-in's MANIFEST.MF and plugin.xml files.
15
# This property file ONLY contains messages for the this plug-in's MANIFEST.MF and plugin.xml files.
16
#
16
#
17
# NOTE:  When using substitution parameters, all single quote characters (e.g. ') must be escaped with a preceding single quote character (e.g. ''text in single quotes'').
17
# NOTE:  When using substitution parameters, all single quote characters (e.g. ') must be escaped with a preceding single quote character (e.g. ''text in single quotes'').
18
#
18
#
19
# NLS_MESSAGEFORMAT_VAR
19
# NLS_MESSAGEFORMAT_VAR
20
# NLS_ENCODING=UTF-8
20
# NLS_ENCODING=UTF-8
21
21
22
pluginName   = TPTP Automated GUI Recorder (AGR)
22
pluginName   = TPTP Automated GUI Recorder (AGR)
23
providerName = Eclipse.org
23
providerName = Eclipse.org
24
24
25
25
26
TST_SUITE_AUTO_GUI_NAME 		= TPTP Automated GUI Test
26
TST_SUITE_AUTO_GUI_NAME 		= TPTP Automated GUI Test
27
TST_SUITE_AUTO_GUI_DESC 		= Use this suite to create Automated GUI test cases in the Eclipse platform
27
TST_SUITE_AUTO_GUI_DESC 		= Use this suite to create Automated GUI test cases in the Eclipse platform
28
TST_CASE_AUTO_GUI_NAME			= TPTP Automated GUI Test Case
28
TST_CASE_AUTO_GUI_NAME			= TPTP Automated GUI Test Case
29
TST_CASE_AUTO_GUI_DESC			= Test Case which can store events recorded on the UI and be used to play them back
29
TST_CASE_AUTO_GUI_DESC			= Test Case which can store events recorded on the UI and be used to play them back
30
widgetResolver = Widget Resolver Extension
30
widgetResolver = Widget Resolver Extension (Deprecated)
31
uiObjectResolverDelegate = UI Object Resolver Delegate Extension
32
macroCommandFactory = MacroCommandFactory Replacement Extension
(-)plugin.xml (+2 lines)
Lines 14-19 Link Here
14
 -->
14
 -->
15
<?eclipse version="3.0"?>
15
<?eclipse version="3.0"?>
16
<plugin>
16
<plugin>
17
   <extension-point id="uiObjectResolverDelegate" name="%uiObjectResolverDelegate" schema="schema/uiObjectResolverDelegate.exsd"/>
18
   <extension-point id="macroCommandFactory" name="%macroCommandFactory" schema="schema/macroCommandFactory.exsd"/>
17
   <extension-point id="widgetResolver" name="%widgetResolver" schema="schema/widgetResolver.exsd"/>
19
   <extension-point id="widgetResolver" name="%widgetResolver" schema="schema/widgetResolver.exsd"/>
18
   <extension
20
   <extension
19
         point="org.eclipse.hyades.ui.typeDescriptions">
21
         point="org.eclipse.hyades.ui.typeDescriptions">
(-).project (-34 / +34 lines)
Lines 1-34 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
1
<?xml version="1.0" encoding="UTF-8"?>
2
<projectDescription>
2
<projectDescription>
3
	<name>org.eclipse.tptp.test.auto.gui</name>
3
	<name>Copy of org.eclipse.tptp.test.auto.gui</name>
4
	<comment></comment>
4
	<comment></comment>
5
	<projects>
5
	<projects>
6
	</projects>
6
	</projects>
7
	<buildSpec>
7
	<buildSpec>
8
		<buildCommand>
8
		<buildCommand>
9
			<name>org.eclipse.emf.codegen.JETBuilder</name>
9
			<name>org.eclipse.emf.codegen.JETBuilder</name>
10
			<arguments>
10
			<arguments>
11
			</arguments>
11
			</arguments>
12
		</buildCommand>
12
		</buildCommand>
13
		<buildCommand>
13
		<buildCommand>
14
			<name>org.eclipse.jdt.core.javabuilder</name>
14
			<name>org.eclipse.jdt.core.javabuilder</name>
15
			<arguments>
15
			<arguments>
16
			</arguments>
16
			</arguments>
17
		</buildCommand>
17
		</buildCommand>
18
		<buildCommand>
18
		<buildCommand>
19
			<name>org.eclipse.pde.ManifestBuilder</name>
19
			<name>org.eclipse.pde.ManifestBuilder</name>
20
			<arguments>
20
			<arguments>
21
			</arguments>
21
			</arguments>
22
		</buildCommand>
22
		</buildCommand>
23
		<buildCommand>
23
		<buildCommand>
24
			<name>org.eclipse.pde.SchemaBuilder</name>
24
			<name>org.eclipse.pde.SchemaBuilder</name>
25
			<arguments>
25
			<arguments>
26
			</arguments>
26
			</arguments>
27
		</buildCommand>
27
		</buildCommand>
28
	</buildSpec>
28
	</buildSpec>
29
	<natures>
29
	<natures>
30
		<nature>org.eclipse.emf.codegen.jet.IJETNature</nature>
30
		<nature>org.eclipse.emf.codegen.jet.IJETNature</nature>
31
		<nature>org.eclipse.pde.PluginNature</nature>
31
		<nature>org.eclipse.pde.PluginNature</nature>
32
		<nature>org.eclipse.jdt.core.javanature</nature>
32
		<nature>org.eclipse.jdt.core.javanature</nature>
33
	</natures>
33
	</natures>
34
</projectDescription>
34
</projectDescription>
(-)src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookMethodGenerator.java (-10 lines)
Lines 1-13 Link Here
1
/**********************************************************************
2
 * Copyright (c) 2007, 2009 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM Corporation - initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.codegen;
1
package org.eclipse.tptp.test.auto.gui.internal.codegen;
12
2
13
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
3
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
(-)src/org/eclipse/tptp/test/auto/gui/internal/codegen/TestSuiteToXMLConvertor.java (-10 lines)
Lines 1-13 Link Here
1
/**********************************************************************
2
 * Copyright (c) 2007, 2009 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM Corporation - initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.codegen;
1
package org.eclipse.tptp.test.auto.gui.internal.codegen;
12
2
13
import java.util.HashSet;
3
import java.util.HashSet;
(-)src/org/eclipse/tptp/test/auto/gui/internal/codegen/VerificationHookClassGenerator.java (-10 lines)
Lines 1-13 Link Here
1
/**********************************************************************
2
 * Copyright (c) 2007, 2009 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 * IBM Corporation - initial API and implementation
10
 **********************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.codegen;
1
package org.eclipse.tptp.test.auto.gui.internal.codegen;
12
2
13
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
3
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
(-)src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUIGenerator.java (-164 / +164 lines)
Lines 1-165 Link Here
1
/**********************************************************************
1
/**********************************************************************
2
 * Copyright (c) 2005, 2007 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUIGenerator.java,v 1.9 2007/04/19 12:28:03 paules Exp $
7
 * $Id: AutoGUIGenerator.java,v 1.9 2007/04/19 12:28:03 paules Exp $
8
 * 
8
 * 
9
 * Contributors: 
9
 * Contributors: 
10
 * IBM - Initial API and implementation
10
 * IBM - Initial API and implementation
11
 **********************************************************************/
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.codegen;
12
package org.eclipse.tptp.test.auto.gui.internal.codegen;
13
13
14
import org.eclipse.core.resources.IFile;
14
import org.eclipse.core.resources.IFile;
15
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.core.runtime.NullProgressMonitor;
17
import org.eclipse.core.runtime.NullProgressMonitor;
18
import org.eclipse.core.runtime.SubProgressMonitor;
18
import org.eclipse.core.runtime.SubProgressMonitor;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
20
import org.eclipse.hyades.test.core.internal.changes.CreateFileChange;
20
import org.eclipse.hyades.test.core.internal.changes.CreateFileChange;
21
import org.eclipse.hyades.test.tools.core.internal.common.codegen.AutomaticDependencyUpdater;
21
import org.eclipse.hyades.test.tools.core.internal.common.codegen.AutomaticDependencyUpdater;
22
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
22
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
23
import org.eclipse.hyades.test.tools.core.internal.common.codegen.IProjectDependencyUpdater;
23
import org.eclipse.hyades.test.tools.core.internal.common.codegen.IProjectDependencyUpdater;
24
import org.eclipse.hyades.test.tools.core.internal.common.codegen.ImportManager;
24
import org.eclipse.hyades.test.tools.core.internal.common.codegen.ImportManager;
25
import org.eclipse.hyades.test.tools.core.internal.common.codegen.JavaGenerator;
25
import org.eclipse.hyades.test.tools.core.internal.common.codegen.JavaGenerator;
26
import org.eclipse.hyades.test.tools.core.internal.java.codegen.JUnitGenerator.JUnitProjectDependencyUpdater;
26
import org.eclipse.hyades.test.tools.core.internal.java.codegen.JUnitGenerator.JUnitProjectDependencyUpdater;
27
import org.eclipse.jdt.core.ICompilationUnit;
27
import org.eclipse.jdt.core.ICompilationUnit;
28
import org.eclipse.jdt.core.IMethod;
28
import org.eclipse.jdt.core.IMethod;
29
import org.eclipse.jdt.core.IType;
29
import org.eclipse.jdt.core.IType;
30
import org.eclipse.jdt.core.JavaCore;
30
import org.eclipse.jdt.core.JavaCore;
31
import org.eclipse.jdt.core.JavaModelException;
31
import org.eclipse.jdt.core.JavaModelException;
32
import org.eclipse.ltk.core.refactoring.Change;
32
import org.eclipse.ltk.core.refactoring.Change;
33
import org.eclipse.ltk.core.refactoring.NullChange;
33
import org.eclipse.ltk.core.refactoring.NullChange;
34
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
34
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
35
35
36
36
37
/**
37
/**
38
 * The code generator for auto gui test suites 
38
 * The code generator for auto gui test suites 
39
 * 
39
 * 
40
 * @author Ali Mehregani
40
 * @author Ali Mehregani
41
 */
41
 * @author Alexander Nyssen
42
public class AutoGUIGenerator extends JavaGenerator
42
 */
43
{
43
public class AutoGUIGenerator extends JavaGenerator
44
	private String superclassName;
44
{
45
	private String testCaseName, testCaseDescription;
45
	private String superclassName;
46
	
46
	private String testCaseName, testCaseDescription;
47
	public AutoGUIGenerator (ITestSuite testSuite, String superClass)
47
	
48
	{
48
	public AutoGUIGenerator (ITestSuite testSuite, String superClass)
49
		super (testSuite, new AutoGUIProjectDependencyUpdater(new AutomaticDependencyUpdater(), !testSuite.getImplementor().isExternalImplementor()));
49
	{
50
		this.superclassName = superClass;
50
		super (testSuite, new AutoGUIProjectDependencyUpdater(new AutomaticDependencyUpdater(), !testSuite.getImplementor().isExternalImplementor()));
51
	}
51
		this.superclassName = superClass;
52
	
52
	}
53
	public void setInput (String testCaseName, String testCaseDescription)
53
	
54
	{
54
	public void setInput (String testCaseName, String testCaseDescription)
55
		this.testCaseName = testCaseName;
55
	{
56
		this.testCaseDescription = testCaseDescription;
56
		this.testCaseName = testCaseName;
57
	}
57
		this.testCaseDescription = testCaseDescription;
58
	
58
	}
59
	protected Change createGenerateCodeChange(IFile file, IProgressMonitor monitor) throws CoreException {
59
	
60
		String code = generateCode(monitor);
60
	protected Change createGenerateCodeChange(IFile file, IProgressMonitor monitor) throws CoreException {
61
		return new CreateFileChange(file, code, CHARSET_UTF8);
61
		String code = generateCode(monitor);
62
	}
62
		return new CreateFileChange(file, code, CHARSET_UTF8);
63
63
	}
64
	/**
64
65
	 * @see org.eclipse.hyades.test.common.internal.codegen.Generator#generateFile(org.eclipse.hyades.models.common.facades.behavioral.ITestSuite, org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor)
65
	/**
66
	 */
66
	 * @see org.eclipse.hyades.test.common.internal.codegen.Generator#generateFile(org.eclipse.hyades.models.common.facades.behavioral.ITestSuite, org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor)
67
	private String generateCode(IProgressMonitor monitor)
67
	 */
68
	throws CoreException
68
	private String generateCode(IProgressMonitor monitor)
69
	{
69
	throws CoreException
70
		CodeGeneratorHelper helper = new CodeGeneratorHelper();
70
	{
71
		if (this.superclassName != null) 
71
		CodeGeneratorHelper helper = new CodeGeneratorHelper();
72
		{
72
		if (this.superclassName != null) 
73
			helper.setSuperclassName(this.superclassName);
73
		{
74
		}
74
			helper.setSuperclassName(this.superclassName);
75
		computeTestMethodNames(getTestSuite(), getTestSuite().getImplementor().isExternalImplementor(), helper);
75
		}
76
		VerificationHookClassGenerator generator = new VerificationHookClassGenerator();
76
		computeTestMethodNames(getTestSuite(), getTestSuite().getImplementor().isExternalImplementor(), helper);
77
		return Helper.formatContent(generator.generate(getTestSuite(), helper));
77
		VerificationHookClassGenerator generator = new VerificationHookClassGenerator();
78
	}
78
		return Helper.formatContent(generator.generate(getTestSuite(), helper));
79
	
79
	}
80
	protected Change createSourceUpdateChange(IFile file, SubProgressMonitor monitor) throws CoreException {
80
	
81
		return new NullChange();
81
	protected Change createSourceUpdateChange(IFile file, SubProgressMonitor monitor) throws CoreException {
82
	}
82
		return new NullChange();
83
83
	}
84
	/**
84
85
	 * Creates a method with name = "methodName" and argument = "argument".  
85
	/**
86
	 * <br/>
86
	 * Creates a method with name = "methodName" and argument = "argument".  
87
	 * Pre-condition(s):
87
	 * <br/>
88
	 * <ul>
88
	 * Pre-condition(s):
89
	 * 	<li> Argument must either be org.eclipse.ui.IEditorPart or org.eclipse.ui.IViewPart. </li>
89
	 * <ul>
90
	 *  <li> methodName must be valid by the following standard:
90
	 * 	<li> Argument must either be org.eclipse.ui.IEditorPart or org.eclipse.ui.IViewPart. </li>
91
	 *  	<ul>
91
	 *  <li> methodName must be valid by the following standard:
92
	 *  		<li> Must begin with an alphabet </li>
92
	 *  	<ul>
93
	 *  		<li> Does not contain any special characters other than '$' '_'</li>
93
	 *  		<li> Must begin with an alphabet </li>
94
	 *  		<li> Must be less than 100 characters long </li>
94
	 *  		<li> Does not contain any special characters other than '$' '_'</li>
95
	 *  	</ul>
95
	 *  		<li> Must be less than 100 characters long </li>
96
	 *  </li> 	
96
	 *  	</ul>
97
	 * </ul>
97
	 *  </li> 	
98
	 * 
98
	 * </ul>
99
	 * @param testSuite The test suite
99
	 * 
100
	 * @param methodName The name of the method to be created
100
	 * @param testSuite The test suite
101
	 * @param argument The argument of the method (see restriction above)
101
	 * @param methodName The name of the method to be created
102
	 * @throws Exception 
102
	 * @param argument The argument of the method (see restriction above)
103
	 */
103
	 * @throws Exception 
104
	public void createMethod (String methodName, String argument) throws Exception
104
	 */
105
	{
105
	public void createMethod (String methodName, String[] arguments) throws Exception
106
		IFile javaFile = getFileHandle(getTestSuite());
106
	{
107
		ICompilationUnit cu = JavaCore.createCompilationUnitFrom(javaFile);
107
		IFile javaFile = getFileHandle(getTestSuite());
108
		IType mainClass = cu.findPrimaryType();
108
		ICompilationUnit cu = JavaCore.createCompilationUnitFrom(javaFile);
109
		
109
		IType mainClass = cu.findPrimaryType();
110
		/* The class is missing */
110
		
111
		if (mainClass == null)
111
		/* The class is missing */
112
		{
112
		if (mainClass == null)
113
			createChange(new NullProgressMonitor()).perform(new NullProgressMonitor());
113
		{
114
			cu = JavaCore.createCompilationUnitFrom(javaFile);
114
			createChange(new NullProgressMonitor()).perform(new NullProgressMonitor());
115
			mainClass = cu.findPrimaryType();
115
			cu = JavaCore.createCompilationUnitFrom(javaFile);
116
		}
116
			mainClass = cu.findPrimaryType();
117
		
117
		}
118
		
118
		
119
		cu.becomeWorkingCopy(null, new NullProgressMonitor());
119
		
120
		String[] args = {argument};
120
		cu.becomeWorkingCopy(null, new NullProgressMonitor());
121
		IMethod method = mainClass.getMethod(methodName, args);
121
		IMethod method = mainClass.getMethod(methodName, arguments);
122
		
122
		
123
		try
123
		try
124
		{
124
		{
125
			/* Create the method if it doesn't exist */
125
			/* Create the method if it doesn't exist */
126
			if (cu != null && !method.exists())
126
			if (cu != null && !method.exists())
127
			{
127
			{
128
				Helper helper = new Helper();
128
				Helper helper = new Helper();
129
				String packageName = helper.getPackageName(getTestSuite());
129
				String packageName = helper.getPackageName(getTestSuite());
130
				helper.setImportManager(new ImportManager(packageName));
130
				helper.setImportManager(new ImportManager(packageName));
131
				method = createTestMethod(mainClass, testCaseName, testCaseDescription, helper, methodName, args);
131
				method = createTestMethod(mainClass, testCaseName, testCaseDescription, helper, methodName, arguments);
132
				
132
				
133
				helper.emitSortedImports(cu);
133
				helper.emitSortedImports(cu);
134
134
135
				cu.commitWorkingCopy(/*force*/false, new NullProgressMonitor());
135
				cu.commitWorkingCopy(/*force*/false, new NullProgressMonitor());
136
			}
136
			}
137
		}
137
		}
138
		finally
138
		finally
139
		{
139
		{
140
			cu.discardWorkingCopy();
140
			cu.discardWorkingCopy();
141
		}
141
		}
142
	}
142
	}
143
143
144
	/**
144
	/**
145
	 * Creates a test method for the specified test case.
145
	 * Creates a test method for the specified test case.
146
	 */
146
	 */
147
	protected IMethod createTestMethod(IType mainClass, String testCaseName, String testCaseDescription, Helper helper, String methodName, String[] args) throws JavaModelException {
147
	protected IMethod createTestMethod(IType mainClass, String testCaseName, String testCaseDescription, Helper helper, String methodName, String[] args) throws JavaModelException {
148
		VerificationHookMethodGenerator generator = new VerificationHookMethodGenerator();
148
		VerificationHookMethodGenerator generator = new VerificationHookMethodGenerator();
149
		String content;
149
		String content;
150
		content = generator.generate(testCaseName, testCaseDescription, helper, methodName, args);
150
		content = generator.generate(testCaseName, testCaseDescription, helper, methodName, args);
151
		return mainClass.createMethod(content, null, /*force*/false, new NullProgressMonitor());
151
		return mainClass.createMethod(content, null, /*force*/false, new NullProgressMonitor());
152
	}
152
	}
153
	
153
	
154
	public static class AutoGUIProjectDependencyUpdater extends JUnitProjectDependencyUpdater {
154
	public static class AutoGUIProjectDependencyUpdater extends JUnitProjectDependencyUpdater {
155
155
156
		public AutoGUIProjectDependencyUpdater(IProjectDependencyUpdater delegate, boolean modelBehavioring) {
156
		public AutoGUIProjectDependencyUpdater(IProjectDependencyUpdater delegate, boolean modelBehavioring) {
157
			super(delegate, modelBehavioring);
157
			super(delegate, modelBehavioring);
158
			addRequiredPlugin(GuiPlugin.getID(), "autogui.jar"); //$NON-NLS-1$
158
			addRequiredPlugin(GuiPlugin.getID(), "autogui.jar"); //$NON-NLS-1$
159
		}
159
		}
160
160
161
	}
161
	}
162
162
163
}
163
}
164
164
165
	
165
	
(-)src/org/eclipse/tptp/test/auto/gui/internal/codegen/AutoGUILaunchGenerator.java (-286 / +286 lines)
Lines 1-286 Link Here
1
/**********************************************************************
1
/**********************************************************************
2
 * Copyright (c) 2005, 2007 IBM Corporation and others.
2
 * Copyright (c) 2005, 2007 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUILaunchGenerator.java,v 1.11 2007/05/02 19:35:57 paules Exp $
7
 * $Id: AutoGUILaunchGenerator.java,v 1.11 2007/05/02 19:35:57 paules Exp $
8
 * 
8
 * 
9
 * Contributors: 
9
 * Contributors: 
10
 * IBM - Initial API and implementation
10
 * IBM - Initial API and implementation
11
 **********************************************************************/
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.codegen;
12
package org.eclipse.tptp.test.auto.gui.internal.codegen;
13
13
14
import java.util.Hashtable;
14
import java.util.Hashtable;
15
import java.util.List;
15
import java.util.List;
16
import java.util.Vector;
16
import java.util.Vector;
17
17
18
import org.eclipse.emf.common.util.URI;
18
import org.eclipse.emf.common.util.URI;
19
import org.eclipse.emf.ecore.resource.Resource;
19
import org.eclipse.emf.ecore.resource.Resource;
20
import org.eclipse.emf.ecore.resource.ResourceSet;
20
import org.eclipse.emf.ecore.resource.ResourceSet;
21
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
21
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
22
import org.eclipse.hyades.datapool.iterator.DatapoolIteratorSequentialPrivate;
22
import org.eclipse.hyades.datapool.iterator.DatapoolIteratorSequentialPrivate;
23
import org.eclipse.hyades.execution.runtime.datapool.IDatapool;
23
import org.eclipse.hyades.execution.runtime.datapool.IDatapool;
24
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolCell;
24
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolCell;
25
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolFactory;
25
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolFactory;
26
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolIterator;
26
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolIterator;
27
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolRecord;
27
import org.eclipse.hyades.execution.runtime.datapool.IDatapoolRecord;
28
import org.eclipse.hyades.models.common.datapool.impl.Common_DatapoolFactoryImpl;
28
import org.eclipse.hyades.models.common.datapool.impl.Common_DatapoolFactoryImpl;
29
import org.eclipse.hyades.models.common.facades.behavioral.ILoop;
29
import org.eclipse.hyades.models.common.facades.behavioral.ILoop;
30
import org.eclipse.hyades.models.common.facades.behavioral.IProperty;
30
import org.eclipse.hyades.models.common.facades.behavioral.IProperty;
31
import org.eclipse.hyades.models.common.facades.behavioral.ITestInvocation;
31
import org.eclipse.hyades.models.common.facades.behavioral.ITestInvocation;
32
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
32
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
33
import org.eclipse.hyades.models.common.facades.behavioral.IVariable;
33
import org.eclipse.hyades.models.common.facades.behavioral.IVariable;
34
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesFactory;
34
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesFactory;
35
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
35
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper;
36
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
36
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
37
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
37
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
38
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
40
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager;
41
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
42
42
43
43
44
/**
44
/**
45
 * The code generator for serializing test suites into XML. 
45
 * The code generator for serializing test suites into XML. 
46
 * 
46
 * 
47
 * @author Ali Mehregani
47
 * @author Ali Mehregani
48
 */
48
 */
49
public class AutoGUILaunchGenerator
49
public class AutoGUILaunchGenerator
50
{
50
{
51
	
51
	
52
	public static String generateScript(ITestSuite testSuite, Vector reqPlugins)
52
	public static String generateScript(ITestSuite testSuite, Vector reqPlugins)
53
	{
53
	{
54
		/* Stores the linkage information */
54
		/* Stores the linkage information */
55
		Hashtable properties = new Hashtable(); 		
55
		Hashtable properties = new Hashtable(); 		
56
		walkThroughActions(properties, testSuite.getImplementor().getBlock().getActions());
56
		walkThroughActions(properties, testSuite.getImplementor().getBlock().getActions());
57
		
57
		
58
		addTestSuiteProperties(testSuite, properties);
58
		addTestSuiteProperties(testSuite, properties);
59
		
59
		
60
		TestSuiteToXMLConvertor genTestSuite = new TestSuiteToXMLConvertor(testSuite, reqPlugins, properties);
60
		TestSuiteToXMLConvertor genTestSuite = new TestSuiteToXMLConvertor(testSuite, reqPlugins, properties);
61
		String script = genTestSuite.generate(testSuite, new Helper());
61
		String script = genTestSuite.generate(testSuite, new Helper());
62
		
62
		
63
		String extraChars = "\t\t" + genTestSuite.NL;
63
		String extraChars = "\t\t" + genTestSuite.NL;
64
		if(script.startsWith(extraChars))
64
		if(script.startsWith(extraChars))
65
			script = script.substring(extraChars.length());
65
			script = script.substring(extraChars.length());
66
		
66
		
67
		return script;
67
		return script;
68
	}
68
	}
69
69
70
	
70
	
71
	private static void addTestSuiteProperties(ITestSuite testSuite, Hashtable properties) 
71
	private static void addTestSuiteProperties(ITestSuite testSuite, Hashtable properties) 
72
	{
72
	{
73
		Vector testSuiteProperties = new Vector();
73
		Vector testSuiteProperties = new Vector();
74
		
74
		
75
		/* Add all properties */
75
		/* Add all properties */
76
		List variables = testSuite.getVariables();
76
		List variables = testSuite.getVariables();
77
		Vector exclusionList = new Vector();
77
		Vector exclusionList = new Vector();
78
		exclusionList.add(GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
78
		exclusionList.add(GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
79
		
79
		
80
		for (int i = 0, variableSize = variables.size(); i < variableSize; i++)
80
		for (int i = 0, variableSize = variables.size(); i < variableSize; i++)
81
		{
81
		{
82
			IVariable currentVariable = (IVariable) variables.get(i);
82
			IVariable currentVariable = (IVariable) variables.get(i);
83
			String name = currentVariable.getName();
83
			String name = currentVariable.getName();
84
			String value = currentVariable.getInitialValue();
84
			String value = currentVariable.getInitialValue();
85
			if (name != null && value != null && !exclusionList.contains(name))
85
			if (name != null && value != null && !exclusionList.contains(name))
86
			{
86
			{
87
				addProperty (testSuiteProperties, name, value);
87
				addProperty (testSuiteProperties, name, value);
88
			}
88
			}
89
		}
89
		}
90
		
90
		
91
		
91
		
92
		/* We need to send out a property that can only be calculated at this level.  The variable used to
92
		/* We need to send out a property that can only be calculated at this level.  The variable used to
93
		 * refer to the location of the project of the test suite can only be calculated here */
93
		 * refer to the location of the project of the test suite can only be calculated here */
94
		addProperty (testSuiteProperties, GlobalConstants.TEST_SUITE_PROPERTY_BASE + 0, AutoGUIUtil.getTestSuiteProjectLocation(testSuite));
94
		addProperty (testSuiteProperties, GlobalConstants.TEST_SUITE_PROPERTY_BASE + 0, AutoGUIUtil.getTestSuiteProjectLocation(testSuite));
95
				
95
				
96
		/* Add the object mine of the test suite */
96
		/* Add the object mine of the test suite */
97
		addProperty (testSuiteProperties, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE, resolveObjectMine(testSuite));
97
		addProperty (testSuiteProperties, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE, resolveObjectMine(testSuite));
98
						
98
						
99
		if (testSuiteProperties.size() > 0)
99
		if (testSuiteProperties.size() > 0)
100
			properties.put(testSuite.getId(), testSuiteProperties);		
100
			properties.put(testSuite.getId(), testSuiteProperties);		
101
	}
101
	}
102
102
103
103
104
	/**
104
	/**
105
	 * Serialize the object mine passed in.  The serialization inlines external object mines that have been included.  
105
	 * Serialize the object mine passed in.  The serialization inlines external object mines that have been included.  
106
	 * This is so as to avoid having to send a seperate property for each included object mine.
106
	 * This is so as to avoid having to send a seperate property for each included object mine.
107
	 * 
107
	 * 
108
	 * @param objectMine The object mine
108
	 * @param objectMine The object mine
109
	 * @param buffer The buffer that will be used to write the object mine to
109
	 * @param buffer The buffer that will be used to write the object mine to
110
	 */
110
	 */
111
	private static void serializeObjectMine(IObjectMine objectMine, StringBuffer buffer)
111
	private static void serializeObjectMine(MacroObjectDescriptorMine objectMine, StringBuffer buffer)
112
	{
112
	{
113
		/* Walk through each of the included object mines of the test suite */
113
		/* Walk through each of the included object mines of the test suite */
114
		List includes = objectMine.getIncludes();
114
		List includes = objectMine.getIncludes();
115
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
115
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
116
		{
116
		{
117
			serializeObjectMine((IObjectMine)includes.get(i), buffer);
117
			serializeObjectMine((MacroObjectDescriptorMine)includes.get(i), buffer);
118
		}
118
		}
119
		
119
		
120
		/* Add the object that have been directly registered with the object mine passed in */
120
		/* Add the object that have been directly registered with the object mine passed in */
121
		buffer.append(objectMine.serializeObjetsToString());
121
		buffer.append(objectMine.serializeObjetsToString());
122
	}
122
	}
123
	
123
	
124
124
125
	private static String resolveObjectMine(ITestSuite testSuite)
125
	private static String resolveObjectMine(ITestSuite testSuite)
126
	{
126
	{
127
		IObjectMine objectMine = null;
127
		MacroObjectDescriptorMine objectMine = null;
128
		try
128
		try
129
		{
129
		{
130
			objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite);
130
			objectMine = MacroObjectDescriptorMineManager.getInstance().loadObjectMine(testSuite);
131
		} 
131
		} 
132
		catch (Exception e)
132
		catch (Exception e)
133
		{
133
		{
134
			return MacroConstants.EMPTY_STRING;
134
			return MacroConstants.EMPTY_STRING;
135
		} 
135
		} 
136
136
137
		if (objectMine == null)
137
		if (objectMine == null)
138
			return MacroConstants.EMPTY_STRING;
138
			return MacroConstants.EMPTY_STRING;
139
		
139
		
140
		StringBuffer buffer = new StringBuffer();
140
		StringBuffer buffer = new StringBuffer();
141
		
141
		
142
		/* Open the starting elements
142
		/* Open the starting elements
143
		 * <object-mine> 
143
		 * <object-mine> 
144
		 * 		<objects> */
144
		 * 		<objects> */
145
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECT_MINE_ELEMENT, false, true);
145
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECT_MINE_ELEMENT, false, true);
146
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECTS_ELEMENT, false, true);
146
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECTS_ELEMENT, false, true);
147
		serializeObjectMine (objectMine, buffer);
147
		serializeObjectMine (objectMine, buffer);
148
				
148
				
149
		/* Close the elements */
149
		/* Close the elements */
150
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECTS_ELEMENT, true, true);
150
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECTS_ELEMENT, true, true);
151
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECT_MINE_ELEMENT, true, true);
151
		MacroUtil.addElement(buffer, 0, MacroConstants.OBJECT_MINE_ELEMENT, true, true);
152
		
152
		
153
		return buffer.toString();
153
		return buffer.toString();
154
	}
154
	}
155
	
155
	
156
	
156
	
157
	private static void addProperty (Vector propertyContainer, String name, String value)
157
	private static void addProperty (Vector propertyContainer, String name, String value)
158
	{
158
	{
159
		if (value == null)
159
		if (value == null)
160
			return;
160
			return;
161
		
161
		
162
		IProperty prop = HyadesFactory.INSTANCE.createProperty();
162
		IProperty prop = HyadesFactory.INSTANCE.createProperty();
163
		prop.setName(name);
163
		prop.setName(name);
164
		prop.setValue(value);
164
		prop.setValue(value);
165
165
166
		propertyContainer.add(prop);		
166
		propertyContainer.add(prop);		
167
	}
167
	}
168
168
169
	private static void walkThroughActions (Hashtable linkageOfProperties, List actions)
169
	private static void walkThroughActions (Hashtable linkageOfProperties, List actions)
170
	{
170
	{
171
		/* Walk throught the test invocations of the test suite and link the datapool entries accordingly
171
		/* Walk throught the test invocations of the test suite and link the datapool entries accordingly
172
		 * just before we parse */
172
		 * just before we parse */
173
		for (int i = 0, actionsSize = actions.size(); i < actionsSize; i++)
173
		for (int i = 0, actionsSize = actions.size(); i < actionsSize; i++)
174
		{
174
		{
175
			/* If in case the item is a test invocation */
175
			/* If in case the item is a test invocation */
176
			if (actions.get(i) instanceof ITestInvocation)
176
			if (actions.get(i) instanceof ITestInvocation)
177
				linkUserInput (linkageOfProperties, (ITestInvocation)actions.get(i));
177
				linkUserInput (linkageOfProperties, (ITestInvocation)actions.get(i));
178
			
178
			
179
			/* If in case the item is a loop */
179
			/* If in case the item is a loop */
180
			if (actions.get(i) instanceof ILoop)
180
			if (actions.get(i) instanceof ILoop)
181
			{
181
			{
182
				ILoop loop = (ILoop)actions.get(i);
182
				ILoop loop = (ILoop)actions.get(i);
183
				walkThroughActions (linkageOfProperties, loop.getBlock().getActions());
183
				walkThroughActions (linkageOfProperties, loop.getBlock().getActions());
184
			}
184
			}
185
		}
185
		}
186
	}
186
	}
187
	private static void linkUserInput (Hashtable linkageOfProperties, ITestInvocation testInvocation)
187
	private static void linkUserInput (Hashtable linkageOfProperties, ITestInvocation testInvocation)
188
	{
188
	{
189
		Vector propertyList = new Vector();
189
		Vector propertyList = new Vector();
190
		List properties = testInvocation.getActionProperties().getProperties();
190
		List properties = testInvocation.getActionProperties().getProperties();
191
		for (int j = 0; j < properties.size(); j++)
191
		for (int j = 0; j < properties.size(); j++)
192
		{
192
		{
193
			IProperty currentProperty = (IProperty)properties.get(j);
193
			IProperty currentProperty = (IProperty)properties.get(j);
194
			
194
			
195
			if (currentProperty == null)
195
			if (currentProperty == null)
196
				continue;
196
				continue;
197
			
197
			
198
			/* Datapool link */
198
			/* Datapool link */
199
			if (currentProperty.getName().startsWith(GlobalConstants.DATAPOOL_LINK_PROPERTY_BASE))
199
			if (currentProperty.getName().startsWith(GlobalConstants.DATAPOOL_LINK_PROPERTY_BASE))
200
			{
200
			{
201
				String propertyValue = currentProperty.getValue();
201
				String propertyValue = currentProperty.getValue();
202
				
202
				
203
				/* Find the value in the datapool referenced by this field */
203
				/* Find the value in the datapool referenced by this field */
204
				Object[] fields = parsePropertyFields (propertyValue);
204
				Object[] fields = parsePropertyFields (propertyValue);
205
				
205
				
206
				/* We're expecting at least three fields here (Datapool path, datapool record index, datapool variable)*/
206
				/* We're expecting at least three fields here (Datapool path, datapool record index, datapool variable)*/
207
				if (fields.length < 3)
207
				if (fields.length < 3)
208
					continue;
208
					continue;
209
				
209
				
210
				ResourceSet resourceSet = null;
210
				ResourceSet resourceSet = null;
211
				Resource res = null;
211
				Resource res = null;
212
				try
212
				try
213
				{
213
				{
214
					resourceSet = new ResourceSetImpl();
214
					resourceSet = new ResourceSetImpl();
215
					res = resourceSet.getResource(URI.createPlatformResourceURI((String)fields[0]), true);
215
					res = resourceSet.getResource(URI.createPlatformResourceURI((String)fields[0]), true);
216
					res.load(null); 
216
					res.load(null); 
217
				}
217
				}
218
				catch (Exception e1)
218
				catch (Exception e1)
219
				{
219
				{
220
					/* Don't link if we can't load the resource */
220
					/* Don't link if we can't load the resource */
221
					continue;
221
					continue;
222
				}
222
				}
223
				
223
				
224
				IDatapoolFactory dpFactory = new Common_DatapoolFactoryImpl();
224
				IDatapoolFactory dpFactory = new Common_DatapoolFactoryImpl();
225
				IDatapool datapool = (IDatapool)res.getContents().get(0);
225
				IDatapool datapool = (IDatapool)res.getContents().get(0);
226
				IDatapoolIterator iter = dpFactory.open(datapool, DatapoolIteratorSequentialPrivate.class.getName());
226
				IDatapoolIterator iter = dpFactory.open(datapool, DatapoolIteratorSequentialPrivate.class.getName());
227
				iter.dpInitialize(datapool, -1);
227
				iter.dpInitialize(datapool, -1);
228
228
229
				int datapoolCellInx = Integer.parseInt((String)fields[1]);
229
				int datapoolCellInx = Integer.parseInt((String)fields[1]);
230
				
230
				
231
				for (int k = 0; k < datapoolCellInx && !iter.dpDone(); k++)
231
				for (int k = 0; k < datapoolCellInx && !iter.dpDone(); k++)
232
					iter.dpNext();
232
					iter.dpNext();
233
				
233
				
234
				if (iter.dpDone())
234
				if (iter.dpDone())
235
					continue;
235
					continue;
236
				
236
				
237
				IDatapoolRecord datapoolRecord = iter.dpCurrent();
237
				IDatapoolRecord datapoolRecord = iter.dpCurrent();
238
				IDatapoolCell cell = datapoolRecord.getCell((String)fields[2]);
238
				IDatapoolCell cell = datapoolRecord.getCell((String)fields[2]);
239
				if (cell == null)
239
				if (cell == null)
240
					continue;
240
					continue;
241
				
241
				
242
				IProperty linkage = HyadesFactory.INSTANCE.createProperty();
242
				IProperty linkage = HyadesFactory.INSTANCE.createProperty();
243
				linkage.setName(currentProperty.getName());
243
				linkage.setName(currentProperty.getName());
244
				linkage.setValue((String)cell.getCellValue());
244
				linkage.setValue((String)cell.getCellValue());
245
				propertyList.add(linkage);
245
				propertyList.add(linkage);
246
			}	
246
			}	
247
			
247
			
248
			/* Otherwise, just add the property */
248
			/* Otherwise, just add the property */
249
			else
249
			else
250
			{
250
			{
251
				propertyList.add(currentProperty);
251
				propertyList.add(currentProperty);
252
			}
252
			}
253
		}
253
		}
254
		
254
		
255
		if (!propertyList.isEmpty())
255
		if (!propertyList.isEmpty())
256
			linkageOfProperties.put (testInvocation.getId(), propertyList);
256
			linkageOfProperties.put (testInvocation.getId(), propertyList);
257
	}
257
	}
258
	/**
258
	/**
259
	 *
259
	 *
260
	 * @param propertyValue
260
	 * @param propertyValue
261
	 * @return
261
	 * @return
262
	 */
262
	 */
263
	public static Object[] parsePropertyFields(String propertyValue)
263
	public static Object[] parsePropertyFields(String propertyValue)
264
	{
264
	{
265
		final String sepChar = "::";
265
		final String sepChar = "::";
266
		String currentField = propertyValue;
266
		String currentField = propertyValue;
267
		Vector fields = new Vector (3);
267
		Vector fields = new Vector (3);
268
		
268
		
269
		do
269
		do
270
		{
270
		{
271
			int inx = currentField.indexOf(sepChar);
271
			int inx = currentField.indexOf(sepChar);
272
			if (inx > 0 && currentField.length() > inx + 2)
272
			if (inx > 0 && currentField.length() > inx + 2)
273
			{
273
			{
274
				fields.add (currentField.substring(0, inx));
274
				fields.add (currentField.substring(0, inx));
275
				currentField = currentField.substring(inx + 2);
275
				currentField = currentField.substring(inx + 2);
276
			}
276
			}
277
			else if (currentField.length() > 0)
277
			else if (currentField.length() > 0)
278
			{
278
			{
279
				fields.add (currentField);
279
				fields.add (currentField);
280
				currentField = null;
280
				currentField = null;
281
			}
281
			}
282
		}while (currentField != null);
282
		}while (currentField != null);
283
		
283
		
284
		return fields.toArray();
284
		return fields.toArray();
285
	}
285
	}
286
}
286
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroUtil.java (-1312 / +792 lines)
Lines 1-1313 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
12
13
import java.io.IOException;
13
import java.io.IOException;
14
import java.io.InputStream;
14
import java.io.InputStream;
15
import java.util.Hashtable;
15
import java.util.Hashtable;
16
import java.util.Vector;
16
17
17
import javax.xml.parsers.ParserConfigurationException;
18
import javax.xml.parsers.ParserConfigurationException;
18
import javax.xml.parsers.SAXParser;
19
import javax.xml.parsers.SAXParser;
19
import javax.xml.parsers.SAXParserFactory;
20
import javax.xml.parsers.SAXParserFactory;
20
21
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.core.runtime.IPath;
23
import org.eclipse.core.runtime.IPath;
23
import org.eclipse.core.runtime.Path;
24
import org.eclipse.core.runtime.Path;
24
import org.eclipse.hyades.test.common.util.XMLUtil;
25
import org.eclipse.hyades.test.common.util.XMLUtil;
25
import org.eclipse.jface.action.ContributionManager;
26
import org.eclipse.jface.action.ActionContributionItem;
26
import org.eclipse.jface.action.CoolBarManager;
27
import org.eclipse.jface.action.CoolBarManager;
27
import org.eclipse.jface.action.IMenuManager;
28
import org.eclipse.jface.action.IAction;
28
import org.eclipse.jface.action.IToolBarManager;
29
import org.eclipse.jface.action.IContributionItem;
29
import org.eclipse.jface.action.MenuManager;
30
import org.eclipse.jface.action.IMenuManager;
30
import org.eclipse.jface.action.ToolBarManager;
31
import org.eclipse.jface.action.IToolBarManager;
31
import org.eclipse.jface.window.ApplicationWindow;
32
import org.eclipse.jface.action.MenuManager;
32
import org.eclipse.jface.wizard.IWizardPage;
33
import org.eclipse.jface.action.ToolBarManager;
33
import org.eclipse.jface.wizard.WizardDialog;
34
import org.eclipse.jface.window.ApplicationWindow;
34
import org.eclipse.osgi.util.NLS;
35
import org.eclipse.jface.window.Window;
35
import org.eclipse.swt.SWT;
36
import org.eclipse.jface.wizard.IWizardPage;
36
import org.eclipse.swt.graphics.Point;
37
import org.eclipse.jface.wizard.WizardDialog;
37
import org.eclipse.swt.graphics.Rectangle;
38
import org.eclipse.osgi.util.NLS;
38
import org.eclipse.swt.widgets.Button;
39
import org.eclipse.swt.custom.CTabFolder;
39
import org.eclipse.swt.widgets.Composite;
40
import org.eclipse.swt.custom.CTabItem;
40
import org.eclipse.swt.widgets.Control;
41
import org.eclipse.swt.graphics.Point;
41
import org.eclipse.swt.widgets.CoolBar;
42
import org.eclipse.swt.graphics.Rectangle;
42
import org.eclipse.swt.widgets.Display;
43
import org.eclipse.swt.widgets.Button;
43
import org.eclipse.swt.widgets.Event;
44
import org.eclipse.swt.widgets.Composite;
44
import org.eclipse.swt.widgets.Menu;
45
import org.eclipse.swt.widgets.Control;
45
import org.eclipse.swt.widgets.MenuItem;
46
import org.eclipse.swt.widgets.CoolBar;
46
import org.eclipse.swt.widgets.Shell;
47
import org.eclipse.swt.widgets.Display;
47
import org.eclipse.swt.widgets.ToolBar;
48
import org.eclipse.swt.widgets.Event;
48
import org.eclipse.swt.widgets.ToolItem;
49
import org.eclipse.swt.widgets.Item;
49
import org.eclipse.swt.widgets.Widget;
50
import org.eclipse.swt.widgets.Menu;
50
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
51
import org.eclipse.swt.widgets.MenuItem;
51
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
52
import org.eclipse.swt.widgets.Shell;
52
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
53
import org.eclipse.swt.widgets.TabFolder;
53
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
54
import org.eclipse.swt.widgets.TabItem;
54
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
55
import org.eclipse.swt.widgets.ToolBar;
55
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
56
import org.eclipse.swt.widgets.ToolItem;
56
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
57
import org.eclipse.swt.widgets.Widget;
57
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
58
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
58
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate;
59
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
59
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
60
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
60
import org.eclipse.ui.IEditorPart;
61
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
61
import org.eclipse.ui.IEditorReference;
62
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
62
import org.eclipse.ui.IPartListener;
63
import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData;
63
import org.eclipse.ui.IViewPart;
64
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
64
import org.eclipse.ui.IViewReference;
65
import org.eclipse.tptp.test.auto.gui.internal.resolvers.PrimitiveWidgetId;
65
import org.eclipse.ui.IWorkbench;
66
import org.eclipse.ui.IEditorPart;
66
import org.eclipse.ui.IWorkbenchPage;
67
import org.eclipse.ui.IPartListener;
67
import org.eclipse.ui.IWorkbenchPart;
68
import org.eclipse.ui.IPluginContribution;
68
import org.eclipse.ui.IWorkbenchWindow;
69
import org.eclipse.ui.IViewPart;
69
import org.eclipse.ui.PartInitException;
70
import org.eclipse.ui.IViewReference;
70
import org.eclipse.ui.intro.IIntroManager;
71
import org.eclipse.ui.IWorkbench;
71
import org.eclipse.ui.intro.IIntroPart;
72
import org.eclipse.ui.IWorkbenchPage;
72
import org.eclipse.ui.testing.IWorkbenchPartTestable;
73
import org.eclipse.ui.IWorkbenchPart;
73
import org.w3c.dom.Node;
74
import org.eclipse.ui.IWorkbenchPartSite;
74
import org.xml.sax.SAXException;
75
import org.eclipse.ui.IWorkbenchWindow;
75
76
import org.eclipse.ui.intro.IIntroManager;
76
/**
77
import org.eclipse.ui.intro.IIntroPart;
77
 * A helper class that is used while recording a macro. <b>Important: </b> This class uses internal classes.
78
import org.w3c.dom.Node;
78
 * 
79
import org.xml.sax.SAXException;
79
 * @author Alexander Nyssen (moved everything related to resolving/deresolving out of here
80
80
 */
81
/**
81
public class MacroUtil {
82
 * A helper class that is used while recording a macro. <b>Important: </b> This
82
83
 * class uses internal classes.
83
	/** The parser used to parse XML fragments */
84
 */
84
	private static SAXParser parser;
85
public class MacroUtil
85
86
{	
86
	private static Hashtable workbenchPartListeners = new Hashtable();
87
	private static Hashtable workbenchPartListeners;
87
	private static IPartListener workbenchPartListener = new IPartListener() {
88
	private static WorkbenchPartListener workbenchPartLisntener;
88
89
	
89
		public void partActivated(IWorkbenchPart part) {
90
	/** The parser used to parse XML fragments */
90
			/* Doesn't need to be implemented */
91
	private static SAXParser parser;
91
		}
92
		
92
93
	static
93
		public void partBroughtToTop(IWorkbenchPart part) {
94
	{
94
			/* Doesn't need to be implemented */
95
		workbenchPartListeners = new Hashtable();
95
		}
96
	}
96
97
	
97
		/**
98
	/**
98
		 * This method will generate a close workbench part command. We can't determine for sure through events reported by a display of when a
99
	 * Returns the path where counters of the given event are stored, or null if
99
		 * workbench part is closed. This part listener is a work around that allows us to capture close events on workbench parts.
100
	 * we are not keeping records of the given event.
100
		 * 
101
	 * 
101
		 * @param part
102
	 * @param event
102
		 *            The part is closed.
103
	 * @return
103
		 */
104
	 */
104
		public void partClosed(IWorkbenchPart part) {
105
	public static WidgetIdentifier getWidgetIdentifier(Widget widget)
105
			Macro currentMacro = MacroManager.getInstance().getCurrentMacro();
106
	{
106
			Event event = new Event();
107
		IWidgetId widgetId = null;
107
108
		if (widget instanceof MenuItem)
108
			event.type = EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED;
109
		{
109
			event.data = part;
110
			MenuItem menuItem = (MenuItem) widget;
110
			event.display = part.getSite().getShell().getDisplay();
111
			widgetId = determineItemId (menuItem);
111
			if (currentMacro != null) {
112
			IViewPart view = null;
112
				try {
113
			if (onMenubar(menuItem))
113
					currentMacro.addEvent(event);
114
			{								
114
				}
115
				return new WidgetIdentifier(new Path(MacroConstants.MENUS_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$
115
				catch (Exception e) {
116
			}			
116
					/* Ignore the error. It doesn't generate the command */
117
			else if ((view = onWorkbenchPartToolbar(menuItem)) != null)
117
					e.printStackTrace();
118
			{
118
				}
119
				/* The context id should be the workbench part toolbar */			
119
			}
120
				IToolBarManager toolbarManager = view.getViewSite().getActionBars().getToolBarManager();
120
		}
121
				if (toolbarManager == null || !(toolbarManager instanceof ToolBarManager))
121
122
					return null;
122
		public void partDeactivated(IWorkbenchPart part) {
123
								
123
			/* Doesn't need to be implemented */
124
				view.setFocus();
124
		}
125
				WidgetIdentifier contextId = getControlIdentifier(((ToolBarManager)toolbarManager).getControl());
125
126
				return new WidgetIdentifier(new Path(MacroConstants.LOCAL_TOOLBAR_MENU_VALUE).append(contextId.getFullyQualifiedPath()), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$				
126
		public void partOpened(IWorkbenchPart part) {
127
			}
127
			/* Doesn't need to be implemented */
128
			Control c = widget.getDisplay().getFocusControl();
128
		}
129
			WidgetIdentifier ci = getControlIdentifier(c);
129
	};
130
			if (ci == null)
130
131
				return null;
131
	private static IWorkbenchWindow findHookTarget(Widget widget) {
132
			return new WidgetIdentifier(new Path(MacroConstants.POPUP_VALUE).append(ci.getFullyQualifiedPath()), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$
132
		if (widget instanceof MenuItem) {
133
		}
133
			MenuItem menuItem = (MenuItem) widget;
134
		else if (widget instanceof ToolItem)
134
			IViewPart view = null;
135
		{
135
			if ((view = onWorkbenchPartToolbar(menuItem)) != null) {
136
			ToolItem toolItem = (ToolItem) widget;
136
				// TODO: check if the toolbar manager has to be used to find the hook target...
137
			widgetId = determineItemId (toolItem);
137
				/* The context id should be the workbench part toolbar */
138
			
138
				IToolBarManager toolbarManager = view.getViewSite().getActionBars().getToolBarManager();
139
			/* Check to see if this toolbar belongs to the global toolbar of the workbench */
139
				if (toolbarManager == null || !(toolbarManager instanceof ToolBarManager))
140
			if (onToolbar(toolItem))
140
					return null;
141
				return new WidgetIdentifier(new Path(MacroConstants.TOOLBAR_VALUE), new Path(widgetId.toString()), widgetId.getResolverId()); //$NON-NLS-1$
141
142
142
				// CHECK: setting the focus does not seem to be necessary to find a hook target
143
			/* Local toolbar somewhere - locate the parent first */
143
				// -> wihtout it, this method is side effect free
144
			ToolBar toolBar = toolItem.getParent();
144
				// view.setFocus();
145
			WidgetIdentifier controlId = getControlIdentifier(toolBar);
145
				return findHookTarget(((ToolBarManager) toolbarManager).getControl());
146
			if (controlId != null)
146
			}
147
			{
147
			Control c = widget.getDisplay().getFocusControl();
148
				IPath localPath = controlId.getFullyQualifiedPath();
148
			return findHookTarget(c);
149
				return new WidgetIdentifier(new Path(MacroConstants.LOCAL_TOOLBAR_VALUE).append(localPath), new Path(widgetId.toString()), widgetId.getResolverId());
149
		}
150
			}
150
		else if (widget instanceof ToolItem) {
151
		}
151
			ToolItem toolItem = (ToolItem) widget;
152
		else if (widget instanceof Shell)
152
153
		{
153
			/* Local toolbar somewhere - locate the parent first */
154
			widgetId =  getShellId((Shell) widget, null);
154
			ToolBar toolBar = toolItem.getParent();
155
			return new WidgetIdentifier(new Path(MacroConstants.SHELL_VALUE), new Path(widgetId.toString()), widgetId.getResolverId());
155
			return findHookTarget(toolBar);
156
		}
156
		}
157
		else if (widget instanceof Control)
157
		else if (widget instanceof Control) {
158
		{
158
			Shell shell = ((Control) widget).getShell();
159
			return getControlIdentifier((Control) widget);
159
			Object data = shell.getData();
160
		}
160
			if (data instanceof IWorkbenchWindow) {
161
		else if (widget instanceof Menu)
161
				IWorkbenchWindow window = (IWorkbenchWindow) data;
162
		{
162
				return window;
163
			widgetId = getActionId((Menu) widget);
163
			}
164
			return new WidgetIdentifier(new Path(MacroConstants.MENUS_VALUE), new Path(widgetId.toString()), widgetId.getResolverId());
164
			return null;
165
		}
165
		}
166
		return null;
166
		return null;
167
	}
167
	}
168
	
168
169
169
	protected static void hookWorkbenchPartListener(Widget widget) {
170
	public static IWidgetId getShellId(Shell shell, String resolverId)
170
		IWorkbenchWindow workbenchWindow = findHookTarget(widget);
171
	{
171
		if (workbenchWindow != null) {
172
		IWidgetId widgetId = MacroManager.getInstance().resolveWidget(shell.getParent(), shell, resolverId, newCounter());
172
			IWorkbenchPage page = workbenchWindow.getActivePage();
173
		if (widgetId != null)
173
174
			return widgetId;
174
			/**
175
		return getDefaultShellId(shell);
175
			 * Ali M.: Under some situations, the part that is returned by the 'getActivePart' method is the old active part. Although the control
176
	}
176
			 * object is coming from the newly active part, the part that is retrieved below will be from the old active part. This will cause
177
177
			 * MacroUtil.getControlIdentifier to return null when attempting to retrieve the widget id in the wrong context. One situation that this
178
	public static IWidgetId getDefaultShellId(Shell shell)
178
			 * fails under is when: - Macro recorder start while the test suite editor is active - A hook is inserted - The package view is focused
179
	{
179
			 * (not activated and focused but just focused)
180
		Object data = shell.getData();
180
			 * 
181
		String id = "";
181
			 * To resolve this issue, I have registered a part listener when the client starts recording. When there is a new active part detected, an
182
		if (data instanceof WizardDialog)
182
			 * event is created and fired to the usual onEvent handler in MacroManager. See MacroManager.hookPartListener.
183
		{
183
			 */
184
			id = data.getClass().getName().toString();
184
			IWorkbenchPart part = page.getActivePart();
185
		}
185
			/*
186
		else if (data instanceof Window)
186
			 * 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
187
		{
187
			 * generated.
188
			id = data.getClass().getName().toString();
188
			 */
189
		}
189
			if (workbenchPartListeners.get(page) == null) {
190
		
190
				page.addPartListener(workbenchPartListener);
191
		PrimitiveWidgetId widgetId = new PrimitiveWidgetId();
191
				workbenchPartListeners.put(page,
192
		widgetId.setId(id);
192
					workbenchPartListener);
193
		return widgetId;
193
			}
194
	}
194
		}
195
	
195
	}
196
	public static WidgetIdentifier getControlIdentifier(Control control)
196
197
	{
197
	public static int[] newCounter() {
198
		Shell shell = control.getShell();
198
		int[] inx = new int[1];
199
		Object data = shell.getData();
199
		inx[0] = 0;
200
		if (data instanceof WizardDialog)
200
		return inx;
201
		{
201
	}
202
			// in wizard
202
203
			WizardDialog wd = (WizardDialog) data;
203
	public static boolean isInputControl(Control control) {
204
			IWizardPage page = wd.getCurrentPage();
204
		return true;
205
			if (page == null)
205
	}
206
				return null;
206
207
			Control pageControl = page.getControl();
207
	/*
208
			IWidgetId relativePath = computeRelativePath((Composite) pageControl, null, control);
208
	 * (non-Javadoc)
209
			if (relativePath != null)
209
	 * 
210
			{
210
	 * @see org.eclipse.instrumentation.IDataProvider#getDefaultValue(org.eclipse.core.runtime.IPath)
211
				IPath path = new Path(MacroConstants.WIZARD_PAGE_VALUE).append(page.getName());
211
	 */
212
				return new WidgetIdentifier(path, new Path(relativePath.toString()), relativePath.getResolverId());
212
	public Object getDefaultValue(IPath node) {
213
			}
213
		return null;
214
			// check for wizard buttons
214
	}
215
			if (control instanceof Button)
215
216
			{
216
	private MenuItem getMenuItem(Menu menu, IPath menuPath) {
217
				relativePath = computeRelativePath(shell, (Composite) pageControl, control);
217
		if (menuPath.isEmpty()) {
218
				return new WidgetIdentifier(new Path(MacroConstants.WIZARD_VALUE), new Path(relativePath.toString()), relativePath.getResolverId());
218
			return null;
219
			}
219
		}
220
			return null;
220
221
		}
221
		String toFind = menuPath.segment(0);
222
		else if (data instanceof IWorkbenchWindow)
222
		MenuItem[] items = menu.getItems();
223
		{
223
224
224
		for (int idx = 0; idx < items.length; idx++) {
225
			IWorkbenchWindow window = (IWorkbenchWindow) data;
225
			MenuItem item = items[idx];
226
			IWorkbenchPage page = window.getActivePage();
226
227
227
			String itemName = removeChar(item.getText(),
228
			/**
228
				'&');
229
			 * Ali M.: Under some situations, the part that is returned by the
229
230
			 * 'getActivePart' method is the old active part. Although the
230
			if (itemName.equals(toFind)) {
231
			 * control object is coming from the newly active part, the part
231
				return getMenuItem(item,
232
			 * that is retrieved below will be from the old active part. This
232
					menuPath.removeFirstSegments(1));
233
			 * will cause MacroUtil.getControlIdentifier to return null when
233
			}
234
			 * attempting to retrieve the widget id in the wrong context. One
234
		}
235
			 * situation that this fails under is when: - Macro recorder start
235
236
			 * while the test suite editor is active - A hook is inserted - The
236
		return null;
237
			 * package view is focused (not activated and focused but just
237
	}
238
			 * focused)
238
239
			 * 
239
	private MenuItem getMenuItem(MenuItem menu, IPath menuPath) {
240
			 * To resolve this issue, I have registered a part listener when the
240
		if (menuPath.isEmpty()) {
241
			 * client starts recording. When there is a new active part
241
			return menu;
242
			 * detected, an event is created and fired to the usual onEvent
242
		}
243
			 * handler in MacroManager. See MacroManager.hookPartListener.
243
244
			 */
244
		Menu subMenu = menu.getMenu();
245
			IWorkbenchPart part = page.getActivePart();
245
		if (subMenu == null) {
246
			IWorkbenchPartSite site = part.getSite();
246
			return null;
247
247
		}
248
			
248
249
			/* Ali M.: Register a dispose listener with this workbench part if we have not
249
		return getMenuItem(subMenu,
250
			 * already done so.  This is so that close commands can be generated. */
250
			menuPath);
251
			if (workbenchPartListeners.get(page) == null)
251
252
			{				
252
	}
253
				if (workbenchPartLisntener == null)
253
254
					workbenchPartLisntener = new WorkbenchPartListener();
254
	public static void forceMenuClosed(Menu menu) {
255
				
255
		Event e = new Event();
256
				page.addPartListener(workbenchPartLisntener);
256
		e.type = SWT.Hide;
257
				workbenchPartListeners.put(page, workbenchPartLisntener);
257
		e.widget = menu;
258
			}
258
	
259
			
259
		menu.notifyListeners(e.type, e);
260
			IPath path;
260
		processDisplayEvents(menu.getDisplay());
261
261
	}
262
			if (part instanceof IViewPart)
262
263
			{
263
	public static void forceMenuOpen(Menu menu) {
264
				path = new Path(MacroConstants.VIEW_VALUE).append(site.getId());
264
		Event e = new Event();
265
			}
265
		e.type = SWT.Show;
266
			else if (part instanceof IEditorPart)
266
		e.widget = menu;
267
			{
267
	
268
				String inputName = ((IEditorPart) part).getEditorInput().getName();
268
		menu.notifyListeners(e.type, e);
269
				path = new Path(MacroConstants.EDITOR_VALUE).append(site.getId()).append(inputName);
269
		processDisplayEvents(menu.getDisplay());
270
			}
270
	}
271
			else
271
272
			{
272
	public static String getAttribute(Node node, String name) {
273
				return null;
273
		Node value = node.getAttributes().getNamedItem(name);
274
			}
274
		if (value != null)
275
275
			return value.getNodeValue();
276
			Composite paneComposite = MacroObjectLocator.getWorkbenchPartControl(part);
276
		return null;
277
277
	}
278
			/* If the control we are looking for is a local tool bar, go up one level */
278
279
			if (part instanceof IViewPart && control instanceof ToolBar)
279
	/**
280
				paneComposite = paneComposite.getParent();
280
	 * Adds an XML element to the string buffer passed in.
281
			IWidgetId relativePath = computeRelativePath(paneComposite, null, control);
281
	 * 
282
282
	 * @param stringBuffer
283
			if (relativePath != null)
283
	 *            The string buffer that the element will be written to
284
			{
284
	 * @param indent
285
				return new WidgetIdentifier(path, new Path(relativePath.toString()), relativePath.getResolverId());
285
	 *            The number of indents that should be prefixed to the element written
286
			}
286
	 * @param elementName
287
		}
287
	 *            The element name
288
		else
288
	 * @param close
289
		{
289
	 *            Indicates whether this element should be closed or not. If set, a forward slash is added before theelement is ended.
290
			/* unknown shell - fetch controls starting from the shell */
290
	 * @param end
291
			IWidgetId relativePath = computeRelativePath(shell, null, control);
291
	 *            Indicates if the element should be ended with a closed angle bracket. For example elements requring attributes are not ended.
292
			if (relativePath == null)
292
	 */
293
				return null;
293
	public static void addElement(StringBuffer stringBuffer, int indent, String elementName, boolean close, boolean end) {
294
			return new WidgetIdentifier(new Path(MacroConstants.SHELL_VALUE), new Path(relativePath.toString()), relativePath.getResolverId());
294
		addIndent(stringBuffer,
295
		}
295
			indent);
296
		return null;
296
		stringBuffer.append(MacroConstants.OPEN_ANGLE_BRACKET);
297
	}
297
		stringBuffer.append(close
298
298
			? MacroConstants.FORWARD_SLASH
299
	private static IWidgetId computeRelativePath(Composite parent, Composite skip, Control control)
299
			: MacroConstants.EMPTY_STRING);
300
	{
300
		stringBuffer.append(elementName);
301
		int[] counter = newCounter();
301
		stringBuffer.append(end
302
		Vector indices = new Vector();		
302
			? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR
303
		boolean result = computeControlIndex(parent, skip, control, counter, indices);
303
			: MacroConstants.EMPTY_STRING);
304
		if (!result && skip == null)
304
	}
305
			return null;
305
306
		
306
	/**
307
		int index = result ? ((Integer)indices.get(0)).intValue() : 0;
307
	 * Adds XML attributes to the string buffer passed in. Attributes with a null value will not be written.
308
		IWidgetId widgetId = MacroManager.getInstance().resolveWidget(control, null, newCounter());
308
	 * 
309
		if (widgetId != null)
309
	 * Pre-condition:
310
			return widgetId;
310
	 * <ul>
311
		return computeDefaultControlId(control, index);
311
	 * <li> attributes and attributeValues must be valid (i.e. non-null) </li>
312
	}
312
	 * <li> attributes and attributeValues length must be the same </li>
313
313
	 * </ul>
314
	
314
	 * 
315
	public static int[] newCounter()
315
	 * @param stringBuffer
316
	{
316
	 *            The string buffer that the attributes will be written to
317
		int[] inx = new int[1];
317
	 * @param attributeNames
318
		inx[0] = 0;
318
	 *            The attribute names
319
		return inx;
319
	 * @param attributeValues
320
	}
320
	 *            The attribute values
321
	
321
	 * @param close
322
	
322
	 *            If set, a forward slash is added after the attributes.
323
	/**
323
	 * @param end
324
	 * Determines the index of the desiredControl relative to the parent control sent in.  The
324
	 *            If set, a closed angle bracket is added after the attributes
325
	 * Index is stored in index[0].
325
	 */
326
	 * 
326
	public static void addAttribute(StringBuffer stringBuffer, String[] attributeNames, String[] attributeValues, boolean close, boolean end) {
327
	 * @param parent The parent control
327
		for (int i = 0; i < attributeValues.length; i++) {
328
	 * @param skip Indicates whether a composite should be skipped
328
			if (attributeValues[i] == null) {
329
	 * @param desiredControl The desired control
329
				continue;
330
	 * @param index The current index calculated thus far (stored in index[0].  The type of this
330
			}
331
	 * parameter is an int array because its value needs to be preserved between recursive calls.
331
			stringBuffer.append(MacroConstants.SINGLE_SPACE);
332
	 * 
332
			stringBuffer.append(attributeNames[i]);
333
	 * @return true if the index was found; false otherwise.
333
			stringBuffer.append(MacroConstants.EQUAL_SIGN);
334
	 */
334
			stringBuffer.append(MacroConstants.DOUBLE_QUOTE);
335
	private static boolean computeControlIndex(Composite parent, Composite skip, Control desiredControl, int[] index, Vector indices)
335
			stringBuffer.append(XMLUtil.useXMLSymbols(attributeValues[i]));
336
	{
336
			stringBuffer.append(MacroConstants.DOUBLE_QUOTE);
337
		return recursiveSearch(parent, skip, desiredControl, null, null, index, new Vector(), indices) != null;
337
		}
338
	}
338
339
339
		stringBuffer.append(close
340
	
340
			? MacroConstants.FORWARD_SLASH
341
	
341
			: MacroConstants.EMPTY_STRING);
342
	public static Control recursiveSearch(Composite parent, Composite skip, Control desiredControl, WidgetIdentifier id, String widgetClassName, int[] index, Vector matches, Vector indices)
342
		stringBuffer.append(end
343
	{
343
			? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR
344
		boolean searchForControl = id == null;
344
			: MacroConstants.EMPTY_STRING);
345
		Control[] children = parent.getChildren();		
345
	}
346
		boolean[] checkTypeAndEquality;
346
347
		Control searchResult;
347
	public static void addIndent(StringBuffer stringBuffer, int indent) {
348
		boolean isTabFolder, isCTabFolder;
348
		for (int i = 0; i < indent; i++) {
349
		
349
			stringBuffer.append("\t");
350
		for (int i = 0; i < children.length; i++)
350
		}
351
		{
351
	}
352
			Control child = children[i];			
352
353
			
353
	public static boolean isIgnorableEvent(Event e) {
354
			if (!child.isVisible())
354
		Shell shell = e.display.getActiveShell();
355
			{
355
		if (shell != null) {
356
				/* If the control is of the same type, then we'll need to increment the index */
356
			Boolean ivalue = (Boolean) shell.getData(MacroManager.IGNORE);
357
				if ((widgetClassName != null && child.getClass().getName().equals(widgetClassName)) || (desiredControl != null && desiredControl.getClass().getName().equals(child.getClass().getName())))
357
			if (ivalue != null && ivalue.equals(Boolean.TRUE))
358
					index[0]++;
358
				return true;
359
				
359
		}
360
				continue;
360
		return false;
361
			}
361
	}
362
362
363
			checkTypeAndEquality = searchForControl ? checkTypeAndEqual(desiredControl, child, index) : checkTypeAndId (child, id, widgetClassName, index);
363
	public static Control getFirstChild(IWorkbenchPart part) {
364
			if (checkTypeAndEquality[0])
364
		Composite partControl = getWorkbenchPartControl(part);
365
			{
365
		return partControl.getChildren()[0];
366
				if (checkTypeAndEquality[1])
366
	}
367
				{
367
368
					addMatch (matches, indices, child, index[0]);
368
	/**
369
				}
369
	 * We have to use internal APIs here to get the controls of a part
370
				
370
	 */
371
				/* Defect 111371 -- We need to step through the items of a tab */		
371
	public static Composite getWorkbenchPartControl(IWorkbenchPart part) {
372
				isTabFolder = child instanceof TabFolder;
372
		IWorkbenchPartTestable testable = (IWorkbenchPartTestable) part.getSite().getAdapter(IWorkbenchPartTestable.class);
373
				isCTabFolder = child instanceof CTabFolder;
373
		return testable.getControl().getParent();
374
				if (isTabFolder || isCTabFolder)
374
	}
375
				{
375
376
					Object[] tabItems = isTabFolder ? (Object[])((TabFolder)child).getItems() : ((CTabFolder)child).getItems();
376
	/**
377
					if (tabItems != null)
377
	 * If str.length() is greater than bound, then the first bound letters of str is returned followed by "..."; otherwise str is returned.
378
					{
378
	 * 
379
						for (int j = 0; j < tabItems.length; j++)
379
	 * @param str
380
						{
380
	 *            The string to bound
381
							Control tabItemControl = isTabFolder ? ((TabItem)tabItems[j]).getControl() : ((CTabItem)tabItems[j]).getControl();
381
	 * @param bound
382
							
382
	 *            The bound
383
							if (tabItemControl == null)
383
	 * @return A bounded version of str
384
								continue;
384
	 */
385
							
385
	public static String boundSize(String str, int bound) {
386
							checkTypeAndEquality = searchForControl ? checkTypeAndEqual (tabItemControl, desiredControl, index) : checkTypeAndId (tabItemControl, id, widgetClassName, index);
386
		if (str == null || str.length() <= bound)
387
							if (checkTypeAndEquality[0] && checkTypeAndEquality[1])
387
			return str;
388
							{
388
389
								addMatch (matches, indices, tabItemControl, index[0]);
389
		return str.substring(0,
390
							}
390
			bound) + "...";
391
							if ((searchResult = recursiveSearch(tabItemControl, skip, desiredControl, id, widgetClassName, index, matches, indices)) != null)
391
	}
392
							{
392
393
								addMatch (matches, indices, searchResult, index[0]);								
393
	/**
394
							}				
394
	 * "Cleans" up the descriptive fields. For example, it removes the '&' sign that is usually included as part of button labels.
395
						}
395
	 * 
396
					}
396
	 * @param descriptiveField
397
				}
397
	 *            The descriptive field
398
398
	 * @return A "cleaned" up version of the descriptive field.
399
			}
399
	 */
400
			
400
	public static String normalizeDescriptiveField(String descriptiveField) {
401
			if ((searchResult = recursiveSearch (child, skip, desiredControl, id, widgetClassName, index, matches, indices)) != null)
401
		if (descriptiveField == null || descriptiveField.length() <= 0)
402
			{
402
			return descriptiveField;
403
				addMatch (matches, indices, searchResult, index[0]);
403
404
			}
404
		/*
405
		}
405
		 * This array holds character array that are of length two. The first item is the unwanted character and the second item is the replacement
406
		
406
		 * character.
407
		if (matches.size() > 0)
407
		 */
408
			return (Control)matches.get(0);
408
		final char[][] UNWANTED_CHARACTERS =
409
		
409
			new char[][] {new char[] {'&', 0}, new char[] {'\t', ' '}, new char[] {'\n', ' '}, new char[] {'\r', ' '}};
410
		return null;		
410
		String cleanDescription = "";
411
	}
411
		char currentCharacter;
412
	
412
		boolean isUnwantedChar;
413
	private static void addMatch (Vector container, Vector indices, Object item, int index)
413
		for (int i = 0, descriptionLength = descriptiveField.length(); i < descriptionLength; i++) {
414
	{
414
			currentCharacter = descriptiveField.charAt(i);
415
		if (!container.contains(item))
415
			isUnwantedChar = false;
416
		{
416
417
			container.add(item);
417
			for (int j = 0; j < UNWANTED_CHARACTERS.length; j++) {
418
			indices.add(new Integer(index));
418
				if (currentCharacter == UNWANTED_CHARACTERS[j][0]) {
419
		}
419
					if (UNWANTED_CHARACTERS[j][1] > 0)
420
	}
420
						cleanDescription += UNWANTED_CHARACTERS[j][1];
421
	
421
422
	private static Control recursiveSearch(Control currentSearchPoint, Composite skip, Control desiredControl, WidgetIdentifier desiredId, String desiredWidgetClassName, int[] index, Vector matches, Vector indices) 
422
					isUnwantedChar = true;
423
	{
423
					break;
424
		Control searchResult = null;
424
				}
425
		if (currentSearchPoint instanceof Composite && !(skip != null && currentSearchPoint.equals(skip)) && currentSearchPoint.isVisible())
425
			}
426
		{
426
427
			searchResult = recursiveSearch((Composite) currentSearchPoint, skip, desiredControl, desiredId, desiredWidgetClassName, index, matches, indices);
427
			if (!isUnwantedChar)
428
		}
428
				cleanDescription += currentCharacter;
429
				
429
		}
430
		return searchResult;
430
431
	}
431
		return cleanDescription;
432
	
432
	}
433
	
433
434
	/**
434
	public static void closeWelcomePage() {
435
	 * A helper method used to indicate whether expected is of the same type as actual.  The 
435
		IIntroManager introManager = GuiPlugin.getDefault().getWorkbench().getIntroManager();
436
	 * return value also indicates if expected == actual.
436
		IIntroPart introPart = introManager.getIntro();
437
	 * 
437
		if (introPart != null)
438
	 * @param expected The expected control
438
			introManager.closeIntro(introPart);
439
	 * @param actual The actual control that 'expected' is checked against
439
	}
440
	 * @param counter A counter that is used for indexing.
440
441
	 * 
441
	public static void maximizeWorkbench() {
442
	 * @return This method has the side affect of incrementing counter if the class types 
442
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
443
	 * of the two controls are the same.  The return value indicates type and whether expected == actual.
443
		Shell workbenchShell = workbench.getActiveWorkbenchWindow().getShell();
444
	 */
444
		Rectangle clientArea = workbench.getDisplay().getClientArea();
445
	private static boolean[] checkTypeAndEqual (Control expected, Control actual, int[] counter)
445
		workbenchShell.setLocation(0,
446
	{
446
			0);
447
		boolean[] typeAndEqualCheck = new boolean[2];
447
		workbenchShell.setSize(new Point(clientArea.width, clientArea.height));
448
		if (expected.getClass().equals(actual.getClass()))
448
		workbenchShell.redraw();
449
		{
449
	}
450
			typeAndEqualCheck[0] = true;
450
451
			
451
	public static void clearWorkbenchPartListeners() {
452
			// same type - increment counter
452
		workbenchPartListeners.clear();
453
			counter[0]++;
453
	}
454
			if (expected.equals(actual))
454
455
			{
455
	public static IMacroObjectIdentifier getCustomEventIdentifier(Event event) {
456
				// bingo
456
		if (event.type == EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) {
457
				typeAndEqualCheck[1] = true;
457
			IWorkbenchPart part = (IWorkbenchPart) event.data;
458
			}
458
			String partId = part.getSite().getId();
459
		}
459
460
		
460
			/* The path to the context */
461
		return typeAndEqualCheck;
461
			IPath contextId = null;
462
	}
462
			IPath partIdPath = null;
463
	
463
			if (part instanceof IViewPart) {
464
	
464
				contextId = new Path(MacroConstants.VIEW_VALUE);
465
	public static boolean[] checkTypeAndId (Control presentControl, WidgetIdentifier desiredId, String desiredWidgetClassName, int[] counter)
465
				partIdPath = new Path(partId);
466
	{
466
			}
467
		boolean[] checkTypeAndEqualId = new boolean[2];
467
			else if (part instanceof IEditorPart) {
468
		
468
				contextId = new Path(MacroConstants.EDITOR_VALUE);
469
		if (desiredWidgetClassName == null || presentControl.getClass().getName().equals(desiredWidgetClassName))
469
				partIdPath = new Path(partId).append(((IEditorPart) part).getEditorInput().getName());
470
		{
470
			}
471
			// same type - increment counter
471
472
			if (!presentControl.isVisible())
472
			if (contextId != null && partId != null) {
473
				return checkTypeAndEqualId;
473
				return new MacroObjectIdentifier(contextId.toString(), new PrimitiveUIObjectIdentifier(partIdPath.toString(), null));
474
			
474
			}
475
			checkTypeAndEqualId[0] = true;
475
		}
476
			counter[0]++;
476
		return null;
477
			if (MacroObjectLocator.foundWidget(presentControl, desiredId.getResolverId(), desiredId.getObjectId().toString()) || computeDefaultControlId(presentControl, counter[0]).equals(desiredId.getObjectId().toString()))
477
	}
478
			{
478
479
				checkTypeAndEqualId[1] = true;
479
	/**
480
			}			
480
	 * This method is provided to close any nested shells that a test case may have activated.
481
		}
481
	 */
482
		
482
	public static void closeSecondaryShells(final Display display) {
483
		return checkTypeAndEqualId;
483
		display.syncExec(new Runnable() {
484
	}
484
485
	
485
			public void run() {
486
	
486
				Shell[] shells = display.getShells();
487
	private static IWidgetId computeDefaultControlId(Control control, int controlIndex)
487
				for (int i = 0; i < shells.length; i++) {
488
	{
488
					if (!shells[i].isDisposed() && shells[i].getData(GlobalConstants.OPENED_SHELL_INDICATOR) == null)
489
		PrimitiveWidgetId primitiveWidgetId = new PrimitiveWidgetId();
489
						shells[i].close();
490
		primitiveWidgetId.setId(control.getClass().getName() + "#" + controlIndex);
490
				}
491
		return primitiveWidgetId;
491
			}
492
	}
492
		});
493
493
	}
494
494
495
	public static boolean isInputControl(Control control)
495
	public static void processDisplayEvents(Display display) {
496
	{
496
		for (int i = 0;; i++) {
497
		return true;
497
			if (!display.readAndDispatch())
498
	}
498
				break;
499
499
		}
500
	/**
500
	}
501
	 * @param menuItem
501
502
	 * @return
502
	public static XMLDefaultHandler createXMLDocument(InputStream is) throws CoreException, SAXException, IOException {
503
	 */
503
		XMLDefaultHandler handler = null;
504
	private static boolean onMenubar(MenuItem menuItem)
504
		try {
505
	{
505
			SAXParser parser = getParser();
506
		Menu parent = menuItem.getParent();
506
			handler = new XMLDefaultHandler();
507
		MenuItem parentItem = parent.getParentItem();
507
			parser.parse(is,
508
508
				handler);
509
		if (parentItem != null)
509
		}
510
		{
510
		finally {
511
			return onMenubar(parentItem);
511
			try {
512
		}
512
				is.close();
513
513
			}
514
		Shell theShell = parent.getShell();
514
			catch (IOException e) {
515
		return parent == theShell.getMenuBar();
515
			}
516
	}
516
		}
517
517
518
	private static boolean onToolbar(ToolItem toolItem)
518
		return handler;
519
	{
519
	}
520
		ToolBar toolBar = toolItem.getParent();
520
521
		Shell shell = toolBar.getShell();
521
	private static SAXParser getParser() throws CoreException {
522
		Object data = shell.getData();
522
		if (parser == null) {
523
		if (data instanceof ApplicationWindow)
523
			try {
524
		{
524
				return SAXParserFactory.newInstance().newSAXParser();
525
			ApplicationWindow window = (ApplicationWindow) data;
525
			}
526
			ToolBarManager mng = window.getToolBarManager();
526
			catch (ParserConfigurationException e) {
527
			if (mng != null)
527
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING,
528
			{
528
					e.getLocalizedMessage()),
529
				if (mng.getControl() != null && mng.getControl() == toolBar)
529
					0,
530
					return true;
530
					e);
531
			}
531
			}
532
			CoolBarManager cmng = window.getCoolBarManager();
532
			catch (SAXException e) {
533
			if (cmng != null)
533
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING,
534
			{
534
					e.getLocalizedMessage()),
535
				CoolBar cbar = cmng.getControl();
535
					0,
536
				Composite parent = toolBar.getParent();
536
					e);
537
				while (parent != null)
537
			}
538
				{
538
		}
539
					if (parent == cbar)
539
		return parser;
540
						return true;
540
	}
541
					parent = parent.getParent();
541
542
				}
542
	public static String removeChar(String input, char toRemove) {
543
			}
543
		StringBuffer buf = new StringBuffer(input.length());
544
		}
544
545
		return false;
545
		int last = 0;
546
	}
546
		for (int pos = input.indexOf(toRemove); pos != -1; pos = input.indexOf(toRemove,
547
	
547
			last)) {
548
	private static IViewPart onWorkbenchPartToolbar(MenuItem menuItem)
548
			buf.append(input.substring(last,
549
	{
549
				pos));
550
		IWorkbenchPage[] pages = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getPages();
550
			last = pos + 1;
551
		
551
		}
552
		/* For evey page */
552
553
		for (int i = 0; i < pages.length; i++)
553
		buf.append(input.substring(last,
554
		{
554
			input.length()));
555
			IViewReference[] viewReferences = pages[i].getViewReferences();
555
556
			
556
		return buf.toString();
557
			/* For evey opened view */
557
	}
558
			for (int j = 0; j < viewReferences.length; j++)
558
559
			{
559
	/**
560
				IViewPart viewPart = viewReferences[j].getView(false);
560
	 * @param menuItem
561
				if (viewPart == null)
561
	 * @return
562
					continue;
562
	 */
563
				
563
	public static boolean onMenubar(MenuItem menuItem) {
564
				IMenuManager menuManager = viewPart.getViewSite().getActionBars().getMenuManager();
564
		Menu parent = menuItem.getParent();
565
				if (menuManager != null && menuManager instanceof MenuManager && searchForMenuItem(((MenuManager)menuManager).getMenu(), menuItem))
565
		MenuItem parentItem = parent.getParentItem();
566
					return viewPart;
566
567
			}
567
		if (parentItem != null) {
568
		}
568
			return onMenubar(parentItem);
569
		
569
		}
570
		return null;
570
571
	}
571
		Shell theShell = parent.getShell();
572
572
		return parent == theShell.getMenuBar();
573
	private static boolean searchForMenuItem(Menu menu, MenuItem menuItem)
573
	}
574
	{
574
575
		if (menu == null)
575
	public static ContributionManager onToolbar(ToolItem toolItem) {
576
			return false;
576
		ToolBar toolBar = toolItem.getParent();
577
		
577
		Shell shell = toolBar.getShell();
578
		MenuItem[] items = menu.getItems();
578
		Object data = shell.getData();
579
		for (int i = 0; i < items.length; i++)
579
		if (data instanceof ApplicationWindow) {
580
		{
580
			ApplicationWindow window = (ApplicationWindow) data;
581
			if (items[i] == menuItem)
581
			ToolBarManager mng = window.getToolBarManager();
582
				return true;
582
			if (mng != null) {
583
			Menu cascadeMenu = items[i].getMenu();
583
				if (mng.getControl() != null && mng.getControl() == toolBar)
584
			if (cascadeMenu != null && searchForMenuItem (cascadeMenu, menuItem))
584
					return mng;
585
				return true;
585
			}
586
		}
586
			CoolBarManager cmng = window.getCoolBarManager();
587
		
587
			if (cmng != null) {
588
		return false;
588
				CoolBar cbar = cmng.getControl();
589
	}
589
				Composite parent = toolBar.getParent();
590
590
				while (parent != null) {
591
591
					if (parent == cbar)
592
	/**
592
						return cmng;
593
	 * @param toolItem
593
					parent = parent.getParent();
594
	 * @return
594
				}
595
	 */
595
			}
596
	private static String getDisplayName(ToolItem toolItem)
596
		}
597
	{
597
		return null;
598
		String name = toolItem.getText();
598
	}
599
599
600
		if (name != null && !name.equals(MacroConstants.EMPTY_STRING))
600
	public static IViewPart onWorkbenchPartToolbar(MenuItem menuItem) {
601
		{
601
		IWorkbenchPage[] pages = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getPages();
602
			return name;
602
603
		}
603
		/* For evey page */
604
604
		for (int i = 0; i < pages.length; i++) {
605
		name = toolItem.getToolTipText();
605
			IViewReference[] viewReferences = pages[i].getViewReferences();
606
606
607
		if (name != null)
607
			/* For evey opened view */
608
		{
608
			for (int j = 0; j < viewReferences.length; j++) {
609
			return name;
609
				IViewPart viewPart = viewReferences[j].getView(false);
610
		}
610
				if (viewPart == null)
611
611
					continue;
612
		return "unknown"; //$NON-NLS-1$
612
613
	}
613
				IMenuManager menuManager = viewPart.getViewSite().getActionBars().getMenuManager();
614
614
				if (menuManager != null && menuManager instanceof MenuManager && searchForMenuItem(((MenuManager) menuManager).getMenu(),
615
	/**
615
					menuItem))
616
	 * Returns an identifier for the given MenuItem, based on its user-readable
616
					return viewPart;
617
	 * strings
617
			}
618
	 * 
618
		}
619
	 * @param menuItem
619
620
	 * @return
620
		return null;
621
	 */
621
	}
622
	private static String getDisplayName(MenuItem menuItem)
622
623
	{
623
	private static boolean searchForMenuItem(Menu menu, MenuItem menuItem) {
624
		if (menuItem.getParent() == null || menuItem.getParent().getParentItem() == null)
624
		if (menu == null)
625
		{
625
			return false;
626
			return removeChar(menuItem.getText(), '&');
626
627
		}
627
		MenuItem[] items = menu.getItems();
628
628
		for (int i = 0; i < items.length; i++) {
629
		return getDisplayName(menuItem.getParent()) + "/" //$NON-NLS-1$
629
			if (items[i] == menuItem)
630
				+ removeChar(menuItem.getText(), '&');
630
				return true;
631
	}
631
			Menu cascadeMenu = items[i].getMenu();
632
632
			if (cascadeMenu != null && searchForMenuItem(cascadeMenu,
633
	/**
633
				menuItem))
634
	 * Returns an identifier for the given Menu, based on its user-readable
634
				return true;
635
	 * strings
635
		}
636
	 * 
636
637
	 * @param menu
637
		return false;
638
	 * @return
638
	}
639
	 */
639
	
640
	private static String getDisplayName(Menu menu)
640
	/**
641
	{
641
	 * @param wd
642
642
	 * @param control
643
		MenuItem parentItem = menu.getParentItem();
643
	 * @return
644
644
	 */
645
		if (parentItem == null)
645
	public static boolean onWizardDialog(WizardDialog wd, Button control) {
646
		{
646
		// see if we have a button on the wizard page or on the wizard dialog (i.e. wizard)
647
			return MacroConstants.EMPTY_STRING;
647
		IWizardPage page = wd.getCurrentPage();
648
		}
648
		Shell shell = control.getShell();
649
649
		Control pageControl = page.getControl();
650
		return getDisplayName(parentItem);
650
		IUIObjectIdentifier relativePath = NonTrivialUIObjectResolverDelegate.computeRelativePath(
651
	}
651
			(Composite) pageControl,
652
652
			null,
653
653
			control);
654
	/**
654
		if (relativePath != null) {
655
	 * Defect #: 112668 This method is invoked to retrieve the id of a menu item.  
655
			return false;
656
	 * Here's the policy that it employs:
656
		}
657
	 * <ol>
657
		// check for wizard buttons
658
	 * 	<li> Use the contributed widget resolvers </li>
658
		if (control instanceof Button) {
659
	 * 	<li> If failed, default to what was being used before </li>
659
			relativePath = NonTrivialUIObjectResolverDelegate.computeRelativePath(
660
	 * </ol>
660
				shell,
661
	 * 
661
				(Composite) pageControl,
662
	 * @param item The menu item
662
				control);
663
	 * @return The id of the passed item.
663
			return true;
664
	 */
664
		}
665
	public static IWidgetId determineItemId (Item item)
665
		return false;
666
	{
666
667
		IWidgetId menuItemIdObj = MacroManager.getInstance().resolveWidget(item, null, newCounter());
667
	}
668
		
668
	
669
		/* Give a chance for contributors to resolve the menu item */
669
	/**
670
		if (menuItemIdObj != null)
670
	 * Used to located the editor part with the passed id.
671
			return menuItemIdObj;
671
	 * 
672
		
672
	 * @param shell
673
		if (item instanceof ToolItem)
673
	 *            The current shell
674
		{
674
	 * @param id
675
			return getActionId((ToolItem)item);
675
	 *            The id of the editor part
676
		}
676
	 * @param line
677
		else if (item instanceof MenuItem)
677
	 *            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
678
		{
678
	 *            used)
679
			return getActionId((MenuItem)item);
679
	 * @param input
680
		}
680
	 *            If not null, then it attempts to match the input of the identified editor with the input that is passed it.
681
		else if (item instanceof IContributionItem)
681
	 * 
682
		{
682
	 * @return The editor part with the passed 'id'
683
			return getActionId((IContributionItem)item);
683
	 * 
684
		}
684
	 * @throws CoreException
685
		return null;
685
	 *             If the editor part cannot be located.
686
	}
686
	 */
687
687
	public static IEditorPart locateEditor(Shell shell, String id, String input) throws CoreException {
688
	
688
		Object data = shell.getData();
689
	/**
689
		IEditorPart editor = null;
690
	 * Walks through all parent menus of the menuItem and returns an index of format
690
691
	 * &lt;num&gt;|&lt;num&gt;|&lt;num&gt;|...  For example assuming menuItem is
691
		try {
692
	 * placed as follows:
692
			if (data instanceof IWorkbenchWindow) {
693
	 * 
693
				IWorkbenchWindow window = (IWorkbenchWindow) data;
694
	 * 		item 1
694
				IWorkbenchPage page = window.getActivePage();
695
	 *       |_item 2
695
696
	 *       |    |_item 4
696
				if (page != null) {
697
	 *       |_item 3
697
					IEditorReference[] erefs = page.getEditorReferences();
698
	 *            |_menuItem
698
699
	 *            
699
					for (int i = 0; i < erefs.length; i++) {
700
	 * then its respective index will be 1|2|1
700
						IEditorReference eref = erefs[i];
701
	 * 
701
						if (eref.getId().equals(id)) {
702
	 * @param menuItem The menu item whose index will be determined
702
							// check the input
703
	 * @return The index of the menu item as described above.
703
							IEditorPart part = eref.getEditor(true);
704
	 */
704
							if (input == null) {
705
	public static String findMenuItemIndex(MenuItem menuItem, String menuInx)
705
								editor = part;
706
	{
706
								break;
707
		if (menuItem == null)
707
							}
708
			return menuInx;
708
							else if (part.getEditorInput().getName().equals(input)) {
709
		
709
								editor = part;
710
		if (menuInx.length() > 0)
710
								break;
711
			menuInx = "|" + menuInx;
711
							}
712
		menuInx = menuItem.getParent().indexOf(menuItem) + menuInx;
712
						}
713
		return findMenuItemIndex(menuItem.getParent().getParentItem(), menuInx);
713
					}
714
	}
714
				}
715
715
			}
716
716
		}
717
	/*
717
		catch (Throwable t) {
718
	 * (non-Javadoc)
718
719
	 * 
719
		}
720
	 * @see org.eclipse.instrumentation.IDataProvider#getDefaultValue(org.eclipse.core.runtime.IPath)
720
		if (editor != null) {
721
	 */
721
			editor.getSite().getPage().activate(editor);
722
	public Object getDefaultValue(IPath node)
722
			return editor;
723
	{
723
		}
724
		return null;
724
725
	}
725
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR,
726
726
			id));
727
	private MenuItem getMenuItem(Menu menu, IPath menuPath)
727
		return null;
728
	{
728
	}
729
		if (menuPath.isEmpty())
729
	
730
		{
730
	/**
731
			return null;
731
	 * Used to located the view part with the passed id.
732
		}
732
	 * 
733
733
	 * @param shell
734
		String toFind = menuPath.segment(0);
734
	 *            The current shell
735
		MenuItem[] items = menu.getItems();
735
	 * @param id
736
736
	 *            The id of the view part
737
		for (int idx = 0; idx < items.length; idx++)
737
	 * @param line
738
		{
738
	 *            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
739
			MenuItem item = items[idx];
739
	 *            used)
740
740
	 * 
741
			String itemName = removeChar(item.getText(), '&');
741
	 * @return The view part with the passed 'id'
742
742
	 * 
743
			if (itemName.equals(toFind))
743
	 * @throws CoreException
744
			{
744
	 *             If the view part cannot be located.
745
				return getMenuItem(item, menuPath.removeFirstSegments(1));
745
	 */
746
			}
746
	public static IViewPart locateView(Shell shell, String id) throws CoreException {
747
		}
747
		try {
748
748
			Object data = shell.getData();
749
		return null;
749
750
	}
750
			if (data instanceof IWorkbenchWindow) {
751
751
				IWorkbenchWindow window = (IWorkbenchWindow) data;
752
	private MenuItem getMenuItem(MenuItem menu, IPath menuPath)
752
				IWorkbenchPage page = window.getActivePage();
753
	{
753
				if (page != null) {
754
		if (menuPath.isEmpty())
754
					IViewPart view = page.findView(id);
755
		{
755
756
			return menu;
756
					if (view == null) {
757
		}
757
						try {
758
758
							view = page.showView(id);
759
		Menu subMenu = menu.getMenu();
759
760
		if (subMenu == null)
760
						}
761
		{
761
						catch (PartInitException pie) {
762
			return null;
762
							/* Do a thorough search */
763
		}
763
							IWorkbenchWindow[] windows = GuiPlugin.getDefault().getWorkbench().getWorkbenchWindows();
764
764
765
		return getMenuItem(subMenu, menuPath);
765
							/* For every workbench window */
766
766
							for (int i = 0; i < windows.length && view == null; i++) {
767
	}
767
								/* For every page of a workbench window */
768
768
								IWorkbenchPage[] pages = windows[i].getPages();
769
	public static String removeChar(String input, char toRemove)
769
								for (int j = 0; j < pages.length && view == null; j++) {
770
	{
770
									view = pages[j].findView(id);
771
		StringBuffer buf = new StringBuffer(input.length());
771
772
772
								}
773
		int last = 0;
773
							}
774
		for (int pos = input.indexOf(toRemove); pos != -1; pos = input.indexOf(toRemove, last))
774
							// need to mke sure that even if it is found in another page, we show it.
775
		{
775
776
			buf.append(input.substring(last, pos));
776
						}
777
			last = pos + 1;
777
					}
778
		}
778
					// added for defcet 175320 in order to ensure the page is
779
779
					// given focus no matter where it is found
780
		buf.append(input.substring(last, input.length()));
780
					page.showView(id);
781
781
					return view;
782
		return buf.toString();
782
				}
783
	}
783
			}
784
784
		}
785
	public static String getAttribute(Node node, String name)
785
		catch (Throwable t) {
786
	{
786
			/* The next line will throw an exception */
787
		Node value = node.getAttributes().getNamedItem(name);
787
		}
788
		if (value != null)
788
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW,
789
			return value.getNodeValue();
789
			id));
790
		return null;
790
		return null;
791
	}
791
	}
792
792
793
		
794
	/**
795
	 * Adds an XML element to the string buffer passed in.
796
	 * 
797
	 * @param stringBuffer The string buffer that the element will be written to
798
	 * @param indent The number of indents that should be prefixed to the element written
799
	 * @param elementName The element name
800
	 * @param close Indicates whether this element should be closed or not.  If set, 
801
	 * a forward slash is added before theelement is ended.  
802
	 * @param end Indicates if the element should be ended with a closed angle bracket.  
803
	 * For example elements requring attributes are not ended.
804
	 */
805
	public static void addElement (StringBuffer stringBuffer, int indent, String elementName, boolean close, boolean end)
806
	{
807
		addIndent(stringBuffer, indent);
808
		stringBuffer.append(MacroConstants.OPEN_ANGLE_BRACKET);
809
		stringBuffer.append(close ? MacroConstants.FORWARD_SLASH : MacroConstants.EMPTY_STRING);		
810
		stringBuffer.append(elementName);
811
		stringBuffer.append(end ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR: MacroConstants.EMPTY_STRING);		
812
	}
813
814
	
815
	/**
816
	 * Adds XML attributes to the string buffer passed in.  Attributes with a null value will
817
	 * not be written.
818
	 * 
819
	 * Pre-condition:
820
	 * <ul>
821
	 * 	<li> attributes and attributeValues must be valid (i.e. non-null) </li>
822
	 * 	<li> attributes and attributeValues length must be the same </li>
823
	 * </ul>
824
	 *  
825
	 * @param stringBuffer The string buffer that the attributes will be written to
826
	 * @param attributeNames The attribute names
827
	 * @param attributeValues The attribute values
828
	 * @param close If set, a forward slash is added after the attributes.  
829
	 * @param end If set, a closed angle bracket is added after the attributes
830
	 */
831
	public static void addAttribute(StringBuffer stringBuffer, String[] attributeNames, String[] attributeValues, boolean close, boolean end)
832
	{
833
		for (int i = 0; i < attributeValues.length; i++)
834
		{
835
			if (attributeValues[i] == null)
836
			{
837
				continue;
838
			}
839
			stringBuffer.append(MacroConstants.SINGLE_SPACE);
840
			stringBuffer.append(attributeNames[i]);
841
			stringBuffer.append(MacroConstants.EQUAL_SIGN);
842
			stringBuffer.append(MacroConstants.DOUBLE_QUOTE);
843
			stringBuffer.append(XMLUtil.useXMLSymbols(attributeValues[i]));
844
			stringBuffer.append(MacroConstants.DOUBLE_QUOTE);
845
		}
846
		
847
		stringBuffer.append(close ? MacroConstants.FORWARD_SLASH : MacroConstants.EMPTY_STRING);
848
		stringBuffer.append(end ? MacroConstants.CLOSE_ANGLE_BRACKET + GlobalConstants.LINE_SEPARATOR : MacroConstants.EMPTY_STRING);
849
	}
850
	
851
	
852
	public static void addIndent (StringBuffer stringBuffer, int indent)
853
	{
854
		for (int i = 0; i < indent; i++)
855
		{
856
			stringBuffer.append("\t");
857
		}
858
	}
859
	
860
	
861
	public static boolean isIgnorableEvent(Event e)
862
	{
863
		Shell shell = e.display.getActiveShell();
864
		if (shell != null)
865
		{
866
			Boolean ivalue = (Boolean) shell.getData(MacroManager.IGNORE);
867
			if (ivalue != null && ivalue.equals(Boolean.TRUE))
868
				return true;
869
		}
870
		return false;
871
	}
872
873
	public static Control getFirstChild(IWorkbenchPart part)
874
	{
875
		Composite partControl = MacroObjectLocator.getWorkbenchPartControl(part);
876
		return partControl.getChildren()[0];
877
	}
878
879
	/**
880
	 * Given a context id, return the focus type.
881
	 * 
882
	 * @param contextId
883
	 *            The id of the context
884
	 * @return The type of the context (i.e. focus type). -1 is returned if the
885
	 *         focus type is not recognized.
886
	 */
887
	public static byte findFocusType(String contextId)
888
	{
889
		if (contextId.startsWith(MacroConstants.VIEW_VALUE + "/"))
890
			return VerificationMetaData.VIEW;
891
		else if (contextId.startsWith(MacroConstants.EDITOR_VALUE + "/"))
892
			return VerificationMetaData.EDITOR;
893
		else if (contextId.startsWith(MacroConstants.SHELL_VALUE + "/"))
894
			return VerificationMetaData.SHELL;
895
896
		return -1;
897
	}
898
899
	/**
900
	 * Return the class name containing the verification point that this meta
901
	 * data points to.
902
	 * 
903
	 * @param metaData
904
	 *            The verification point's meta data
905
	 * @return The class name. null is returned if it can't be determined
906
	 */
907
	public static String getClassName(VerificationMetaData metaData)
908
	{
909
		String className = metaData.getResource();
910
911
		if (className == null || className.length() <= 0)
912
			return null;
913
914
		int index = className.lastIndexOf('.');
915
		if (index != -1)
916
			return className.substring(index + 1, className.length());
917
		return className;
918
	}
919
920
	/**
921
	 * Find the method name corresponding the verification hook
922
	 * 
923
	 * @param metaData
924
	 * @return
925
	 */
926
	public static String findMethodName(VerificationMetaData metaData)
927
	{
928
		String methodName = metaData.getHook();
929
930
		if (methodName == null || methodName.length() <= 0)
931
			return null;
932
933
		int index = methodName.indexOf(':');
934
		if (index != -1)
935
			return methodName.substring(0, index);
936
937
		return methodName;
938
	}
939
940
	/**
941
	 * Find the parameter types of the verificaiton hook
942
	 * 
943
	 * @param metaData
944
	 * @return
945
	 */
946
	public static Class[] findParameterType(VerificationMetaData metaData)
947
	{
948
		Class param = null;
949
		if (metaData.getFocusType() == VerificationMetaData.EDITOR)
950
			param = IEditorPart.class;
951
		else if (metaData.getFocusType() == VerificationMetaData.VIEW)
952
			param = IViewPart.class;
953
		else if (metaData.getFocusType() == VerificationMetaData.SHELL)
954
			param = Shell.class;
955
956
		if (param != null)
957
			return new Class[] { param };
958
959
		return null;
960
	}
961
962
	
963
	/**
964
	 * If str.length() is greater than bound, then the first bound letters
965
	 * of str is returned followed by "..."; otherwise str is returned.
966
	 * 
967
	 * @param str The string to bound
968
	 * @param bound The bound
969
	 * @return A bounded version of str
970
	 */
971
	public static String boundSize(String str, int bound) 
972
	{					
973
		if (str == null || str.length() <= bound)
974
			return str;
975
		
976
		return str.substring(0, bound) + "...";
977
	}
978
	
979
980
	
981
	/**
982
	 * "Cleans" up the descriptive fields.  For example, it removes the '&' sign that is usually included
983
	 * as part of button labels.
984
	 * 
985
	 * @param descriptiveField The descriptive field
986
	 * @return A "cleaned" up version of the descriptive field.
987
	 */
988
	public static String normalizeDescriptiveField(String descriptiveField) 
989
	{
990
		if (descriptiveField == null || descriptiveField.length() <= 0)
991
			return descriptiveField;
992
		
993
		/* This array holds character array that are of length two.  The first item is the unwanted character and the second
994
		 * item is the replacement character. */
995
		final char[][] UNWANTED_CHARACTERS = new char[][] {new char[]{'&', 0}, new char[]{'\t', ' '}, new char[]{'\n', ' '}, new char[]{'\r', ' '}};
996
		String cleanDescription = "";
997
		char currentCharacter;
998
		boolean isUnwantedChar;
999
		for (int i = 0, descriptionLength = descriptiveField.length(); i < descriptionLength; i++)
1000
		{
1001
			currentCharacter = descriptiveField.charAt(i);
1002
			isUnwantedChar = false;
1003
			
1004
			for (int j = 0; j < UNWANTED_CHARACTERS.length; j++)
1005
			{
1006
				if (currentCharacter == UNWANTED_CHARACTERS[j][0])
1007
				{
1008
					if (UNWANTED_CHARACTERS[j][1] > 0)
1009
						cleanDescription += UNWANTED_CHARACTERS[j][1];
1010
					
1011
					isUnwantedChar = true;
1012
					break;
1013
				}
1014
			}
1015
			
1016
			if (!isUnwantedChar)
1017
				cleanDescription += currentCharacter;
1018
		}
1019
				
1020
		return cleanDescription;
1021
	}
1022
	
1023
	public static void closeWelcomePage()
1024
	{		
1025
		IIntroManager introManager = GuiPlugin.getDefault().getWorkbench().getIntroManager();
1026
		IIntroPart introPart = introManager.getIntro();
1027
		if (introPart != null)
1028
			introManager.closeIntro(introPart);
1029
	}
1030
1031
	
1032
	public static void maximizeWorkbench()
1033
	{
1034
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
1035
		Shell workbenchShell = workbench.getActiveWorkbenchWindow().getShell();
1036
		Rectangle clientArea = workbench.getDisplay().getClientArea();
1037
		workbenchShell.setLocation (0, 0);
1038
		workbenchShell.setSize(new Point(clientArea.width, clientArea.height));
1039
		workbenchShell.redraw();
1040
	}
1041
	public static void clearWorkbenchPartListeners()
1042
	{
1043
		workbenchPartListeners.clear();
1044
	}
1045
	
1046
	
1047
	private static class WorkbenchPartListener implements IPartListener
1048
	{
1049
1050
		public void partActivated(IWorkbenchPart part) 
1051
		{
1052
			/* Doesn't need to be implemented */
1053
		}
1054
1055
		public void partBroughtToTop(IWorkbenchPart part)
1056
		{
1057
			/* Doesn't need to be implemented */			
1058
		}
1059
1060
		/**
1061
		 * This method will generate a close workbench part command.  We can't determine for sure through
1062
		 * events reported by a display of when a workbench part is closed.  This part listener is
1063
		 * a work around that allows us to capture close events on workbench parts.
1064
		 * 
1065
		 * @param part The part is closed.
1066
		 */
1067
		public void partClosed(IWorkbenchPart part) 
1068
		{
1069
			Macro currentMacro = MacroManager.getInstance().getCurrentMacro(); 
1070
			Event event = new Event();
1071
			
1072
			event.type = Macro.WORKBENCH_PART_CLOSED;
1073
			event.data = part;
1074
			event.display = part.getSite().getShell().getDisplay();
1075
			if (currentMacro != null)
1076
			{
1077
				try 
1078
				{
1079
					currentMacro.addEvent(event);
1080
				} 
1081
				catch (Exception e) 
1082
				{
1083
					/* Ignore the error.  It doesn't generate the command */
1084
					e.printStackTrace();
1085
				}
1086
			}			
1087
		}
1088
1089
		public void partDeactivated(IWorkbenchPart part) 
1090
		{
1091
			/* Doesn't need to be implemented */
1092
		}
1093
1094
		public void partOpened(IWorkbenchPart part) 
1095
		{
1096
			/* Doesn't need to be implemented */			
1097
		}
1098
		
1099
	}
1100
1101
	public static WidgetIdentifier getCustomEventIdentifier(Event event) 
1102
	{
1103
		if (event.type == Macro.WORKBENCH_PART_CLOSED)
1104
		{
1105
			IWorkbenchPart part = (IWorkbenchPart)event.data;
1106
			String partId = part.getSite().getId();
1107
							
1108
			/* The path to the context */
1109
			IPath contextId = null;
1110
			IPath partIdPath = null;
1111
			if (part instanceof IViewPart)
1112
			{
1113
				contextId = new Path(MacroConstants.VIEW_VALUE);
1114
				partIdPath = new Path(partId);
1115
			}
1116
			else if (part instanceof IEditorPart)
1117
			{
1118
				contextId = new Path(MacroConstants.EDITOR_VALUE);
1119
				partIdPath = new Path(partId).append(((IEditorPart)part).getEditorInput().getName());
1120
			}
1121
			
1122
			if (contextId != null && partId != null)
1123
				return new WidgetIdentifier (contextId, partIdPath, null);			
1124
		}
1125
		return null;
1126
	}
1127
1128
	
1129
	/* Returns an identifier for the verification hook context */
1130
	public static WidgetIdentifier getVerificationContextIdentifier(Event event) 
1131
	{
1132
		/* See if the context is an editor or a view */
1133
		Control control = null;
1134
		if (event.widget instanceof Control)
1135
		{
1136
			control = (Control)event.widget;
1137
			WidgetIdentifier widgetId = getControlIdentifier(control);
1138
			if (widgetId != null)
1139
			{
1140
				String firstSegment = new Path(widgetId.getContextId().toString()).segment(0);
1141
				if (firstSegment.equals(MacroConstants.VIEW_VALUE) || firstSegment.equals(MacroConstants.EDITOR_VALUE))
1142
					return widgetId;
1143
			}
1144
		}
1145
		
1146
		/* It's not an editor or a view.  See if it's a shell */
1147
		Shell shellFound = null;
1148
		if (event.widget instanceof Shell)
1149
			shellFound = (Shell) event.widget;
1150
		else if (control != null)
1151
			shellFound = control.getShell();
1152
		
1153
		/* Make sure that the shell is not the workbench shell */
1154
		if (shellFound == null || GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell().equals(shellFound))
1155
			return null;
1156
		
1157
		IWidgetId shellPath = getShellId(shellFound, null);
1158
		if (shellPath.toString().length() <= 0)
1159
			return null;
1160
		
1161
		return new WidgetIdentifier (new Path(MacroConstants.SHELL_VALUE).append(shellPath.toString()), null, shellPath.getResolverId());
1162
	}
1163
	
1164
	
1165
	/**
1166
	 * This method is provided to close any nested shells that a test case may have
1167
	 * activated. 
1168
	 */
1169
	public static void closeSecondaryShells(final Display display)
1170
	{
1171
		display.syncExec(new Runnable(){
1172
			public void run() 
1173
			{				
1174
				Shell[] shells = display.getShells();
1175
				for (int i = 0; i < shells.length; i++)
1176
				{
1177
					if (!shells[i].isDisposed() && shells[i].getData(GlobalConstants.OPENED_SHELL_INDICATOR) == null)
1178
						shells[i].close();
1179
				}				
1180
			}
1181
		});
1182
	}
1183
	
1184
	public static void processDisplayEvents(Display display)
1185
	{
1186
		for (int i = 0;;i++)
1187
		{			
1188
			if (!display.readAndDispatch())
1189
				break;
1190
		}
1191
	}
1192
	
1193
	
1194
	public static XMLDefaultHandler createXMLDocument (InputStream is) throws CoreException, SAXException, IOException
1195
	{
1196
		XMLDefaultHandler handler = null;
1197
		try
1198
		{
1199
			SAXParser parser = getParser();
1200
			handler = new XMLDefaultHandler();
1201
			parser.parse(is, handler);
1202
		}
1203
		finally
1204
		{
1205
			try
1206
			{
1207
				is.close();
1208
			}
1209
			catch (IOException e)
1210
			{
1211
			}
1212
		}
1213
		
1214
		return handler;
1215
	}
1216
	
1217
	private static SAXParser getParser() throws CoreException
1218
	{
1219
		if (parser == null)
1220
		{
1221
			try
1222
			{
1223
				return SAXParserFactory.newInstance().newSAXParser();
1224
			}
1225
			catch (ParserConfigurationException e)
1226
			{
1227
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e);
1228
			}
1229
			catch (SAXException e)
1230
			{
1231
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e);
1232
			}
1233
		}
1234
		return parser;
1235
	}
1236
1237
	
1238
	private static PrimitiveWidgetId getActionId(IContributionItem contrib)
1239
	{
1240
		String id = null;
1241
		PrimitiveWidgetId widgetId = new PrimitiveWidgetId();
1242
		
1243
		if (contrib instanceof IPluginContribution)
1244
		{
1245
			id = ((IPluginContribution) contrib).getLocalId();
1246
		}
1247
		id = id == null ? contrib.getId() : id;	
1248
		if (id != null)
1249
		{
1250
			widgetId.setId("contribid/" + id); //$NON-NLS-1$
1251
		}
1252
		else
1253
		{
1254
			if (contrib instanceof ActionContributionItem)
1255
			{
1256
				ActionContributionItem actionItem = (ActionContributionItem) contrib;		
1257
				id = actionItem.getId();		
1258
				if (id != null)
1259
				{
1260
					widgetId.setId("actionid/" + id); //$NON-NLS-1$
1261
				}
1262
				else
1263
				{		
1264
					IAction action = actionItem.getAction();			
1265
					id = action.getActionDefinitionId();			
1266
					if (id != null)
1267
					{
1268
						widgetId.setId("defid/" + id); //$NON-NLS-1$
1269
					}
1270
					else
1271
					{
1272
						widgetId.setId("actionclass/" + action.getClass().getName()); //$NON-NLS-1$
1273
					}
1274
				}
1275
			}
1276
			else
1277
			{
1278
				widgetId.setId("contribclass/" + contrib.getClass().getName()); //$NON-NLS-1$				
1279
			}
1280
		}
1281
		
1282
		return widgetId;
1283
	}
1284
1285
1286
	/**
1287
	 * @param widget
1288
	 * @return
1289
	 */
1290
	public static IWidgetId getActionId(Widget widget)
1291
	{
1292
		Object data = widget.getData();
1293
		PrimitiveWidgetId widgetId = new PrimitiveWidgetId();
1294
		if (data != null && (data instanceof IContributionItem))
1295
		{
1296
			widgetId = getActionId((IContributionItem) data);
1297
			if (!widgetId.toString().equals(MacroConstants.EMPTY_STRING))
1298
			{
1299
				if (widget instanceof MenuItem)
1300
				{
1301
					String menuInx = findMenuItemIndex((MenuItem)widget, "");
1302
					widgetId.setId(widgetId.toString() + menuInx);
1303
				}
1304
			}
1305
		}
1306
		else
1307
		{
1308
			widgetId.setId("readablename/" + ((widget instanceof MenuItem) ? getDisplayName((MenuItem)widget) : getDisplayName((ToolItem)widget)));			//$NON-NLS-1$
1309
		}
1310
		
1311
		return widgetId; 
1312
	}
1313
}
793
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMine.java (-569 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.LinkedList;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
20
import org.eclipse.osgi.util.NLS;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
22
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
23
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
24
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
25
import org.w3c.dom.NamedNodeMap;
26
import org.w3c.dom.Node;
27
28
29
/**
30
 * A concrete implementation of IObjectMine.
31
 * 
32
 * @author Ali Mehregani
33
 */
34
public class ObjectMine implements IObjectMine
35
{
36
	/** The root node of the tree structure that contains the objects */
37
	private IUIObject root;
38
	
39
	/** Included object mines */
40
	private ArrayList includes;
41
	
42
	/** The test suite that owns this object mine */
43
	private ITestSuite owner;
44
		
45
	/** The output object mine */
46
	private IObjectMine outputObjectMine;
47
	
48
	/** The active object */
49
	private IUIObject activeObject;
50
51
	/** Keeps track of the maximum reference id in use.  This is used to generate a unique
52
	 * reference id when requested */
53
	private int maximumRefId;
54
55
	/** The xml handler used to parse the object mine */
56
	private XMLDefaultHandler defaultXMLHandler;
57
	
58
	
59
	public ObjectMine (ITestSuite testSuite, XMLDefaultHandler defaultXMLHandler)
60
	{
61
		owner = testSuite;
62
		root = new UIObject(null);
63
		includes = new ArrayList();
64
		this.defaultXMLHandler = defaultXMLHandler;
65
	}
66
	
67
	public void addInclude(IObjectMine objectMine)
68
	{		
69
		includes.add(objectMine);		
70
		if (outputObjectMine != null)
71
		{
72
			IObjectMine foundObjectMine = findIncludedObjectMine(outputObjectMine);
73
			outputObjectMine = foundObjectMine == null ? outputObjectMine : foundObjectMine;
74
		}
75
	}
76
77
	public IUIObject lookupUIObject(IUIObject parent, String referenceId)
78
	{	
79
		IUIObject uiObject = lookupIncludes(parent, referenceId);
80
		if (uiObject != null)
81
			return uiObject;
82
				
83
		uiObject = lookupUIObject(parent);		
84
		if (uiObject == null)
85
			return null;
86
87
		uiObject = uiObject.findChild(referenceId);				
88
		return uiObject;
89
	}
90
	
91
	
92
	
93
	private IUIObject lookupUIObject(IUIObject object, boolean requiresPresence) throws UIObjectNotFound
94
	{
95
		if (object == null)
96
		{
97
			return root;
98
		}
99
		
100
		LinkedList relationship = object.getHierarchicalRelation();
101
		IUIObject currentNode = root;
102
		for (int i = 0, height=relationship.size(); currentNode != null && i < height; i++)
103
		{
104
			currentNode = currentNode.findChild(((IUIObject)relationship.get(i)).getReferenceId());
105
		}
106
		
107
		if (currentNode == null && requiresPresence)
108
			throw new UIObjectNotFound(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, object.getReferenceId()));
109
		
110
		return currentNode;
111
	}
112
	
113
	
114
	public IUIObject lookupUIObject(IUIObject parent, String contextId, String objectId)
115
	{
116
		IUIObject uiObject = lookupIncludes(parent, contextId, objectId);
117
		if (uiObject != null)
118
			return uiObject;
119
		
120
		IUIObject parentNode = lookupUIObject(parent);
121
		if (parentNode == null)
122
			return null;
123
		
124
		IUIObject[] children = parentNode.getChildren();
125
		for (int i = 0; i < children.length; i++)
126
		{
127
			if (((contextId == null && children[i].getContextId() == null) || (contextId != null && contextId.equals(children[i].getContextId()))) &&
128
				objectId.equals(children[i].getObjectId()))
129
			{
130
				return children[i];
131
			}
132
			
133
		}
134
		return null;
135
	}
136
	
137
	public IUIObject[] getChildren()
138
	{
139
		return root.getChildren();
140
	}
141
	
142
	
143
	
144
	private IUIObject lookupUIObject (IUIObject parent)
145
	{
146
		try
147
		{
148
			return lookupUIObject(parent, false);
149
		} 
150
		catch (UIObjectNotFound e)
151
		{
152
			return null;
153
		}
154
	}
155
156
	
157
	/**
158
	 * Looks up the included object mine to determine if they have a corresponding object
159
	 * with the reference id passed in.
160
	 * 
161
	 * @param parent The parent of the object
162
	 * @param referenceId The reference id of the object
163
	 * 
164
	 * @return The object with the reference id passed in; null if none is found. 
165
	 * @throws UIObjectNotFound In case the parent can't be found.
166
	 */
167
	private IUIObject lookupIncludes(IUIObject parent, String referenceId) 
168
	{
169
		IUIObject[] uiObject = lookupIncludes (parent, referenceId, null, null);
170
		return uiObject != null && uiObject.length > 0 ? uiObject[0] : null;
171
	}
172
173
	
174
	/**
175
	 * Looks up the included object mine to determine if they have a corresponding object
176
	 * with the contextId id and object id passed in.
177
	 * 
178
	 * @param parent The parent of the object
179
	 * @param contextId The context id of the object
180
	 * @param objectId The id of the object
181
	 * 
182
	 * @return The object with the matching context and object id passed in; null if none is found. 
183
	 * @throws UIObjectNotFound In case the parent can't be found.
184
	 */
185
	private IUIObject lookupIncludes(IUIObject parent, String contextId, String objectId) 
186
	{
187
		IUIObject[] uiObject = lookupIncludes (parent, null, contextId, objectId);
188
		return uiObject != null && uiObject.length > 0 ? uiObject[0] : null;
189
	}
190
	
191
	
192
	/**
193
	 * Looks up the included object mines to find an object that has been requested.
194
	 * If reference id happens to be null, then context/object id are used.
195
	 * 
196
	 * @param parent The parent of the object
197
	 * @param referenceId The reference id of the object. 
198
	 * @param contextId The context id of the object
199
	 * @param objectId The id of the object
200
	 *  
201
	 * @return The objects to look for
202
	 */
203
	private IUIObject[] lookupIncludes(IUIObject parent, String referenceId, String contextId, String objectId)
204
	{
205
		boolean useReferenceId = referenceId != null;
206
		boolean useObjectId = objectId != null;
207
		
208
		IUIObject objectRequested = null;
209
		IUIObject[] children = null; 
210
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
211
		{
212
			IObjectMine objectMine = (IObjectMine)includes.get(i);
213
			if (useReferenceId)
214
			{
215
				objectRequested = objectMine.lookupUIObject(parent, referenceId);
216
			}
217
			else if (useObjectId)
218
			{
219
				objectRequested = objectMine.lookupUIObject(parent, contextId, objectId);
220
			}
221
		
222
			children = objectRequested == null ? children : new IUIObject[] {objectRequested};
223
			if (children != null)
224
			{
225
				return children;
226
			}
227
		}
228
		
229
		return null;
230
	}
231
	
232
	
233
	public IUIObject getRoot()
234
	{
235
		return root;
236
	}
237
238
	
239
	public IUIObject registerObject(IUIObject parent, Node objectNode) throws IDCollisionException, UIObjectNotFound, CoreException
240
	{
241
		NamedNodeMap attributes = objectNode.getAttributes();
242
		IUIObject uiObject = new UIObject(parent);
243
244
		IUIObject node = lookupUIObject(parent, true);		
245
		
246
		/* Set the attributes of the object */
247
		String referenceIdStr = getAttribute(attributes, MacroConstants.REFERENCE_ID_ATTRIBUTE);
248
		updateMaxReferenceId(referenceIdStr);
249
		
250
		Hashtable lineLevelDetail = null;
251
		if (defaultXMLHandler != null)
252
			lineLevelDetail = defaultXMLHandler.getLineTable();
253
		uiObject.setReferenceId(referenceIdStr);
254
		uiObject.setContextId(getAttribute(attributes, MacroConstants.CONTEXT_ID_ATTRIBUTE));
255
		uiObject.setObjectId(getAttribute(attributes, MacroConstants.ID_ATTRIBUTE));
256
		uiObject.setDescriptive(getAttribute(attributes, MacroConstants.DESCRIPTIVE_ATTRIBUTE));
257
		uiObject.setResolver(getAttribute(attributes, MacroConstants.RESOLVER_ATTRIBUTE));
258
		if (lineLevelDetail != null)
259
			uiObject.setData(((Integer[])lineLevelDetail.get(objectNode)));
260
		node.addChild(uiObject);
261
		
262
		return uiObject;
263
	}
264
	
265
	public IUIObject registerObject(IUIObject uiObject) throws IDCollisionException, UIObjectNotFound, CoreException
266
	{
267
		updateMaxReferenceId(uiObject.getReferenceId());
268
		
269
		IUIObject parentObject = uiObject.getParent();
270
		
271
		/* If the object that is about to be registered happens to be at the first level (i.e. 
272
		 * it is an infant), then it needs to be registered with the output destination of this object mine */
273
		if (parentObject == null && outputObjectMine != null)
274
		{
275
			outputObjectMine.registerObject(uiObject);
276
			includes.contains(outputObjectMine);
277
			return uiObject;
278
		}
279
		
280
		if (parentObject == null)
281
		{
282
			root.addChild(uiObject);
283
		}
284
		else
285
		{			
286
			parentObject.addChild(uiObject);	
287
		}
288
		
289
		
290
		return uiObject;
291
	}
292
293
	private void updateMaxReferenceId(String referenceIdStr)
294
	{
295
		try
296
		{
297
			int referenceId = Integer.parseInt(referenceIdStr);
298
			int maximumIncludedRefId = findMaximumIncludedRefId();
299
			maximumRefId = Math.max(Math.max(referenceId, maximumIncludedRefId), maximumRefId);
300
			
301
			if (referenceId == maximumRefId)
302
				maximumRefId++;
303
		}
304
		catch (NumberFormatException nfe)
305
		{
306
			/* Doesn't need to be handled */
307
		}
308
	}
309
	
310
	
311
	/**
312
	 * Walks through the included object mines of this object mine to determine the
313
	 * unique reference id.
314
	 * 
315
	 * @return A unique reference id that is global to all included object mines.
316
	 */
317
	private int findMaximumIncludedRefId()
318
	{
319
		int uniqueRefId = 0;
320
321
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
322
		{
323
			IObjectMine currentObjectMine = (IObjectMine)includes.get(i);
324
			try
325
			{
326
				uniqueRefId = Math.max(Integer.parseInt(currentObjectMine.getUniqueReferenceId()), uniqueRefId);
327
			}
328
			catch (NumberFormatException nfe)
329
			{
330
				/* Ignore the exception */
331
			}
332
		}		
333
		return uniqueRefId;
334
	}
335
336
	private String getAttribute(NamedNodeMap attributes, String attributeName)
337
	{
338
		Node attr = attributes.getNamedItem(attributeName);
339
		return attr == null ? null : attr.getNodeValue();
340
	}
341
342
	public void setOutputSource(IObjectMine objectMine)
343
	{
344
		outputObjectMine = objectMine == null ? null : findIncludedObjectMine(objectMine);
345
		if (outputObjectMine == null)
346
			outputObjectMine = objectMine;		
347
	}
348
349
350
	public IObjectMine getOutputSource()
351
	{
352
		return outputObjectMine;
353
	}
354
355
	
356
	private IObjectMine findIncludedObjectMine(IObjectMine objectMine)
357
	{
358
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
359
		{
360
			IObjectMine currentObjectMine = (IObjectMine)includes.get(i);
361
			if (currentObjectMine.equals(objectMine))
362
				return currentObjectMine;
363
		}
364
		
365
		return null;
366
	}
367
	
368
	public ITestSuite getOwner()
369
	{
370
		return owner;
371
	}
372
	
373
	
374
	public static class UIObjectNotFound extends Exception
375
	{
376
		static final long serialVersionUID = 4699726279267599112L;
377
		
378
		public UIObjectNotFound(String message)
379
		{
380
			super(message);
381
		}
382
	}
383
	
384
	
385
	public static class IDCollisionException extends Exception
386
	{
387
		static final long serialVersionUID = -6526030843455792891L;
388
		
389
		public IDCollisionException(String message)
390
		{
391
			super(message);
392
		}		
393
	}
394
395
396
	public String serializeToString()
397
	{
398
		StringBuffer objectMineSerialized = new StringBuffer();
399
		int indent = 0;
400
		
401
		/* <object-mine> */
402
		MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECT_MINE_ELEMENT, false, true);
403
				
404
		serializeHeader(objectMineSerialized, indent + 1, true);
405
		serializeObjects(objectMineSerialized, indent + 1, true);
406
		
407
		/* </object-mine> */
408
		MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECT_MINE_ELEMENT, true, true);
409
		
410
		return objectMineSerialized.toString();
411
	}
412
413
414
	private void serializeHeader(StringBuffer objectMineSerialized, int indent, boolean includeHeader)
415
	{
416
		/* Don't write anything if the header is empty */
417
		if (outputObjectMine == null && (includes == null || includes.size() <= 0))
418
			return;
419
		
420
		boolean outputElement = outputObjectMine != null;
421
		
422
		/* <header output="..."/>*/
423
		if (includeHeader)
424
		{
425
			MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.HEADER_ELEMENT, false, !outputElement);
426
			if (outputElement)
427
				MacroUtil.addAttribute(objectMineSerialized, new String[] {MacroConstants.OUTPUT_ATTRIBUTE}, new String[] {AutoGUIUtil.resolveTestSuitePath(outputObjectMine.getOwner())}, false, true);
428
		}
429
430
		/* Add the <include .../> elements */
431
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
432
		{
433
			IObjectMine currentInclude = (IObjectMine)includes.get(i);
434
			ITestSuite testSuite = currentInclude.getOwner();
435
			String path = AutoGUIUtil.resolveTestSuitePath(testSuite);
436
			
437
			if (path  != null)
438
			{
439
				MacroUtil.addElement(objectMineSerialized, indent + 1, MacroConstants.INCLUDE_ELEMENT, false, false);
440
				MacroUtil.addAttribute(objectMineSerialized, 
441
							new String[] {MacroConstants.PATH_ATTRIBUTE}, 
442
							new String[] {path}, 
443
							true, true);
444
			}
445
		}
446
		
447
		if (includeHeader)
448
		{
449
			MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.HEADER_ELEMENT, true, true);
450
		}
451
	}
452
453
	
454
	private void serializeObjects(StringBuffer objectMineSerialized, int indent, boolean includeHeader)
455
	{	
456
		IUIObject[] rootChildren = root.getChildren();
457
		if (rootChildren == null || rootChildren.length <= 0)
458
			return;
459
		
460
		/* Add the objects */
461
		if (includeHeader)
462
		{
463
			MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECTS_ELEMENT, false, true);
464
			addObject(objectMineSerialized, indent + 1, rootChildren);
465
			MacroUtil.addElement(objectMineSerialized, indent, MacroConstants.OBJECTS_ELEMENT, true, true);
466
			return;
467
		}
468
		
469
		addObject(objectMineSerialized, indent + 1, rootChildren);
470
	}
471
	
472
	/**
473
	 * @see org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine#serializeHeaderToString()
474
	 */
475
	public String serializeHeaderToString()
476
	{
477
		StringBuffer sb = new StringBuffer();
478
		serializeHeader(sb, 0, false);
479
		return sb.toString();
480
	}
481
482
	
483
	/**
484
	 * @see org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine#serializeObjetsToString()
485
	 */
486
	public String serializeObjetsToString()
487
	{
488
		StringBuffer sb = new StringBuffer();
489
		serializeObjects(sb, 0, false);
490
		return sb.toString();
491
	}
492
	
493
	private void addObject(StringBuffer objectMapSerialized, int indent, IUIObject[] rootChildren)
494
	{		
495
		if (rootChildren == null)
496
			return;
497
		
498
		for (int i = 0; i < rootChildren.length; i++)
499
		{
500
			IUIObject currentUIObject = rootChildren[i];			
501
			IUIObject[] children = rootChildren[i].getChildren();
502
			
503
			/* If the object is a shell without any children, then skip it */
504
			if (currentUIObject.getParent() == null && (children == null || children.length <= 0))
505
				continue;
506
			
507
			boolean hasChildren =  children!= null && children.length > 0;
508
			MacroUtil.addElement (objectMapSerialized, indent, MacroConstants.OBJECT_ELEMENT, false, false);
509
			MacroUtil.addAttribute(objectMapSerialized, 
510
					new String[] {MacroConstants.DESCRIPTIVE_ATTRIBUTE,
511
								  MacroConstants.REFERENCE_ID_ATTRIBUTE,
512
								  MacroConstants.CONTEXT_ID_ATTRIBUTE,
513
								  MacroConstants.RESOLVER_ATTRIBUTE,
514
								  MacroConstants.ID_ATTRIBUTE},
515
					new String[] {currentUIObject.getDescriptive(),
516
								  currentUIObject.getReferenceId(),
517
								  currentUIObject.getContextId(),
518
								  currentUIObject.getResolverId(),
519
								  currentUIObject.getObjectId()}
520
					, !hasChildren, true);
521
			if (hasChildren)
522
			{
523
				addObject(objectMapSerialized, indent + 1, rootChildren[i].getChildren());
524
				MacroUtil.addElement (objectMapSerialized, indent, MacroConstants.OBJECT_ELEMENT, true, true);
525
			}
526
		}
527
		
528
	}
529
530
531
	public IUIObject getActiveObject()
532
	{
533
		return activeObject;
534
	}
535
536
	public void setActiveObject(IUIObject activeObject)
537
	{
538
		this.activeObject = activeObject;
539
	}
540
541
	public String getUniqueReferenceId()
542
	{
543
		int maximumIncludedRefId = findMaximumIncludedRefId();
544
		maximumRefId = Math.max(maximumIncludedRefId, maximumRefId);
545
		
546
		/* Restart the reference id */
547
		if (maximumRefId >= Integer.MAX_VALUE - 10)
548
		{
549
			maximumRefId = 0;
550
		}
551
		return String.valueOf(maximumRefId);
552
	}
553
554
	public List getIncludes()
555
	{
556
		return includes;
557
	}
558
	
559
	public boolean equals(Object o)
560
	{
561
		return o instanceof IObjectMine ? getOwner().getId().equals(((IObjectMine)o).getOwner().getId()) : false;		
562
	}
563
564
	public void setOwner(ITestSuite testSuite)
565
	{
566
		this.owner = testSuite;		
567
	}
568
569
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/XMLDefaultHandler.java (-166 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2003, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.Hashtable;
14
import java.util.Stack;
15
16
import javax.xml.parsers.DocumentBuilderFactory;
17
import javax.xml.parsers.ParserConfigurationException;
18
19
import org.w3c.dom.Element;
20
import org.w3c.dom.Node;
21
import org.w3c.dom.Text;
22
import org.xml.sax.Attributes;
23
import org.xml.sax.Locator;
24
import org.xml.sax.helpers.DefaultHandler;
25
26
public class XMLDefaultHandler extends DefaultHandler
27
{
28
29
	private org.w3c.dom.Document fDocument;
30
31
	private Locator fLocator;
32
33
	private Hashtable fLineTable;
34
35
	private Element fRootElement;
36
37
	private Stack fElementStack = new Stack();
38
	
39
	/* Indicates whether a CDATA section is reached */
40
	private boolean cdataStarted;
41
42
	public XMLDefaultHandler()
43
	{
44
		fLineTable = new Hashtable();
45
	}
46
47
	public void startElement(String uri, String localName, String qName, Attributes attributes)
48
	{
49
		Element element = fDocument.createElement(qName);
50
		for (int i = 0; i < attributes.getLength(); i++)
51
		{
52
			element.setAttribute(attributes.getQName(i), attributes.getValue(i));
53
		}
54
55
		Integer lineNumber = new Integer(fLocator.getLineNumber());
56
		Integer[] range = new Integer[] { lineNumber, new Integer(-1) };
57
		fLineTable.put(element, range);
58
		if (fRootElement == null)
59
			fRootElement = element;
60
		else
61
			((Element) fElementStack.peek()).appendChild(element);
62
		fElementStack.push(element);
63
	}
64
65
	public void endElement(String uri, String localName, String qName)
66
	{
67
		Integer[] range = (Integer[]) fLineTable.get(fElementStack.pop());
68
		range[1] = new Integer(fLocator.getLineNumber());
69
	}
70
71
	/*
72
	 * (non-Javadoc)
73
	 * 
74
	 * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
75
	 */
76
	public void setDocumentLocator(Locator locator)
77
	{
78
		fLocator = locator;
79
	}
80
81
	/*
82
	 * (non-Javadoc)
83
	 * 
84
	 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
85
	 */
86
	public void startDocument()
87
	{
88
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
89
		try
90
		{
91
			fDocument = factory.newDocumentBuilder().newDocument();
92
		}
93
		catch (ParserConfigurationException e)
94
		{
95
		}
96
	}
97
98
	/*
99
	 * (non-Javadoc)
100
	 * 
101
	 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
102
	 */
103
	public void endDocument()
104
	{
105
		fDocument.appendChild(fRootElement);
106
	}
107
108
	/*
109
	 * (non-Javadoc)
110
	 * 
111
	 * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String,
112
	 *      java.lang.String)
113
	 */
114
	public void processingInstruction(String target, String data)
115
	{
116
		fDocument.appendChild(fDocument.createProcessingInstruction(target, data));
117
	}
118
119
	/*
120
	 * (non-Javadoc)
121
	 * 
122
	 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
123
	 */
124
	public void characters(char[] characters, int start, int length)
125
	{
126
		StringBuffer buff = new StringBuffer();
127
		for (int i = 0; i < length; i++)
128
		{
129
			buff.append(characters[start + i]);
130
		}
131
132
		String buffValue = buff.toString();	
133
		boolean isBufferJustWhiteSpace = buffValue.trim().equals("");
134
		boolean isBufferEmpty = buffValue.length() <= 0;
135
		
136
		if ((cdataStarted && isBufferEmpty) || (!cdataStarted && isBufferJustWhiteSpace))
137
		{
138
			cdataStarted = false;
139
			return;
140
		}
141
				
142
		Text text = fDocument.createTextNode(buffValue);
143
		cdataStarted = true;
144
		if (fRootElement == null)
145
			fDocument.appendChild(text);
146
		else
147
			((Element) fElementStack.peek()).appendChild(text);
148
	}
149
	
150
	public Node getDocumentElement()
151
	{
152
		fDocument.getDocumentElement().normalize();
153
		return fDocument.getDocumentElement();
154
	}
155
156
	public org.w3c.dom.Document getDocument()
157
	{
158
		fDocument.getDocumentElement().normalize();
159
		return fDocument;
160
	}
161
162
	public Hashtable getLineTable()
163
	{
164
		return fLineTable;
165
	}
166
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroManager.java (-1129 / +909 lines)
Lines 1-1130 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
12
13
import java.io.IOException;
13
import java.io.IOException;
14
import java.io.InputStream;
14
import java.io.InputStream;
15
import java.lang.reflect.InvocationTargetException;
15
import java.lang.reflect.InvocationTargetException;
16
import java.util.Hashtable;
16
import java.util.Vector;
17
import java.util.Vector;
17
18
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IConfigurationElement;
20
import org.eclipse.core.runtime.NullProgressMonitor;
21
import org.eclipse.core.runtime.IProgressMonitor;
21
import org.eclipse.core.runtime.Platform;
22
import org.eclipse.core.runtime.NullProgressMonitor;
22
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
23
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.core.runtime.jobs.IJobManager;
24
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
24
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
25
import org.eclipse.core.runtime.jobs.IJobManager;
25
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
26
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
26
import org.eclipse.jface.dialogs.MessageDialog;
27
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
27
import org.eclipse.jface.operation.IRunnableContext;
28
import org.eclipse.jface.dialogs.MessageDialog;
28
import org.eclipse.osgi.util.NLS;
29
import org.eclipse.jface.operation.IRunnableContext;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.osgi.util.NLS;
30
import org.eclipse.swt.widgets.Display;
31
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.widgets.Event;
32
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.Listener;
33
import org.eclipse.swt.widgets.Display;
33
import org.eclipse.swt.widgets.Shell;
34
import org.eclipse.swt.widgets.Event;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
35
import org.eclipse.swt.widgets.Listener;
35
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
36
import org.eclipse.swt.widgets.Shell;
36
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
37
import org.eclipse.swt.widgets.Widget;
37
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
38
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
38
import org.eclipse.tptp.test.auto.gui.internal.commands.factory.IMacroCommandFactory;
39
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
39
import org.eclipse.tptp.test.auto.gui.internal.commands.factory.MacroCommandFactoryLoader;
40
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
40
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
41
import org.eclipse.tptp.test.auto.gui.internal.commands.MacroCommandShell;
41
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
42
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
42
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException;
43
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
43
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound;
44
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
44
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner;
45
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader;
45
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
46
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException;
46
import org.eclipse.ui.IPartListener;
47
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound;
47
import org.eclipse.ui.IWorkbench;
48
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner;
48
import org.eclipse.ui.IWorkbenchPage;
49
import org.eclipse.ui.IPartListener;
49
import org.eclipse.ui.IWorkbenchPart;
50
import org.eclipse.ui.IWorkbench;
50
import org.eclipse.ui.IWorkbenchWindow;
51
import org.eclipse.ui.IWorkbenchPage;
51
import org.eclipse.ui.PlatformUI;
52
import org.eclipse.ui.IWorkbenchPart;
52
import org.w3c.dom.Node;
53
import org.eclipse.ui.IWorkbenchWindow;
53
import org.w3c.dom.NodeList;
54
import org.eclipse.ui.PlatformUI;
54
import org.xml.sax.SAXException;
55
import org.w3c.dom.Node;
55
56
import org.w3c.dom.NodeList;
56
/**
57
import org.xml.sax.SAXException;
57
 * A singleton class that manages the macro recording and playback. Clients
58
58
 * should always keep in mind that there is only one instance of a macro manager
59
/**
59
 * always running. Proper synchronization and clean up is left to the client
60
 * A singleton class that manages the macro recording and playback.  Clients should always keep in
60
 */
61
 * mind that there is only one instance of a macro manager always running.  Proper synchronization
61
public class MacroManager {
62
 * and clean up is left to the client
62
63
 */
63
	public static final String IGNORE = "__macro_ignore__";
64
public class MacroManager
64
65
{
65
	/*
66
	public static final String IGNORE = "__macro_ignore__";
66
	 * The state of jobs. This is used to listen for on going jobs and adding
67
67
	 * wait commands when there is a job running
68
	/* The state of jobs.  This is used to listen for on going jobs and adding wait commands when
68
	 */
69
	 * there is a job running */
69
	public static final int IDLE = 0;
70
	public static final int IDLE = 0;
70
71
71
	public static final int RUNNING = 1;
72
	public static final int RUNNING = 1;
72
73
73
	public static final int DONE = 2;
74
	public static final int DONE = 2;
74
75
75
	private Macro currentMacro;
76
	private Macro currentMacro;
76
77
77
	/* The instance that this singleton class holds */
78
	/* The instance that this singleton class holds */
78
	private static MacroManager macroManagerInstance;
79
	private static MacroManager macroManagerInstance;
79
80
80
	/*
81
	/* Keeps track of the global states that the macro manager is in.  See the
81
	 * Keeps track of the global states that the macro manager is in. See the
82
	 * global state events for the possible states that this macro manager can be in.  This
82
	 * global state events for the possible states that this macro manager can
83
	 * variable must be locked when it is read/written from/to.  Use globalStateLock to lock
83
	 * be in. This variable must be locked when it is read/written from/to. Use
84
	 * this field. */
84
	 * globalStateLock to lock this field.
85
	private byte globalState;
85
	 */
86
86
	private byte globalState;
87
	/* Global state lock */
87
88
	private Boolean globalStateLock;
88
	/* Global state lock */
89
89
	private Boolean globalStateLock;
90
	/* Global states */
90
91
	public static final byte RECORDING_MODE = 0x00; 			/* Recording mode */
91
	/* Verification hook listener */
92
	public static final byte VERIFICATION_MODE = 0x01; 			/* Verificaiton mode */
92
	private VerificationHookListener verificationHooksListener;
93
	public static final byte SUSPEND_MODE = 0x02; 				/* Suspend mode */
93
94
	public static final byte QUICK_RUN_MODE = 0x03; 			/* Quick run mode (when current workbench is used as the context) */
94
	/* The active workbench page */
95
	public static final byte EXECUTION_RUN_MODE = 0x04; 		/* Execution run mode (when proper launch configuration is used) */
95
	private IWorkbenchPage activePage;
96
	public static final byte IDLE_MODE = 0x05; 					/* Idle mode */
96
97
	public static final byte POSITION_BASED_REC_MODE = 0x06;	/* Position based recording */
97
	/* The part listener */
98
98
	private IPartListener partListener;
99
	/* Custom event details */
99
100
	public static final int POSITION_BASED_EVENT = Integer.MIN_VALUE;
100
	/*
101
	
101
	 * Global state listeners that will be invoked when the global state of this
102
	/* The verification command */
102
	 * macro manager changes
103
	private VerificationCommand verificationCommand;
103
	 */
104
104
	private Vector globalStateListeners;
105
	/* Verification hook listener */
105
106
	private VerificationHookListener verificationHooksListener;
106
	/* Stores the dependecies of the current test suite that is being executed */
107
107
	private Vector dependecies;
108
	/* The active workbench page */
108
109
	private IWorkbenchPage activePage;
109
	/* Stores the runner that is running the current test suite */
110
110
	private AutoGUIRunner runner;
111
	/* The part listener */
111
112
	private IPartListener partListener;
112
	/* Indicates whether artificial wait time is on/off */
113
113
	private boolean artificialWaitOn;
114
	/* Global state listeners that will be invoked when the global state 
114
115
	 * of this macro manager changes */
115
	/*
116
	private Vector globalStateListeners;
116
	 * Stores the allowable time-out threshold time for individual command
117
117
	 * execution
118
	/* Stores the dependecies of the current test suite that is being executed */
118
	 */
119
	private Vector dependecies;
119
	private int commandTimeoutThreshold;
120
120
121
	/* Stores the runner that is running the current test suite */
121
	/*
122
	private AutoGUIRunner runner;
122
	 * Points to the object mine loaded for the operation (e.g. record/playback)
123
	
123
	 * that is in progress
124
	/* Indicates whether artificial wait time is on/off */
124
	 */
125
	private boolean artificialWaitOn;
125
	private MacroObjectDescriptorMine objectMine;
126
	
126
127
	/* Stores the allowable time-out threshold time for individual command execution */
127
	private IMacroCommandFactory commandFactory;
128
	private int commandTimeoutThreshold;
128
129
	
129
	/* Points to the test suite that is being used to record a test case */
130
	/* Points to the object mine loaded for the operation (e.g. record/playback) that is in progress */
130
	private ITestSuite testSuite;
131
	private IObjectMine objectMine;
131
132
	
132
	/*
133
	/* Points to the test suite that is being used to record a test case */
133
	 * Indicates whether object mines should be used for a recording session or
134
	private ITestSuite testSuite;
134
	 * not
135
	
135
	 */
136
	/* Indicates whether object mines should be used for a recording session or not */
136
	private boolean objectMineOn;
137
	private boolean objectMineOn;
137
138
	
138
	/* The display listeners */
139
	/* Keeps an ordered list of the resolver ids */
139
	private DisplayListener listener;
140
	private String[] resolverIds;
140
141
	
141
	/* The job listeners */
142
	/* The widget resolver:
142
	private JobListener jobListener;
143
	 * KEY = resolver id
143
144
	 * VALUE = A class of type WidgetResolverLoader
144
	class DisplayListener implements Listener {
145
	 */
145
146
	private Hashtable widgetResolvers;
146
		public void handleEvent(Event event) {
147
	
147
			/* Bail out if we are in the suspend mode */
148
	/* The display listeners */
148
			synchronized (globalStateLock) {
149
	private DisplayListener listener;
149
				if (globalState == ModeConstants.SUSPEND_MODE)
150
150
					return;
151
	/* The job listeners */
151
			}
152
	private JobListener jobListener;
152
153
153
			onEvent(event);
154
	
154
		}
155
	class DisplayListener implements Listener
155
	}
156
	{
156
157
		public void handleEvent(Event event)
157
	class JobListener extends JobChangeAdapter {
158
		{
158
159
			/* Bail out if we are in the suspend mode */
159
		private int state = IDLE;
160
			synchronized (globalStateLock)
160
161
			{
161
		public void running(IJobChangeEvent event) {
162
				if (globalState == SUSPEND_MODE)
162
			if (!event.getJob().isSystem() && state == IDLE)
163
					return;
163
				state = RUNNING;
164
			}
164
		}
165
165
166
			onEvent(event);
166
		public void done(IJobChangeEvent event) {
167
		}
167
			if (!event.getJob().isSystem() && state == RUNNING)
168
	}
168
				state = DONE;
169
169
		}
170
	class JobListener extends JobChangeAdapter
170
171
	{
171
		public void reset() {
172
		private int state = IDLE;
172
			state = IDLE;
173
173
		}
174
		public void running(IJobChangeEvent event)
174
175
		{
175
		public int getState() {
176
			if (!event.getJob().isSystem() && state == IDLE)
176
			return state;
177
				state = RUNNING;
177
		}
178
		}
178
	}
179
179
180
		public void done(IJobChangeEvent event)
180
	/**
181
		{
181
	 * Private constructor. Use getInstance()
182
			if (!event.getJob().isSystem() && state == RUNNING)
182
	 */
183
				state = DONE;
183
	private MacroManager() {
184
		}
184
		listener = new DisplayListener();
185
185
		jobListener = new JobListener();
186
		public void reset()
186
		globalStateLock = new Boolean(false);
187
		{
187
		globalState = ModeConstants.RECORDING_MODE; /*
188
			state = IDLE;
188
													 * The initial global state
189
		}
189
													 * is recording
190
190
													 */
191
		public int getState()
191
	}
192
		{
192
193
			return state;
193
	/**
194
		}
194
	 * Returns the instance that this singleton class holds
195
	}
195
	 * 
196
196
	 * @return An instance of this class
197
	/**
197
	 */
198
	 * Private constructor. Use getInstance()
198
	public static MacroManager getInstance() {
199
	 */
199
		if (macroManagerInstance == null)
200
	private MacroManager()
200
			macroManagerInstance = new MacroManager();
201
	{
201
202
		listener = new DisplayListener();
202
		return macroManagerInstance;
203
		jobListener = new JobListener();		
203
	}
204
		globalStateLock = new Boolean(false);
204
205
		globalState = RECORDING_MODE; /* The initial global state is recording */
205
	public boolean isRecording() {
206
		widgetResolvers = new Hashtable();
206
		return currentMacro != null;
207
	}
207
	}
208
208
209
	/**
209
	/**
210
	 * Returns the instance that this singleton class holds
210
	 * Invoked to start a recording session
211
	 * 
211
	 * 
212
	 * @return An instance of this class
212
	 * @param testSuite
213
	 */
213
	 *            The test suite
214
	public static MacroManager getInstance()
214
	 * @param objectMineOn
215
	{
215
	 *            Indicates whether object mines should be used or not
216
		if (macroManagerInstance == null)
216
	 * 
217
			macroManagerInstance = new MacroManager();
217
	 * @throws CoreException
218
218
	 *             In case of an unexpected error
219
		return macroManagerInstance;
219
	 * @throws UIObjectNotFound
220
	}
220
	 *             If an expected UI object is not found
221
221
	 * @throws IDCollisionException
222
	public boolean isRecording()
222
	 *             If there is a ID collision between UI objects
223
	{
223
	 */
224
		return currentMacro != null;
224
	public void startRecording(ITestSuite testSuite, boolean objectMineOn)
225
	}
225
			throws CoreException, UIObjectNotFound, IDCollisionException {
226
226
		this.objectMineOn = objectMineOn;
227
	/**
227
		Display display = PlatformUI.getWorkbench().getDisplay();
228
	 * Invoked to start a recording session
228
		hookListeners(display);
229
	 * 
229
		MacroUtil.clearWorkbenchPartListeners();
230
	 * @param testSuite The test suite
230
		currentMacro = new Macro();
231
	 * @param objectMineOn Indicates whether object mines should be used or not
231
		currentMacro.initializeForRecording(display);
232
	 * 
232
233
	 * @throws CoreException In case of an unexpected error
233
		this.testSuite = testSuite;
234
	 * @throws UIObjectNotFound If an expected UI object is not found
234
		objectMine = MacroObjectDescriptorMineManager.getInstance()
235
	 * @throws IDCollisionException If there is a ID collision between UI objects
235
				.loadObjectMine(testSuite);
236
	 */
236
237
	public void startRecording(ITestSuite testSuite, boolean objectMineOn) throws CoreException, UIObjectNotFound, IDCollisionException
237
		hookPartListener();
238
	{
238
	}
239
		this.objectMineOn = objectMineOn;
239
240
		Display display = PlatformUI.getWorkbench().getDisplay();
240
	/**
241
		hookListeners(display);
241
	 * Stops the current macro that this macro manager maintains. The macro
242
		MacroUtil.clearWorkbenchPartListeners();
242
	 * returned can be null, if a previous error has caused the current macro to
243
		currentMacro = new Macro();
243
	 * be null
244
		currentMacro.initializeForRecording(display);
244
	 * 
245
		
245
	 * @param interrupted
246
		this.testSuite = testSuite; 
246
	 *            true if it is interrupted and false if it is normally stopped.
247
		objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite);
247
	 * @return The macro to be stopped (null if a previous error has occurred in
248
		
248
	 *         macro manager)
249
		hookPartListener();		
249
	 */
250
	}
250
	public Macro stopRecording(boolean interrupted) {
251
251
		removePartListener();
252
	
252
253
	/**
253
		/* Write the object mine to the test suite */
254
	 * Stops the current macro that this macro manager maintains.  The macro returned
254
		if (testSuite != null && objectMine != null && objectMineOn) {
255
	 * can be null, if a previous error has caused the current macro to be null
255
			if (!interrupted)
256
	 * 
256
				MacroObjectDescriptorMineManager.getInstance().writeObjectMine(
257
	 * @param interrupted true if it is interrupted and false if it is normally stopped. 
257
						objectMine);
258
	 * @return The macro to be stopped (null if a previous error has occurred in macro manager)
258
			testSuite = null;
259
	 */
259
			objectMine = null;
260
	public Macro stopRecording(boolean interrupted)
260
		}
261
	{
261
262
		removePartListener();
262
		if (currentMacro != null)
263
263
			currentMacro.stopRecording();
264
		/* Write the object mine to the test suite */
264
265
		if (testSuite != null && objectMine != null && objectMineOn)
265
		Macro newMacro = currentMacro;
266
		{
266
		currentMacro = null;
267
			if (!interrupted)
267
268
				ObjectMineManager.getInstance().writeObjectMine(objectMine);
268
		shutdown();
269
			testSuite = null;
269
		return newMacro;
270
			objectMine = null;
270
	}
271
		}
271
272
		
272
	/**
273
		if (currentMacro != null)
273
	 * Register a part listener
274
			currentMacro.stopRecording();
274
	 */
275
275
	private void hookPartListener() {
276
		Macro newMacro = currentMacro;
276
		activePage = GuiPlugin.getDefault().getWorkbench()
277
		currentMacro = null;		
277
				.getActiveWorkbenchWindow().getActivePage();
278
278
		partListener = new IPartListener() {
279
		shutdown();
279
280
		return newMacro;
280
			public void partActivated(IWorkbenchPart part) {
281
	}
281
				Event event = null;
282
	
282
283
	
283
				/* Simulate a focus in event */
284
284
				try {
285
	/**
285
					event = new Event();
286
	 * Register a part listener
286
					event.type = SWT.FocusIn;
287
	 */
287
					Shell shell = part.getSite().getPage().getWorkbenchWindow()
288
	private void hookPartListener()
288
							.getShell();
289
	{
289
					event.display = shell.getDisplay();
290
		activePage = GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
290
					event.widget = MacroUtil.getFirstChild(part);
291
		partListener = new IPartListener()
291
				} catch (Exception e) {
292
		{
292
					/* Don't report an event if there is an error */
293
			public void partActivated(IWorkbenchPart part)
293
					System.err.println(e.getMessage());
294
			{
294
				}
295
				Event event = null;
295
296
296
				if (event != null) {
297
				/* Simulate a focus in event */
297
					listener.handleEvent(event);
298
				try
298
				}
299
				{
299
			}
300
					event = new Event();
300
301
					event.type = SWT.FocusIn;
301
			public void partBroughtToTop(IWorkbenchPart part) {
302
					Shell shell = part.getSite().getPage().getWorkbenchWindow().getShell();
302
				/* Does not need to be implmented */
303
					event.display = shell.getDisplay();
303
			}
304
					event.widget = MacroUtil.getFirstChild(part);
304
305
				}
305
			public void partClosed(IWorkbenchPart part) {
306
				catch (Exception e)
306
				/* Does not need to be implmented */
307
				{
307
			}
308
					/* Don't report an event if there is an error */
308
309
					System.err.println(e.getMessage());
309
			public void partDeactivated(IWorkbenchPart part) {
310
				}
310
				/* Does not need to be implmented */
311
311
			}
312
				if (event != null)
312
313
				{
313
			public void partOpened(IWorkbenchPart part) {
314
					listener.handleEvent(event);
314
				/* Does not need to be implmented */
315
				}
315
			}
316
			}
316
317
317
		};
318
			public void partBroughtToTop(IWorkbenchPart part)
318
319
			{
319
		activePage.addPartListener(partListener);
320
				/* Does not need to be implmented */
320
	}
321
			}
321
322
322
	/**
323
			public void partClosed(IWorkbenchPart part)
323
	 * Remove the part listener
324
			{
324
	 */
325
				/* Does not need to be implmented */
325
	private void removePartListener() {
326
			}
326
		if (activePage == null)
327
327
			return;
328
			public void partDeactivated(IWorkbenchPart part)
328
329
			{
329
		activePage.removePartListener(partListener);
330
				/* Does not need to be implmented */
330
		activePage = null;
331
			}
331
		partListener = null;
332
332
	}
333
			public void partOpened(IWorkbenchPart part)
333
334
			{
334
	public Macro getCurrentMacro() {
335
				/* Does not need to be implmented */
335
		return currentMacro;
336
			}
336
	}
337
337
338
		};
338
	public void hookListeners(Display display) {
339
339
		display.addFilter(SWT.MouseUp, listener);
340
		activePage.addPartListener(partListener);
340
		display.addFilter(SWT.KeyUp, listener);
341
	}
341
		display.addFilter(SWT.KeyDown, listener);
342
342
		display.addFilter(SWT.Selection, listener);
343
	/**
343
		display.addFilter(SWT.DefaultSelection, listener);
344
	 * Remove the part listener
344
		display.addFilter(SWT.Expand, listener);
345
	 */
345
		display.addFilter(SWT.Collapse, listener);
346
	private void removePartListener()
346
		display.addFilter(SWT.Modify, listener);
347
	{
347
		display.addFilter(SWT.Activate, listener);
348
		if (activePage == null)
348
		display.addFilter(SWT.Close, listener);
349
			return;
349
		display.addFilter(SWT.FocusIn, listener);
350
350
		IJobManager jobManager = Platform.getJobManager();
351
		activePage.removePartListener(partListener);
351
		jobManager.addJobChangeListener(jobListener);
352
		activePage = null;
352
	}
353
		partListener = null;
353
354
	}
354
	public void hookPositionBasedListeners(Display display) {
355
	
355
		display.addFilter(SWT.Activate, listener);
356
	public Macro getCurrentMacro()
356
		display.addFilter(SWT.Close, listener);
357
	{
357
		display.addFilter(SWT.MouseUp, listener);
358
		return currentMacro;
358
		display.addFilter(SWT.MouseDown, listener);
359
	}
359
		display.addFilter(SWT.MouseMove, listener);
360
360
		display.addFilter(SWT.KeyUp, listener);
361
361
		display.addFilter(SWT.KeyDown, listener);
362
362
363
	public void hookListeners(Display display)
363
		IJobManager jobManager = Platform.getJobManager();
364
	{
364
		jobManager.addJobChangeListener(jobListener);
365
		display.addFilter(SWT.MouseUp, listener);
365
	}
366
		display.addFilter(SWT.KeyUp, listener);
366
367
		display.addFilter(SWT.KeyDown, listener);
367
	public void unhookListeners(Display display) {
368
		display.addFilter(SWT.Selection, listener);
368
		display.removeFilter(SWT.MouseUp, listener);
369
		display.addFilter(SWT.DefaultSelection, listener);
369
		display.removeFilter(SWT.KeyUp, listener);
370
		display.addFilter(SWT.Expand, listener);
370
		display.removeFilter(SWT.KeyDown, listener);
371
		display.addFilter(SWT.Collapse, listener);
371
		display.removeFilter(SWT.Selection, listener);
372
		display.addFilter(SWT.Modify, listener);
372
		display.removeFilter(SWT.DefaultSelection, listener);
373
		display.addFilter(SWT.Activate, listener);		
373
		display.removeFilter(SWT.Expand, listener);
374
		display.addFilter(SWT.Close, listener);
374
		display.removeFilter(SWT.Collapse, listener);
375
		display.addFilter(SWT.FocusIn, listener);		
375
		display.removeFilter(SWT.Modify, listener);
376
		IJobManager jobManager = Platform.getJobManager();
376
		display.removeFilter(SWT.Activate, listener);
377
		jobManager.addJobChangeListener(jobListener);
377
		display.removeFilter(SWT.Close, listener);
378
	}
378
		display.removeFilter(SWT.FocusIn, listener);
379
	
379
		IJobManager jobManager = Platform.getJobManager();
380
	public void hookPositionBasedListeners(Display display)
380
		jobManager.removeJobChangeListener(jobListener);
381
	{	
381
	}
382
		display.addFilter(SWT.Activate, listener);		
382
383
		display.addFilter(SWT.Close, listener);
383
	public void unhookPositionBasedListeners(Display display) {
384
		display.addFilter(SWT.MouseUp, listener);
384
		display.removeFilter(SWT.Activate, listener);
385
		display.addFilter(SWT.MouseDown, listener);
385
		display.removeFilter(SWT.Close, listener);
386
		display.addFilter(SWT.KeyUp, listener);
386
		display.removeFilter(SWT.MouseUp, listener);
387
		display.addFilter(SWT.KeyDown, listener);
387
		display.removeFilter(SWT.MouseDown, listener);
388
		
388
		display.removeFilter(SWT.MouseMove, listener);
389
		IJobManager jobManager = Platform.getJobManager();
389
		display.removeFilter(SWT.KeyUp, listener);
390
		jobManager.addJobChangeListener(jobListener);
390
		display.removeFilter(SWT.KeyDown, listener);
391
	}
391
392
392
		IJobManager jobManager = Platform.getJobManager();
393
	public void unhookListeners(Display display)
393
		jobManager.removeJobChangeListener(jobListener);
394
	{
394
	}
395
		display.removeFilter(SWT.MouseUp, listener);
395
396
		display.removeFilter(SWT.KeyUp, listener);
396
	public void shutdown() {
397
		display.removeFilter(SWT.KeyDown, listener);
397
		Display display = PlatformUI.getWorkbench().getDisplay();
398
		display.removeFilter(SWT.Selection, listener);
398
		unhookListeners(display);
399
		display.removeFilter(SWT.DefaultSelection, listener);
399
		unhookPositionBasedListeners(display);
400
		display.removeFilter(SWT.Expand, listener);
400
		if (currentMacro != null)
401
		display.removeFilter(SWT.Collapse, listener);
401
			currentMacro.stopRecording();
402
		display.removeFilter(SWT.Modify, listener);
402
		currentMacro = null;
403
		display.removeFilter(SWT.Activate, listener);
403
		artificialWaitOn = false;
404
		display.removeFilter(SWT.Close, listener);
404
	}
405
		display.removeFilter(SWT.FocusIn, listener);
405
406
		IJobManager jobManager = Platform.getJobManager();
406
	/**
407
		jobManager.removeJobChangeListener(jobListener);
407
	 * Prepares this macro manager for playback of test cases. This method
408
	}
408
	 * should be invoked to do the required one time initialization before a
409
	
409
	 * test suite's test cases are played back.
410
	public void unhookPositionBasedListeners(Display display)
410
	 * 
411
	{		
411
	 * @param objectMineXML
412
		display.removeFilter(SWT.Activate, listener);		
412
	 *            The object mine XML
413
		display.removeFilter(SWT.Close, listener);
413
	 * @throws CoreException
414
		display.removeFilter(SWT.MouseUp, listener);
414
	 *             In case of any unexpected error
415
		display.removeFilter(SWT.MouseDown, listener);
415
	 */
416
		display.removeFilter(SWT.KeyUp, listener);
416
	public void prepareForPlayBack(String objectMineXML) throws CoreException {
417
		display.removeFilter(SWT.KeyDown, listener);
417
		try {
418
		
418
			setObjectMine(MacroObjectDescriptorMineManager.getInstance()
419
		IJobManager jobManager = Platform.getJobManager();
419
					.loadObjectMine(objectMineXML));
420
		jobManager.removeJobChangeListener(jobListener);
420
		} catch (Exception e) {
421
	}
421
			AutoGUIUtil.throwCoreException(
422
422
					AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
423
	public void shutdown()
423
		}
424
	{
424
	}
425
		Display display = PlatformUI.getWorkbench().getDisplay();
425
426
		unhookListeners(display);
426
	/**
427
		unhookPositionBasedListeners(display);
427
	 * Plays a provided macro stream. The method will close the input stream
428
		if (currentMacro != null)
428
	 * upon parsing.
429
			currentMacro.stopRecording();
429
	 * 
430
		currentMacro = null;
430
	 * @param is
431
		artificialWaitOn = false;
431
	 * @throws CoreException
432
	}
432
	 */
433
	
433
	public boolean play(final Display display, final IRunnableContext context,
434
	
434
			String scriptName, XMLDefaultHandler handler, Boolean shouldBlock)
435
	/**
435
			throws CoreException {
436
	 * Prepares this macro manager for playback of test cases.  This method should be
436
		Node root = handler.getDocumentElement();
437
	 * invoked to do the required one time initialization before a test suite's test 
437
		NodeList children = root.getChildNodes();
438
	 * cases are played back.
438
		MacroCommandShell.initializeForNewPlay();
439
	 * 
439
440
	 * @param objectMineXML The object mine XML
440
		final Macro macro = new Macro(scriptName);
441
	 * @throws CoreException In case of any unexpected error
441
		for (int i = 0; i < children.getLength(); i++) {
442
	 */
442
			Node child = children.item(i);
443
	public void prepareForPlayBack(String objectMineXML) throws CoreException
443
			if (child.getNodeName().equals(MacroConstants.SHELL_ELEMENT)) {
444
	{	
444
				macro.load(child, handler.getLineTable());
445
		try
445
			}
446
		{
446
		}
447
			setObjectMine(ObjectMineManager.getInstance().loadObjectMine(objectMineXML));
447
		// discard the DOM
448
		} catch (Exception e)
448
		handler = null;
449
		{
449
450
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
450
		final boolean[] result = new boolean[1];
451
		} 						
451
452
	}
452
		class MacroOperationWrapper implements Runnable {
453
	
453
454
	
454
			private Exception exception;
455
	/**
455
			private Object objectToNotify;
456
	 * Plays a provided macro stream. The method will close the input stream
456
			private boolean isDone;
457
	 * upon parsing.
457
458
	 * 
458
			public MacroOperationWrapper(Object objectToNotify) {
459
	 * @param is
459
				this.objectToNotify = objectToNotify;
460
	 * @throws CoreException
460
				isDone = false;
461
	 */
461
			}
462
	public boolean play(final Display display, final IRunnableContext context, String scriptName, XMLDefaultHandler handler, Boolean shouldBlock) throws CoreException
462
463
	{		
463
			public void run() {
464
		Node root = handler.getDocumentElement();
464
				try {
465
		NodeList children = root.getChildNodes();
465
					/*
466
		MacroCommandShell.initializeForNewPlay();
466
					 * Ali M.: Unfortunately position-based commands don't work
467
		
467
					 * when the macro is played in an IRunnableContext with a
468
		final Macro macro = new Macro(scriptName);
468
					 * progress bar. I had to sacrifice the progress bar for
469
		for (int i = 0; i < children.getLength(); i++)
469
					 * position-based commands to run correctly
470
		{
470
					 */
471
			Node child = children.item(i);
471
					result[0] = runMacro(macro, display,
472
			if (child.getNodeName().equals(MacroConstants.SHELL_ELEMENT))
472
							new NullProgressMonitor());
473
			{
473
474
				macro.addShell(child, handler.getLineTable());
474
					if (objectToNotify != null) {
475
			}
475
						synchronized (objectToNotify) {
476
		}
476
							objectToNotify.notify();
477
		// discard the DOM
477
						}
478
		handler = null;
478
					}
479
479
					isDone = true;
480
		final boolean[] result = new boolean[1];
480
				} catch (Exception e) {
481
		
481
					exception = e;
482
		class MacroOperationWrapper implements Runnable
482
					isDone = true;
483
		{
483
				}
484
			private Exception exception;
484
			}
485
			private Object objectToNotify;
485
486
			private boolean isDone;
486
			public void didErrorOccur() throws Exception {
487
			
487
				if (exception != null)
488
			public MacroOperationWrapper (Object objectToNotify)
488
					throw exception;
489
			{
489
			}
490
				this.objectToNotify = objectToNotify;
490
491
				isDone = false;
491
			public boolean isDone() {
492
			}
492
				return isDone;
493
			
493
			}
494
			
494
		}
495
			public void run()
495
496
			{
496
		try {
497
				try
497
			/*
498
				{					
498
			 * Run the macro synchronously or asynchronously depending on the
499
					/* Ali M.: Unfortunately position-based commands don't work when the macro is played in an IRunnableContext with
499
			 * argument passed in
500
					 * a progress bar.  I had to sacrifice the progress bar for position-based commands to run correctly */
500
			 */
501
					result[0] = runMacro(macro, display, new NullProgressMonitor());
501
			if (shouldBlock.booleanValue()) {
502
					
502
				MacroOperationWrapper macroRunOperation = new MacroOperationWrapper(
503
					if (objectToNotify != null)
503
						shouldBlock);
504
					{
504
				Thread macroRunThread = new Thread(macroRunOperation);
505
						synchronized(objectToNotify)
505
				macroRunThread.start();
506
						{
506
507
							objectToNotify.notify();
507
				while (!macroRunOperation.isDone()) {
508
						}
508
					synchronized (shouldBlock) {
509
					}
509
						shouldBlock.wait(500);
510
					isDone = true;
510
					}
511
				}
511
				}
512
				catch (Exception e)
512
513
				{
513
				macroRunOperation.didErrorOccur();
514
					exception = e;
514
			} else
515
					isDone = true;
515
				new Thread(new MacroOperationWrapper(null)).start();
516
				}
516
		} catch (Exception e) {
517
			}
517
			/* The cause of this exception would give away the error */
518
			
518
			AutoGUIUtil.throwCoreException(
519
			public void didErrorOccur() throws Exception
519
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, -1, e);
520
			{
520
			result[0] = false;
521
				if (exception != null)
521
		} finally {
522
					throw exception;
522
			/* Indicate that we were done playing, if this is a blocking call */
523
			}
523
			if (shouldBlock != null && shouldBlock.booleanValue())
524
			
524
				MacroCommandShell.macroStopped();
525
			public boolean isDone()
525
		}
526
			{
526
		return result[0];
527
				return isDone;
527
	}
528
			}
528
529
		}
529
	private boolean runMacro(final Macro macro, final Display display,
530
		
530
			IProgressMonitor monitor) throws InvocationTargetException {
531
		try
531
		boolean success = false;
532
		{			
532
		try {
533
			/* Run the macro synchronously or asynchronously depending on the argument passed in */
533
			// System.out.println("Start macro: "+macro.getName());
534
			if (shouldBlock.booleanValue())
534
			success = macro.playback(display, null, monitor);
535
			{
535
		} catch (CoreException e) {
536
				MacroOperationWrapper macroRunOperation = new MacroOperationWrapper(shouldBlock);
536
			throw new InvocationTargetException(e);
537
				Thread macroRunThread = new Thread(macroRunOperation);
537
		} catch (ClassCastException e) {
538
				macroRunThread.start();
538
			throw new InvocationTargetException(e);
539
				
539
		} finally {
540
				while (!macroRunOperation.isDone())
540
			monitor.done();
541
				{
541
			// System.out.println("Stop macro: "+macro.getName());
542
					synchronized (shouldBlock)
542
		}
543
					{
543
		return success;
544
						shouldBlock.wait(500);
544
	}
545
					}
545
546
				}
546
	public XMLDefaultHandler createMacroDocument(InputStream is)
547
				
547
			throws CoreException {
548
				macroRunOperation.didErrorOccur();
548
		XMLDefaultHandler handler = null;
549
			}
549
		try {
550
			else
550
			handler = MacroUtil.createXMLDocument(is);
551
				new Thread(new MacroOperationWrapper(null)).start();
551
		} catch (SAXException e) {
552
		}
552
			AutoGUIUtil.throwCoreException(NLS.bind(
553
		catch (Exception e)
553
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e
554
		{
554
							.getLocalizedMessage()), 0, e);
555
			/* The cause of this exception would give away the error */
555
		} catch (IOException e) {
556
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, -1, e);
556
			AutoGUIUtil.throwCoreException(NLS.bind(
557
			result[0] = false;
557
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e
558
		}
558
							.getLocalizedMessage()), 0, e);
559
		finally
559
		}
560
		{
560
561
			/* Indicate that we were done playing, if this is a blocking call */
561
		return handler;
562
			if (shouldBlock != null && shouldBlock.booleanValue())
562
	}
563
				MacroCommandShell.macroStopped();
563
564
		}
564
	private void onEvent(Event event) {
565
		return result[0];
565
		try {
566
	}
566
			/*
567
567
			 * If for any reason the current macro is null, then something has
568
	private boolean runMacro(final Macro macro, final Display display, IProgressMonitor monitor) throws InvocationTargetException
568
			 * gone wrong. Shut the macro manager down
569
	{
569
			 */
570
		boolean success = false;
570
			if (currentMacro == null) {
571
		try
571
				shutdown();
572
		{
572
				return;
573
			// System.out.println("Start macro: "+macro.getName());
573
			}
574
			success = macro.playback(display, null, monitor);
574
575
		}
575
			synchronized (globalStateLock) {
576
		catch (CoreException e)
576
				if (globalState == ModeConstants.RECORDING_MODE
577
		{
577
						&& (event.type == SWT.Close || event.type == SWT.Activate)
578
			throw new InvocationTargetException(e);
578
						&& !(event.widget instanceof Shell))
579
		}
579
					return;
580
		catch (ClassCastException e)
580
			}
581
		{
581
582
			throw new InvocationTargetException(e);
582
			/*
583
		}
583
			 * If there is an incomming event and there is already a job running
584
		finally
584
			 * in the background then insert a pause command
585
		{
585
			 */
586
			monitor.done();
586
			if (jobListener.getState() == RUNNING
587
			// System.out.println("Stop macro: "+macro.getName());
587
					|| jobListener.getState() == DONE) {
588
		}
588
				currentMacro.addPause();
589
		return success;
589
				jobListener.reset();
590
	}
590
			}
591
591
592
	public XMLDefaultHandler createMacroDocument(InputStream is) throws CoreException
592
			/*
593
	{
593
			 * Check the global state here. If we're in the verification mode,
594
		XMLDefaultHandler handler = null;
594
			 * then redirect the events to the verification command.
595
		try
595
			 */
596
		{
596
			synchronized (globalStateLock) {
597
			handler = MacroUtil.createXMLDocument(is);
597
				if (globalState == ModeConstants.RECORDING_MODE) {
598
		}
598
					currentMacro.addEvent(event);
599
		catch (SAXException e)
599
				} else if (globalState == ModeConstants.POSITION_BASED_REC_MODE) {
600
		{
600
					/*
601
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e);
601
					 * We'll tag the event with a detail constant that will
602
		}
602
					 * identify the event as position based
603
		catch (IOException e)
603
					 */
604
		{
604
					event.detail = EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT;
605
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_PARSING, e.getLocalizedMessage()), 0, e);
605
					currentMacro.addEvent(event);
606
		}
606
				} else if (globalState == ModeConstants.VERIFICATION_MODE) {
607
		
607
					/*
608
		return handler;
608
					 * We'll tag the event with a detail constant that will
609
	}
609
					 * identify the event as verification hook insertion related
610
610
					 * command
611
611
					 */
612
	private void onEvent(Event event)
612
					event.detail = EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT;
613
	{
613
					currentMacro.addEvent(event);
614
		try
614
615
		{				
615
					// see if the insertion was successful, notify the listener
616
			/* If for any reason the current macro is null, then something has gone wrong.  Shut the macro manager down */
616
					// about the result
617
			if (currentMacro == null)
617
					if (currentMacro.getTopShell() == null) {
618
			{
618
						setGlobalState(ModeConstants.SUSPEND_MODE);
619
				shutdown();
619
						showError(
620
				return;
620
								AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL_T,
621
			}
621
								AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL);
622
622
						setGlobalState(ModeConstants.RECORDING_MODE);
623
623
					}
624
			synchronized (globalStateLock)
624
				}
625
			{
625
			}
626
				if (globalState == RECORDING_MODE && (event.type == SWT.Close || event.type == SWT.Activate) && !(event.widget instanceof Shell))
626
627
					return;
627
		} catch (Exception e) {
628
			}
628
			AutoGUIUtil.openErrorWithDetail(
629
629
					AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN, e.getMessage(), e);
630
			/* If there is an incomming event and there is already a job running in the background
630
			e.printStackTrace();
631
			 * then insert a pause command */
631
			stopRecording(true);
632
			if (jobListener.getState() == RUNNING || jobListener.getState() == DONE)
632
		}
633
			{
633
	}
634
				currentMacro.addPause();
634
635
				jobListener.reset();
635
	/**
636
			}
636
	 * Show an error message
637
637
	 * 
638
			/* Check the global state here.  If we're in the verification mode, then 
638
	 * @param title
639
			 * redirect the events to the verification command. */
639
	 *            The title of the error message
640
			synchronized (globalStateLock)
640
	 * @param errorMsg
641
			{
641
	 *            The actual error message
642
				if (globalState == RECORDING_MODE)
642
	 */
643
				{
643
	public void showError(final String title, final String errorMsg) {
644
					currentMacro.addEvent(event);
644
		final IWorkbench workbench = PlatformUI.getWorkbench();
645
				}
645
		workbench.getDisplay().syncExec(new Runnable() {
646
				else if (globalState == POSITION_BASED_REC_MODE)
646
647
				{
647
			public void run() {
648
					/* We'll tag the event with a detail constant that will identify the event as position based */
648
				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
649
					event.detail = POSITION_BASED_EVENT;
649
				if (window != null) {
650
					currentMacro.addEvent (event);
650
					MessageDialog.openError(window.getShell(), title, errorMsg);
651
				}
651
				}
652
				else if (globalState == VERIFICATION_MODE)
652
			}
653
				{					
653
		});
654
					verificationCommand = VerificationCommand.constructInstance(null, event);
654
	}
655
					
655
656
					/* If we get events that can possibly change our shell stack, then fire off to the current macro
656
	protected void notifyVerificationListener(
657
					 * to handle it */				
657
			VerificationCommand verificationCommand) {
658
					if (event.type == SWT.Activate && event.widget instanceof Shell)
658
		if (verificationHooksListener != null)
659
					{
659
			verificationHooksListener.instanceReady(verificationCommand);
660
						currentMacro.addEvent(event);
660
661
					}
661
	}
662
662
663
					/* Something went wrong.  Inform the user with some feedback */
663
	protected void notifyVerificationListener(String error) {
664
					if (verificationCommand == null)
664
		if (verificationHooksListener != null)
665
					{
665
			verificationHooksListener.error(error);
666
						String error = VerificationCommand.getError();
666
	}
667
						if (error != null && !error.equals(""))
667
668
							notifyVerificationListener(error);
668
	/**
669
					}
669
	 * Pre-condition:
670
670
	 * <ul>
671
					/* The normal flow */
671
	 * <li> To guarantee that this field is not changed while it is being used,
672
					else
672
	 * it must be locked </li>
673
					{
673
	 * </ul>
674
						MacroCommandShell topShell = currentMacro.getTopShell();					
674
	 * 
675
						
675
	 * @return The global state of the macro manager.
676
						/* There is a chance that the macro does not have a top shell.  We'll
676
	 */
677
						 * attempt to resolve its top shell, if unsuccessful, then we'll prompt
677
	public byte getGlobalState() {
678
						 * the user with an error. */
678
		return globalState;
679
						
679
	}
680
						if (topShell == null && event.widget instanceof Control)
680
681
						{
681
	public void setGlobalState(byte globalState) {
682
							Event artificialEvent = new Event();
682
		synchronized (globalStateLock) {
683
							artificialEvent.type = SWT.Activate;
683
			byte oldState = this.globalState;
684
							artificialEvent.display = event.widget.getDisplay();
684
			this.globalState = globalState;
685
							artificialEvent.widget = ((Control) event.widget).getShell();
685
686
							currentMacro.addEvent(artificialEvent);
686
			if (globalStateListeners != null && oldState != this.globalState) {
687
						}
687
				for (int i = 0; i < globalStateListeners.size(); i++) {
688
688
					GlobalStateListener gsl = (GlobalStateListener) globalStateListeners
689
						/* If the resolve attempt failed, then notify the user */
689
							.get(i);
690
						topShell = currentMacro.getTopShell();
690
					if (gsl.isListenerOn())
691
						if (topShell == null)
691
						gsl.globalStateChange(oldState, this.globalState);
692
						{
692
				}
693
							setGlobalState(SUSPEND_MODE);
693
694
							showError(AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL_T, AutoGUIMessages.AUTO_GUI_ERROR_VER_TOP_SHELL);
694
			}
695
							setGlobalState(RECORDING_MODE);
695
		}
696
							return;
696
	}
697
						}
697
698
698
	public void setGlobalStateWithoutLock(byte globalState) {
699
						verificationCommand.setParent (topShell);
699
		byte oldState = this.globalState;
700
						topShell.addVerificationCommand(verificationCommand);
700
		this.globalState = globalState;
701
						notifyVerificationListener(verificationCommand);
701
702
					}
702
		if (globalStateListeners != null && oldState != this.globalState) {
703
				}
703
			for (int i = 0; i < globalStateListeners.size(); i++) {
704
			}
704
				GlobalStateListener gsl = (GlobalStateListener) globalStateListeners
705
705
						.get(i);
706
		}
706
				if (gsl.isListenerOn())
707
		catch (Exception e)
707
					gsl.globalStateChange(oldState, this.globalState);
708
		{
708
			}
709
			e.printStackTrace();
709
710
			stopRecording(true);
710
		}
711
		}
711
	}
712
	}
712
713
713
	public void setVerListener(VerificationHookListener verHookListener) {
714
	/**
714
		verificationHooksListener = verHookListener;
715
	 * Show an error message 
715
	}
716
	 * @param title The title of the error message
716
717
	 * @param errorMsg The actual error message
717
	public void removeVerListener() {
718
	 */
718
		verificationHooksListener = null;
719
	private void showError(final String title, final String errorMsg)
719
	}
720
	{
720
721
		final IWorkbench workbench = PlatformUI.getWorkbench();
721
	public void registerGlobalStateListener(GlobalStateListener gsl) {
722
		workbench.getDisplay().syncExec(new Runnable()
722
		if (this.globalStateListeners == null)
723
		{
723
			this.globalStateListeners = new Vector(2);
724
			public void run()
724
725
			{
725
		this.globalStateListeners.add(gsl);
726
				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
726
	}
727
				if (window != null)
727
728
				{
728
	public void removeGlobalStateListener(GlobalStateListener gsl) {
729
					MessageDialog.openError(window.getShell(), title, errorMsg);
729
		if (this.globalStateListeners != null) {
730
				}
730
			this.globalStateListeners.remove(gsl);
731
			}
731
			if (this.globalStateListeners.size() == 0)
732
		});
732
				this.globalStateListeners = null;
733
	}
733
		}
734
734
	}
735
	private void notifyVerificationListener(VerificationCommand verificationCommand)
735
736
	{
736
	public void setDependecies(Vector dependecies) {
737
		if (verificationHooksListener != null)
737
		this.dependecies = dependecies;
738
			verificationHooksListener.instanceReady(verificationCommand);
738
	}
739
739
740
	}
740
	public Vector getDependecies() {
741
741
		return this.dependecies;
742
	private void notifyVerificationListener(String error)
742
	}
743
	{
743
744
		if (verificationHooksListener != null)
744
	public AutoGUIRunner getRunner() {
745
			verificationHooksListener.error(error);
745
		return runner;
746
	}
746
	}
747
	
747
748
	
748
	public void setRunner(AutoGUIRunner runner) {
749
	/**
749
		this.runner = runner;
750
	 * Return the widget id resolved by the widget resolver whose id is passed in.
750
	}
751
	 * If in case the resolverId is null, then step through the widget resolvers starting
751
752
	 * from index inx and return the results of the first resolver that is able to resolve
752
	/**
753
	 * the widget that is passed in.
753
	 * This method is invoked to toggle the position based recording option on
754
	 *   
754
	 * or off. Turning on position based recording will only record
755
	 * @param widget The widget to be resolved
755
	 * position-based commands. This is only recommended where object based
756
	 * @param resolverId The resolver id.  It can be null
756
	 * recording cannot be used. (e.g. User clicking at a specific location of a
757
	 * @param inx The index of the resolvers that the search should begin from.  This is 
757
	 * canvas)
758
	 * declared as an array because this method needs to preserve the change in value.  The
758
	 * 
759
	 * array is of size 1 and its value must always be >= 0. 
759
	 * @param state
760
	 * 
760
	 *            True indicates that position based recording should be turned
761
	 * @return The resolved widget id or null if none can be found 
761
	 *            on and false indicates that it should be turned off
762
	 */	
762
	 * 
763
	public IWidgetId resolveWidget (Widget parent, Object object, String resolverId, int[] inx)
763
	 * @return true if operation is successful; false otherwise
764
	{		
764
	 */
765
		/* Load the widget if neccessary */
765
	public synchronized boolean togglePositionBasedRec(boolean state) {
766
		if (resolverIds == null)
766
767
		{
767
		synchronized (globalStateLock) {
768
			loadWidgetResolvers();
768
			Display currentDisplay = PlatformUI.getWorkbench().getDisplay();
769
		}
769
770
		
770
			/* We're required to turn on position based recoridng */
771
		/* We have a valid resolver id */
771
			if (state) {
772
		if (resolverId != null)
772
				if (currentDisplay != null) {
773
		{
773
					unhookListeners(currentDisplay);
774
			WidgetResolverLoader widgetResolverLoader = (WidgetResolverLoader)widgetResolvers.get(resolverId);
774
					hookPositionBasedListeners(currentDisplay);
775
			if (widgetResolverLoader == null)
775
776
			{
776
					globalState = ModeConstants.POSITION_BASED_REC_MODE;
777
				return null;
777
				} else
778
			}
778
					return false;
779
			return widgetResolverLoader.getWidgetResolver().getUniqueId(parent, object);
779
			}
780
		}
780
			/* Otherwise turn the option off */
781
		
781
			else if (!state) {
782
		/* Otherwise, we'll need to step through the resolvers */
782
				if (currentDisplay != null) {
783
		if (inx[0] < 0 || inx[0] >= resolverIds.length)
783
					unhookPositionBasedListeners(currentDisplay);
784
			return null;
784
					hookListeners(currentDisplay);
785
		
785
786
		for (int i = inx[0]; i < resolverIds.length; i++)
786
					globalState = ModeConstants.RECORDING_MODE;
787
		{			
787
				} else
788
			WidgetResolverLoader widgetResolverLoader = (WidgetResolverLoader)widgetResolvers.get(resolverIds[i]);
788
					return false;
789
			IWidgetId widgetId = widgetResolverLoader.getWidgetResolver().getUniqueId(parent, object);
789
			}
790
			inx[0]++;
790
791
			if (widgetId != null)
791
		}
792
				return widgetId;
792
793
		}
793
		return true;
794
				
794
795
		return null;
795
	}
796
	}
796
797
	
797
	public boolean isArtificialWaitOn() {
798
	
798
		return artificialWaitOn;
799
	public Hashtable getWidgetResolvers()
799
	}
800
	{
800
801
		if (resolverIds == null)
801
	public void setArtificialWaitOn(boolean artificialWaitOn) {
802
			loadWidgetResolvers();
802
		this.artificialWaitOn = artificialWaitOn;
803
		
803
	}
804
		return widgetResolvers;
804
805
	}
805
	/**
806
	
806
	 * @return the objectMine
807
	public IWidgetId resolveWidget (Widget widget, String resolverId, int[] inx)
807
	 */
808
	{
808
	public MacroObjectDescriptorMine getObjectMine() {
809
		return resolveWidget (widget instanceof Control ? ((Control)widget).getParent() : null, widget, resolverId, inx);
809
		return objectMine;
810
	}
810
	}
811
811
812
	/**
812
	/**
813
	 * Load the registered widget resolvers.  The widget resolvers are ordered in the descending order of their priority
813
	 * @param objectMine
814
	 */
814
	 *            the objectMine to set
815
	private void loadWidgetResolvers()
815
	 */
816
	{
816
	public void setObjectMine(MacroObjectDescriptorMine objectMine) {
817
		IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.tptp.test.auto.gui.widgetResolver");
817
		this.objectMine = objectMine;
818
		Vector tempContainer = new Vector(elements.length);
818
	}
819
		
819
820
		for (int i = 0; i < elements.length; i++)
820
	/**
821
		{
821
	 * Used to register classes as listeners that are awaiting the creation of a
822
			WidgetResolverLoader widgetResolverReg = WidgetResolverLoader.constructInstance(elements[i]);
822
	 * VerificationCommand from a focus command of an editor or a viewer.
823
			if (widgetResolverReg != null)
823
	 * 
824
			{
824
	 * @author Ali Mehregani
825
				tempContainer.add(findIndex(widgetResolverReg.getPriority(), tempContainer), widgetResolverReg);
825
	 */
826
				widgetResolvers.put(widgetResolverReg.getId(), widgetResolverReg);
826
	public interface VerificationHookListener {
827
			}
827
828
		}
828
		/**
829
		
829
		 * Reports any error while attempting to construct object
830
		resolverIds = new String[tempContainer.size()];
830
		 * 
831
		for (int i = 0; i < resolverIds.length; i++)
831
		 * @param error
832
		{
832
		 *            A descriptive error message
833
			resolverIds[i] = ((WidgetResolverLoader)tempContainer.get(i)).getId();
833
		 */
834
		}
834
		public void error(String error);
835
	}
835
836
836
		/**
837
	private int findIndex(int desiredPriority, Vector container, int startIntervalInx, int endIntervalInx, int length) 
837
		 * Invoked when there is an instance ready
838
	{		
838
		 * 
839
		if (startIntervalInx == endIntervalInx || startIntervalInx == endIntervalInx - 1)
839
		 * @param verificationCommand
840
		{
840
		 *            The instance of verification command created as a result
841
			if (length > 0)
841
		 *            of an event.
842
			{
842
		 */
843
				WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader)container.get(startIntervalInx);
843
		public void instanceReady(VerificationCommand verificationCommand);
844
				int priority = widgetResolverReg.getPriority();
844
	}
845
				if (desiredPriority < priority)
845
846
					return startIntervalInx;
846
	/**
847
			}
847
	 * A gateway for client to determine the global state changes of the macro
848
			return endIntervalInx;
848
	 * recorder.
849
		}
849
	 * 
850
		
850
	 * @author amehregani
851
		/* What's in the middle? */
851
	 */
852
		int middleInx = startIntervalInx + (int) Math.ceil((endIntervalInx - startIntervalInx)/2);
852
	public interface GlobalStateListener {
853
		WidgetResolverLoader widgetResolverReg = (WidgetResolverLoader)container.get(middleInx);
853
854
		int middleElementPriority = widgetResolverReg.getPriority();
854
		/**
855
		
855
		 * Indicates whether the listener is interested in listening for a
856
		if (middleElementPriority > desiredPriority)
856
		 * global state change.
857
			endIntervalInx = middleInx;
857
		 * 
858
		else if (middleElementPriority < desiredPriority)
858
		 * @return True if the listener's globalStateChange method should be
859
			startIntervalInx = middleInx;
859
		 *         invoke upon a global state change; false otherwise.
860
		else
860
		 */
861
			return middleInx;
861
		public boolean isListenerOn();
862
		return findIndex(desiredPriority, container, startIntervalInx, endIntervalInx, length);
862
863
	}
863
		/**
864
	
864
		 * Invoked when the global state of the macro manager has changed
865
	private int findIndex(int priority, Vector container)
865
		 * 
866
	{
866
		 * @param oldState
867
		int length = container.size();
867
		 *            The old state
868
		return findIndex (priority, container, 0, length, length);
868
		 * @param newState
869
	}
869
		 *            The new state
870
870
		 */
871
	
871
		public void globalStateChange(byte oldState, byte newState);
872
	/**
872
	}
873
	 * Pre-condition:
873
874
	 * <ul>
874
	public int getCommandTimeoutThreshold() {
875
	 * 	<li> To guarantee that this field is not changed while it is being used, it must be locked </li>
875
		return commandTimeoutThreshold;
876
	 * </ul>
876
	}
877
	 *  
877
878
	 * @return The global state of the macro manager. 
878
	public void setCommandTimeoutThreshold(int commandTimeoutThreshold) {
879
	 */
879
		this.commandTimeoutThreshold = commandTimeoutThreshold;
880
	public byte getGlobalState()
880
	}
881
	{	
881
882
		return globalState;
882
	public int getOutstandShellCommands() {
883
	}
883
		return MacroCommandShell.getMacroCommandsBeingPlayed().size();
884
	
884
	}
885
885
886
	public void setGlobalState(byte globalState)
886
	/**
887
	{
887
	 * @return the objectMineOn
888
		synchronized (globalStateLock)
888
	 */
889
		{
889
	public boolean isObjectMineOn() {
890
			byte oldState = this.globalState;
890
		return objectMineOn;
891
			this.globalState = globalState;
891
	}
892
892
893
			if (globalStateListeners != null && oldState != this.globalState)
893
	/**
894
			{
894
	 * @param objectMineOn
895
				for (int i = 0; i < globalStateListeners.size(); i++)
895
	 *            the objectMineOn to set
896
				{
896
	 */
897
					GlobalStateListener gsl = (GlobalStateListener) globalStateListeners.get(i);
897
	public void setObjectMineOn(boolean objectMineOn) {
898
					if (gsl.isListenerOn())
898
		this.objectMineOn = objectMineOn;
899
						gsl.globalStateChange(oldState, this.globalState);
899
	}
900
				}
900
901
901
	public IMacroCommandFactory getMacroCommandFactory() {
902
			}
902
		if (commandFactory == null) {
903
		}
903
			// see if we have a contribution via the macroCommandFactory
904
	}
904
			// extension point
905
	
905
			return MacroCommandFactoryLoader.getHighestPriorityFactory();
906
	public void setGlobalStateWithoutLock(byte globalState)
906
		}
907
	{
907
		return commandFactory;
908
		byte oldState = this.globalState;
908
	}
909
		this.globalState = globalState;
909
910
	
911
		if (globalStateListeners != null && oldState != this.globalState)
912
		{
913
			for (int i = 0; i < globalStateListeners.size(); i++)
914
			{
915
				GlobalStateListener gsl = (GlobalStateListener) globalStateListeners.get(i);
916
				if (gsl.isListenerOn())
917
					gsl.globalStateChange(oldState, this.globalState);
918
			}
919
	
920
		}
921
	}
922
923
	public void setVerListener(VerificationHookListener verHookListener)
924
	{
925
		verificationHooksListener = verHookListener;
926
	}
927
928
	public void removeVerListener()
929
	{
930
		verificationHooksListener = null;
931
	}
932
933
	public void registerGlobalStateListener(GlobalStateListener gsl)
934
	{
935
		if (this.globalStateListeners == null)
936
			this.globalStateListeners = new Vector(2);
937
938
		this.globalStateListeners.add(gsl);
939
	}
940
941
	public void removeGlobalStateListener(GlobalStateListener gsl)
942
	{
943
		if (this.globalStateListeners != null)
944
		{
945
			this.globalStateListeners.remove(gsl);
946
			if (this.globalStateListeners.size() == 0)
947
				this.globalStateListeners = null;
948
		}
949
	}
950
951
	public void setDependecies(Vector dependecies)
952
	{
953
		this.dependecies = dependecies;
954
	}
955
956
	public Vector getDependecies()
957
	{
958
		return this.dependecies;
959
	}
960
961
	public AutoGUIRunner getRunner()
962
	{
963
		return runner;
964
	}
965
966
	public void setRunner(AutoGUIRunner runner)
967
	{
968
		this.runner = runner;
969
	}
970
	
971
	
972
	/**
973
	 * This method is invoked to toggle the position based recording option on or off.
974
	 * Turning on position based recording will only record position-based commands. 
975
	 * This is only recommended where object based recording cannot be used. (e.g. User
976
	 * clicking at a specific location of a canvas)
977
	 * 
978
	 * @param state True indicates that position based recording should be turned on and false indicates
979
	 * that it should be turned off
980
	 * 
981
	 * @return true if operation is successful; false otherwise
982
	 */
983
	public synchronized boolean togglePositionBasedRec(boolean state) 
984
	{
985
	
986
		synchronized (globalStateLock)
987
		{
988
			Display currentDisplay = PlatformUI.getWorkbench().getDisplay();
989
			
990
			/* We're required to turn on position based recoridng */
991
			if (state)
992
			{
993
				if (currentDisplay != null)
994
				{
995
					unhookListeners(currentDisplay);
996
					hookPositionBasedListeners(currentDisplay);
997
					
998
					globalState = POSITION_BASED_REC_MODE;
999
				}
1000
				else 
1001
					return false;
1002
			}
1003
			/* Otherwise turn the option off */
1004
			else if (!state)
1005
			{
1006
				if (currentDisplay != null)
1007
				{
1008
					unhookPositionBasedListeners(currentDisplay);
1009
					hookListeners(currentDisplay);
1010
					
1011
					globalState = RECORDING_MODE;
1012
				}
1013
				else
1014
					return false;
1015
			}
1016
				
1017
		}
1018
		
1019
		return true;
1020
		
1021
	}
1022
	
1023
	public boolean isArtificialWaitOn() 
1024
	{
1025
		return artificialWaitOn;
1026
	}
1027
1028
	public void setArtificialWaitOn(boolean artificialWaitOn) 
1029
	{
1030
		this.artificialWaitOn = artificialWaitOn;
1031
	}
1032
	
1033
	
1034
	/**
1035
	 * @return the objectMine
1036
	 */
1037
	public IObjectMine getObjectMine()
1038
	{
1039
		return objectMine;
1040
	}
1041
1042
	/**
1043
	 * @param objectMine the objectMine to set
1044
	 */
1045
	public void setObjectMine(IObjectMine objectMine)
1046
	{
1047
		this.objectMine = objectMine;
1048
	}
1049
	
1050
	
1051
	/**
1052
	 * Used to register classes as listeners that are awaiting the creation of a VerificationCommand
1053
	 * from a focus command of an editor or a viewer.
1054
	 * 
1055
	 * @author Ali Mehregani
1056
	 */
1057
	public interface VerificationHookListener
1058
	{
1059
		/**
1060
		 * Reports any error while attempting to construct object
1061
		 * 
1062
		 * @param error A descriptive error message 
1063
		 */
1064
		public void error(String error);
1065
1066
		/**
1067
		 * Invoked when there is an instance ready
1068
		 * 
1069
		 * @param verificationCommand The instance of verification command created as a result of an event.
1070
		 */
1071
		public void instanceReady(VerificationCommand verificationCommand);
1072
	}
1073
1074
	/**
1075
	 * A gateway for client to determine the global state changes of the macro recorder.
1076
	 * 
1077
	 * @author amehregani
1078
	 */
1079
	public interface GlobalStateListener
1080
	{
1081
		/**
1082
		 * Indicates whether the listener is interested in listening 
1083
		 * for a global state change.
1084
		 * 
1085
		 * @return True if the listener's globalStateChange method should be
1086
		 * invoke upon a global state change; false otherwise.
1087
		 */
1088
		public boolean isListenerOn();
1089
1090
		/**
1091
		 * Invoked when the global state of the macro manager has changed
1092
		 * 
1093
		 * @param oldState The old state
1094
		 * @param newState The new state
1095
		 */
1096
		public void globalStateChange(byte oldState, byte newState);
1097
	}
1098
1099
	public int getCommandTimeoutThreshold() {
1100
		return commandTimeoutThreshold;
1101
	}
1102
1103
	public void setCommandTimeoutThreshold(int commandTimeoutThreshold) {
1104
		this.commandTimeoutThreshold = commandTimeoutThreshold;
1105
	}
1106
	
1107
	public int getOutstandShellCommands()
1108
	{
1109
		return MacroCommandShell.getMacroCommandsBeingPlayed().size();
1110
	}
1111
1112
	/**
1113
	 * @return the objectMineOn
1114
	 */
1115
	public boolean isObjectMineOn()
1116
	{
1117
		return objectMineOn;
1118
	}
1119
1120
	/**
1121
	 * @param objectMineOn the objectMineOn to set
1122
	 */
1123
	public void setObjectMineOn(boolean objectMineOn)
1124
	{
1125
		this.objectMineOn = objectMineOn;
1126
	}
1127
1128
1129
	
1130
}
910
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroObjectLocator.java (-916 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.ArrayList;
14
import java.util.Enumeration;
15
import java.util.Hashtable;
16
import java.util.Iterator;
17
import java.util.Vector;
18
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.jface.action.CoolBarManager;
23
import org.eclipse.jface.action.IContributionItem;
24
import org.eclipse.jface.action.ICoolBarManager;
25
import org.eclipse.jface.action.IMenuManager;
26
import org.eclipse.jface.action.IToolBarManager;
27
import org.eclipse.jface.action.MenuManager;
28
import org.eclipse.jface.action.ToolBarContributionItem;
29
import org.eclipse.jface.action.ToolBarManager;
30
import org.eclipse.jface.window.ApplicationWindow;
31
import org.eclipse.jface.window.Window;
32
import org.eclipse.jface.wizard.IWizardPage;
33
import org.eclipse.jface.wizard.WizardDialog;
34
import org.eclipse.osgi.util.NLS;
35
import org.eclipse.swt.SWT;
36
import org.eclipse.swt.widgets.Composite;
37
import org.eclipse.swt.widgets.Control;
38
import org.eclipse.swt.widgets.Decorations;
39
import org.eclipse.swt.widgets.Event;
40
import org.eclipse.swt.widgets.Item;
41
import org.eclipse.swt.widgets.Menu;
42
import org.eclipse.swt.widgets.MenuItem;
43
import org.eclipse.swt.widgets.Shell;
44
import org.eclipse.swt.widgets.ToolBar;
45
import org.eclipse.swt.widgets.ToolItem;
46
import org.eclipse.swt.widgets.Widget;
47
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
48
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
49
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
50
import org.eclipse.tptp.test.auto.gui.internal.commands.CommandTarget;
51
import org.eclipse.tptp.test.auto.gui.internal.commands.EditorCommandTarget;
52
import org.eclipse.tptp.test.auto.gui.internal.commands.ViewCommandTarget;
53
import org.eclipse.tptp.test.auto.gui.internal.commands.WindowCommandTarget;
54
import org.eclipse.tptp.test.auto.gui.internal.commands.WizardCommandTarget;
55
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
56
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
57
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader;
58
import org.eclipse.ui.IActionBars;
59
import org.eclipse.ui.IEditorPart;
60
import org.eclipse.ui.IEditorReference;
61
import org.eclipse.ui.IViewPart;
62
import org.eclipse.ui.IViewSite;
63
import org.eclipse.ui.IWorkbenchPage;
64
import org.eclipse.ui.IWorkbenchPart;
65
import org.eclipse.ui.IWorkbenchWindow;
66
import org.eclipse.ui.PartInitException;
67
import org.eclipse.ui.testing.IWorkbenchPartTestable;
68
import org.w3c.dom.Node;
69
70
/**
71
 * A utility class used to locate different objects needed when playing back 
72
 * commands.
73
 * 
74
 * @author Ali Mehregani
75
 */
76
public class MacroObjectLocator
77
{
78
79
	public static CommandTarget[] locateCommandTarget(Composite parent, WidgetIdentifier wid, ArrayList parents, int line) throws CoreException
80
	{
81
		Shell shell = (Shell) parent;
82
		
83
		IPath contextId = wid.getContextId();
84
		
85
		String firstToken = contextId.segment(0);		
86
		Iterator iter = parents != null ? parents.iterator() : null;
87
		String id = contextId.segment(1);
88
		
89
		if (MacroConstants.MENUS_VALUE.equals(firstToken))
90
		{
91
			return new CommandTarget[]{locateMenuBarItem(shell, wid, iter, line)};
92
		}
93
		else if (MacroConstants.POPUP_VALUE.equals(firstToken))
94
		{
95
			return new CommandTarget[]{ locatePopupMenuItem(shell, wid, iter, line)};
96
		}
97
		else if (MacroConstants.TOOLBAR_VALUE.equals(firstToken))
98
		{
99
			return new CommandTarget[]{ locateToolItem(shell, wid, line)};
100
		}
101
		else if (MacroConstants.LOCAL_TOOLBAR_VALUE.equals(firstToken))
102
		{
103
			return new CommandTarget[]{ locateLocalToolItem(shell, wid, line)};
104
		}
105
		else if (MacroConstants.LOCAL_TOOLBAR_MENU_VALUE.equals(firstToken))
106
		{
107
			return new CommandTarget[] {locateToolBarMenuItem(shell, wid, line)};
108
		}
109
		else if (MacroConstants.WIZARD_VALUE.equals(firstToken))
110
		{
111
			return locateWizardControl(shell, wid, line);
112
		}
113
		else if (MacroConstants.SHELL_VALUE.equals(firstToken))
114
		{
115
			return locateShellControl(shell, wid, line);
116
		}		
117
		else if (MacroConstants.WIZARD_PAGE_VALUE.equals(firstToken))
118
		{
119
			return locateWizardPageControl(shell, id, wid, line);
120
		}
121
		else if (MacroConstants.VIEW_VALUE.equals(firstToken))
122
		{
123
			return locateViewControl(shell, id, wid, line);
124
		}
125
		else if (MacroConstants.EDITOR_VALUE.equals(firstToken))
126
		{
127
			String inputName = contextId.segment(2);
128
			return locateEditorControl(shell, id, inputName, wid, line);
129
		}
130
		
131
		
132
		return null;
133
	}
134
135
	public static CommandTarget[] locateCommandTarget(Composite parent, WidgetIdentifier wid, int line) throws CoreException
136
	{
137
		return locateCommandTarget(parent, wid, null, line);
138
	}
139
140
	/**
141
	 * Used to located the editor part with the passed id.
142
	 * 
143
	 * @param shell
144
	 *            The current shell
145
	 * @param id
146
	 *            The id of the editor part
147
	 * @param line
148
	 *            The line number of the script (used to indicate the line
149
	 *            number if we throw a core exception. Mark as -1 if a script is
150
	 *            not being used)
151
	 * @param input
152
	 *            If not null, then it attempts to match the input of the
153
	 *            identified editor with the input that is passed it.
154
	 * 
155
	 * @return The editor part with the passed 'id'
156
	 * 
157
	 * @throws CoreException
158
	 *             If the editor part cannot be located.
159
	 */
160
	public static IEditorPart locateEditor(Shell shell, String id, int line, String input) throws CoreException
161
	{
162
		Object data = shell.getData();
163
		IEditorPart editor = null;
164
	
165
		try
166
		{
167
			if (data instanceof IWorkbenchWindow)
168
			{
169
				IWorkbenchWindow window = (IWorkbenchWindow) data;
170
				IWorkbenchPage page = window.getActivePage();
171
	
172
				if (page != null)
173
				{
174
					IEditorReference[] erefs = page.getEditorReferences();
175
	
176
					for (int i = 0; i < erefs.length; i++)
177
					{
178
						IEditorReference eref = erefs[i];
179
						if (eref.getId().equals(id))
180
						{
181
							// check the input
182
							IEditorPart part = eref.getEditor(true);
183
							if (input == null)
184
							{
185
								editor = part;
186
								break;
187
							}
188
							else if (part.getEditorInput().getName().equals(input))
189
							{
190
								editor = part;
191
								break;
192
							}							
193
						}
194
					}
195
				}
196
			}
197
		}
198
		catch (Throwable t)
199
		{
200
			
201
		}
202
		if (editor != null)
203
		{			
204
			editor.getSite().getPage().activate(editor);
205
			return editor;
206
		}
207
	
208
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR, id), line);
209
		return null;
210
	}
211
212
	private static EditorCommandTarget[] locateEditorControl(Shell shell, String id, String inputName, WidgetIdentifier wid, int line) throws CoreException
213
	{
214
		Control[] controls = null;
215
		
216
		try
217
		{			
218
			IEditorPart editor = locateEditor(shell, id, line, inputName);
219
	
220
			if (editor != null)
221
			{
222
				Composite c = getWorkbenchPartControl(editor);
223
				controls = locateVisibleChild(c, null, wid);
224
				if (controls != null)
225
				{
226
					EditorCommandTarget[] editorCommandTargets = new EditorCommandTarget[controls.length];
227
					for (int i = 0; i < controls.length; i++)
228
					{
229
						editorCommandTargets[i] = new EditorCommandTarget(controls[i], editor);
230
					}
231
					
232
					return editorCommandTargets;
233
				}
234
			}
235
		}
236
		catch (Throwable t)
237
		{
238
			t.printStackTrace();
239
		}
240
		if (controls == null)
241
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR_CON, wid.getObjectId().toString()), line);
242
	
243
		return null;
244
	}
245
246
	private static CommandTarget locateLocalToolItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException
247
	{
248
		try
249
		{			
250
			IPath wpath = wid.getContextId().removeFirstSegments(1);
251
			String firstToken = wpath.segment(0);
252
			IWorkbenchPart workbenchPart = null;
253
			Composite parent = null;
254
			CommandTarget target = null;
255
			
256
			if (MacroConstants.VIEW_VALUE.equals(firstToken))
257
			{
258
				String id = wpath.segment(1);
259
				workbenchPart = locateView(shell, id, line);
260
			}
261
			else if (MacroConstants.EDITOR_VALUE.equals(firstToken))
262
			{
263
				String id = wpath.segment(1);
264
				workbenchPart = locateEditor(shell, id, line, null);
265
			}
266
			else if (MacroConstants.SHELL_VALUE.equals(firstToken))
267
			{
268
				parent = shell;
269
			}
270
			
271
			if (workbenchPart != null)
272
			{
273
				Composite comp = getWorkbenchPartControl(workbenchPart);
274
				MacroUtil.processDisplayEvents(shell.getDisplay());
275
				parent = comp.getParent();
276
			}
277
			
278
			if (parent != null)
279
			{
280
				WidgetIdentifier widgetIdentifier = new WidgetIdentifier(wid.getContextId(), new Path(wid.getContextId().lastSegment()), wid.getResolverId());
281
				Control[] controls = locateVisibleChild(parent, null, widgetIdentifier);
282
				if (controls != null && controls.length > 0 && controls[0] instanceof ToolBar)
283
				{
284
					target = locateToolItem((ToolBar)controls[0], wid, line);
285
				}				
286
			}
287
			
288
			if (target != null)
289
				return target;
290
			
291
		}
292
		catch (Throwable t)
293
		{
294
			/* The next line will throw an exception */
295
			t.printStackTrace();
296
		}
297
		
298
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR, wid.getFullyQualifiedId().toString()), line);
299
		return null;
300
	}
301
302
	private static CommandTarget locateMenuBarItem(Shell shell, WidgetIdentifier wid, Iterator parents, int line) throws CoreException
303
	{
304
		try
305
		{
306
			MenuItem item = null;
307
			Object data = shell.getData();
308
			Menu menuBar = shell.getMenuBar();
309
	
310
			if (data instanceof ApplicationWindow && parents != null)
311
			{
312
				ApplicationWindow window = (ApplicationWindow) data;
313
				MenuManager manager = window.getMenuBarManager();
314
				item = locateMenuItem(manager, wid.getResolverId(), wid.getObjectId().toString(), parents, line);
315
			}
316
			else
317
			{
318
				item = locateMenuItem(menuBar, wid.getResolverId(), wid.getObjectId().toString(), line);
319
			}
320
			if (item != null)
321
				return new CommandTarget(item, menuBar);
322
			
323
		}
324
		catch (Throwable t)
325
		{
326
			/* The next line will throw exception */			
327
		}
328
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line);
329
		return null;
330
	}
331
332
	private static MenuItem locateMenuItem(Menu menu, String resolverId, String id, int line)
333
	{
334
		MenuItem[] items = menu.getItems();
335
	
336
		for (int i = 0; i < items.length; i++)
337
		{
338
			MenuItem item = items[i];
339
	
340
			Menu submenu = item.getMenu();
341
			if (submenu != null)
342
			{
343
				/* Ali M.: We have to force the menu to open, since its items may not have already been created */
344
				forceMenuOpen(null, submenu);
345
				MenuItem hit = locateMenuItem(submenu, resolverId, id, line);
346
				if (hit != null)
347
					return hit;
348
			}
349
			else
350
			{
351
				if (foundItem(item, resolverId, id))
352
					return item;
353
			}
354
		}
355
		return null;
356
	}
357
358
	
359
	private static MenuItem locateMenuItem(MenuManager mng, String resolverId, String id, Iterator parents, int line)
360
	{
361
		IContributionItem[] items = mng.getItems();
362
	
363
		String parentId = null;
364
		if (parents.hasNext())
365
			parentId = (String) parents.next();
366
	
367
		for (int i = 0; i < items.length; i++)
368
		{
369
			IContributionItem citem = items[i];
370
	
371
			if (citem instanceof MenuManager)
372
			{
373
				MenuManager submenu = (MenuManager) citem;
374
				String subId = submenu.getId();
375
	
376
				if (subId.equals(parentId))
377
				{
378
					// show this menu to force dynamic items
379
					// to show
380
					Menu menu = submenu.getMenu();
381
					forceMenuOpen(null, menu);
382
	
383
					MenuItem hit = locateMenuItem(submenu, resolverId, id, parents, line);
384
					forceMenuClosed(menu);
385
					if (hit != null)
386
						return hit;
387
				}
388
			}
389
			else
390
			{
391
				/* Ali M.: I believe that the first line and the following block were for optimization purposes only */
392
				//String itemId = getActionId(citem);
393
				//if (itemId != null && id.equals(itemId))
394
				//{
395
				MenuItem hit = locateMenuItem(mng.getMenu(), resolverId, id, line);
396
				if (hit != null)
397
					return hit;
398
				//}
399
			}
400
		}
401
		return null;
402
	}
403
404
	private static CommandTarget locatePopupMenuItem(Shell shell, WidgetIdentifier wid, Iterator parents, int line) throws CoreException
405
	{
406
		try
407
		{
408
			IPath contextPath = wid.getContextId().removeFirstSegments(1);
409
			IPath wpath = new Path(getLastSegment(contextPath));
410
			
411
			int widgetPathInx = contextPath.toString().indexOf(wpath.toString());
412
			if (widgetPathInx > 0)
413
				contextPath = new Path(contextPath.toString().substring(0, widgetPathInx - 1));
414
			CommandTarget[] targets = locateCommandTarget(shell, new WidgetIdentifier(contextPath, wpath, null), line);
415
			if (targets != null)
416
			{
417
				for (int i = 0; i < targets.length; i++)
418
				{
419
					Control control = (Control) targets[i].getWidget();
420
					Menu popupMenu = control.getMenu();
421
					if (popupMenu != null)
422
					{
423
						forceMenuOpen(control, popupMenu);
424
						MenuItem menuItem = locateMenuItem(popupMenu, wid.getResolverId(), wid.getObjectId().toString(), line);
425
						forceMenuClosed(popupMenu);
426
						if (menuItem != null)
427
						{
428
							return new CommandTarget(menuItem, control);
429
						}
430
					}
431
				}
432
			}
433
		}
434
		catch (Throwable t)
435
		{
436
			/* The next line will throw an exception */			
437
		}
438
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line);
439
		return null;
440
	}
441
442
	private static CommandTarget locateToolBarMenuItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException
443
	{
444
		try
445
		{
446
			IPath contextPath = wid.getContextId().removeFirstSegments(1);
447
			
448
			/* The context is a menu */
449
			IViewPart viewPart = null;
450
			if (MacroConstants.VIEW_VALUE.equals(contextPath.segment(0)))
451
			{
452
				viewPart = locateView(shell, contextPath.segment(1), line);
453
			}
454
455
			
456
			IViewSite viewSite = viewPart == null ? null : viewPart.getViewSite();
457
			IMenuManager menuManager = null;
458
			if (viewSite != null)
459
			{
460
				IActionBars actionBar = viewSite.getActionBars();
461
				actionBar.updateActionBars();
462
				menuManager = actionBar.getMenuManager();
463
			}
464
			
465
			if (menuManager instanceof MenuManager)
466
			{
467
				
468
				Menu menu = ((MenuManager)menuManager).getMenu();
469
				if (menu == null)
470
				{
471
					menu = ((MenuManager)menuManager).createMenuBar((Decorations)shell);
472
				}
473
				if (menu != null)
474
				{
475
					forceMenuOpen(null, menu);
476
					MenuItem menuItem = locateMenuItem(menu, wid.getResolverId(), wid.getObjectId().toString(), line);
477
					forceMenuClosed(menu);
478
					if (menuItem != null)
479
					{
480
						return new CommandTarget(menuItem, null);
481
					}
482
				}
483
			}
484
		}
485
		catch (Throwable t)
486
		{
487
			/* The next line will throw an exception */			
488
		}
489
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid.getObjectId().toString()), line);
490
		return null;
491
	}
492
	private static String getLastSegment(IPath contextPath)
493
	{
494
		String[] segments = contextPath.segments();
495
		String candidate = "";
496
		for (int i = segments.length - 1; i >= 0; i--)
497
		{
498
			if (candidate.length() > 0)
499
				candidate = "/" + candidate;
500
			candidate = segments[i] + candidate;
501
			int openingBracesInx = candidate.indexOf('{');
502
			int closingBracesInx = candidate.indexOf('}');
503
			if ((openingBracesInx == -1 && closingBracesInx == -1) || (openingBracesInx >= 0 && openingBracesInx < closingBracesInx))
504
				return candidate;
505
		}
506
		
507
		return "";
508
	}
509
	
510
	private static WindowCommandTarget[] locateShellControl(Shell shell, WidgetIdentifier wid, int line) throws CoreException
511
	{
512
		Control[] controls = null;
513
		Window window = null;
514
		try
515
		{
516
			window = (Window) shell.getData();
517
			controls = locateVisibleChild(shell, null, wid);
518
		}
519
		catch (Throwable t)
520
		{
521
			
522
		}
523
		if (controls == null)
524
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL, wid.getObjectId().toString()), line);
525
		
526
		WindowCommandTarget[] windowCommandTarget = new WindowCommandTarget[controls.length];
527
		for (int i = 0; i < controls.length; i++)
528
		{
529
			if (controls[i].isDisposed())
530
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid.getObjectId().toString()), line);
531
			windowCommandTarget[i] = new WindowCommandTarget(controls[i], window);
532
		}
533
			
534
		return windowCommandTarget;
535
	}
536
537
	private static CommandTarget locateToolItem(ICoolBarManager coolMng, WidgetIdentifier wid, int line)
538
	{
539
		IContributionItem[] items = coolMng.getItems();
540
		for (int i = 0; i < items.length; i++)
541
		{
542
			if (items[i] instanceof ToolBarContributionItem)
543
			{
544
				ToolBarContributionItem item = (ToolBarContributionItem) items[i];
545
				IToolBarManager toolMng = item.getToolBarManager();
546
				CommandTarget target = locateToolItem((ToolBarManager) toolMng, wid, line);
547
				if (target != null)
548
					return target;
549
			}
550
		}
551
		return null;
552
	}
553
	
554
	private static CommandTarget locateToolItem(ToolBarManager toolMng, WidgetIdentifier wid, int line)
555
	{
556
		return locateToolItem(toolMng.getControl(), wid, line);
557
	}
558
	
559
560
	private static CommandTarget locateToolItem(Shell shell, WidgetIdentifier wid, int line) throws CoreException
561
	{
562
		CommandTarget target = null;
563
		try
564
		{
565
			Object data = shell.getData();			
566
			if (data instanceof ApplicationWindow)
567
			{
568
				ApplicationWindow window = (ApplicationWindow) data;
569
				CoolBarManager coolMng = window.getCoolBarManager();
570
				if (coolMng != null)
571
				{
572
					target = locateToolItem(coolMng, wid, line);
573
				}
574
				ToolBarManager toolMng = window.getToolBarManager();
575
				if (toolMng != null)
576
				{
577
					target = locateToolItem(toolMng, wid, line);
578
				}
579
			}
580
		}
581
		catch (Throwable t)
582
		{
583
			/* The next line will throw an exception */
584
			target = null;
585
		}
586
		if (target == null)
587
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL, wid.getObjectId().toString()), line);
588
		return target;
589
	}
590
591
	private static CommandTarget locateToolItem(ToolBar toolBar, WidgetIdentifier wid, int line)
592
	{
593
		if (toolBar == null)
594
			return null;
595
		ToolItem[] items = toolBar.getItems();
596
		for (int i = 0; i < items.length; i++)
597
		{
598
			ToolItem item = items[i];
599
			if (foundItem(item, wid.getResolverId(), wid.getObjectId().toString()))
600
				return new CommandTarget(item, toolBar);
601
		}
602
		return null;
603
	}
604
605
606
	/**
607
	 * Used to located the view part with the passed id.
608
	 * 
609
	 * @param shell
610
	 *            The current shell
611
	 * @param id
612
	 *            The id of the view part
613
	 * @param line
614
	 *            The line number of the script (used to indicate the line
615
	 *            number if we throw a core exception. Mark as -1 if a script is
616
	 *            not being used)
617
	 * 
618
	 * @return The view part with the passed 'id'
619
	 * 
620
	 * @throws CoreException
621
	 *             If the view part cannot be located.
622
	 */
623
	public static IViewPart locateView(Shell shell, String id, int line) throws CoreException
624
	{
625
		try
626
		{
627
			Object data = shell.getData();
628
	
629
			if (data instanceof IWorkbenchWindow)
630
			{
631
				IWorkbenchWindow window = (IWorkbenchWindow) data;				
632
				IWorkbenchPage page = window.getActivePage();
633
				if (page != null)
634
				{
635
					IViewPart view = page.findView(id);
636
				
637
					if (view == null)
638
					{
639
						try
640
						{
641
							view = page.showView(id);
642
							
643
						}
644
						catch (PartInitException pie)
645
						{
646
							/* Do a thorough search */												
647
							IWorkbenchWindow[] windows = GuiPlugin.getDefault().getWorkbench().getWorkbenchWindows();
648
							
649
							/* For every workbench window */
650
							for (int i = 0; i < windows.length && view == null; i++)
651
							{
652
								/* For every page of a workbench window */
653
								IWorkbenchPage[] pages = windows[i].getPages();
654
								for (int j = 0; j < pages.length && view == null; j++)
655
								{
656
									view = pages[j].findView(id);
657
									
658
								}
659
							}
660
							//need to mke sure that even if it is found in another page, we show it.
661
							
662
						}
663
				}
664
					// added for defcet 175320 in order to ensure the page is 
665
					//given focus no matter where it is found
666
					page.showView(id);
667
					return view;
668
				}
669
		}
670
		}
671
		catch (Throwable t)
672
		{
673
			/* The next line will throw an exception */
674
		}
675
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW, id), line);
676
		return null;
677
	}
678
679
	private static ViewCommandTarget[] locateViewControl(Shell shell, String id, WidgetIdentifier wid, int line) throws CoreException
680
	{
681
		Control[] controls = null;
682
		try
683
		{
684
			IViewPart view = locateView(shell, id, line);
685
			if (view != null)
686
			{
687
				Composite c = getWorkbenchPartControl(view);
688
				controls = locateVisibleChild((Composite) c, null, wid);
689
				// controls will never be null but might be empty
690
				// This way the error is caught here and will reflect the view not found
691
				if (controls.length >0)
692
				{
693
					ViewCommandTarget[] viewCommandTarget = new ViewCommandTarget[controls.length];
694
					for (int i = 0; i < controls.length; i++)
695
					{
696
						viewCommandTarget[i] = new ViewCommandTarget(controls[i], view);
697
					}
698
					return viewCommandTarget;
699
				}
700
			}
701
		}
702
		catch (Throwable t)
703
		{
704
			
705
		}
706
		AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW_CON, wid.getObjectId().toString()), line);
707
		return null;
708
	}
709
710
	private static Control[] locateVisibleChild(Composite parent, Composite skip, WidgetIdentifier widgetId)
711
	{
712
		int[] counter = new int[1];
713
		counter[0] = 0;
714
		String wid = widgetId.getObjectId().toString();
715
		int sloc = wid.indexOf('#');
716
		String wclassName = null;
717
		if (sloc != -1)
718
			wclassName = wid.substring(0, sloc);
719
		
720
		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: We need to return all possible matches */
721
		Vector matches = new Vector();
722
		Vector indices = new Vector();
723
		locateVisibleChild(parent, skip, widgetId, wclassName, counter, matches, indices);
724
		Control[] matchedControls = new Control[matches.size()];
725
		matches.toArray(matchedControls);
726
		return matchedControls;
727
	}
728
729
	private static Control locateVisibleChild(Composite parent, Composite skip, WidgetIdentifier id, String wclassName, int[] index, Vector matches, Vector indices)
730
	{
731
		return MacroUtil.recursiveSearch(parent, skip, null, id, wclassName, index, matches, indices);
732
	}
733
734
	private static WizardCommandTarget[] locateWizardControl(Shell shell, WidgetIdentifier wid, int line) throws CoreException
735
	{
736
		WizardDialog wdialog  = null;
737
		Control[] controls  = null;
738
		try
739
		{
740
			wdialog = (WizardDialog) shell.getData();
741
			IWizardPage page = wdialog.getCurrentPage();
742
			Composite pparent = (Composite) page.getControl();
743
			controls = locateVisibleChild(shell, pparent, wid);
744
		}
745
		catch (Throwable t)
746
		{
747
			
748
		}
749
		if (controls == null)
750
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD, wid.getObjectId().toString()), line);
751
		
752
		WizardCommandTarget[] wizardCommandTarget = new WizardCommandTarget[controls.length];
753
		for (int i = 0; i < controls.length; i++)
754
		{
755
			if (controls[i].isDisposed())
756
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid.getObjectId().toString()), line);
757
			wizardCommandTarget[i] = new WizardCommandTarget(controls[i], wdialog);
758
		}
759
			
760
		return wizardCommandTarget;		
761
	}
762
763
	private static WizardCommandTarget[] locateWizardPageControl(Shell shell, String id, WidgetIdentifier wid, int line) throws CoreException
764
	{
765
		Control[] controls = null;
766
		try
767
		{
768
			Object data = shell.getData();
769
			if (data instanceof WizardDialog)
770
			{
771
				WizardDialog wdialog = (WizardDialog) data;
772
				IWizardPage page = wdialog.getCurrentPage();
773
				// assert page
774
				// if (pname.equals(id)==false)
775
				// throwCoreException("Unexpected wizard page: "+pname+", expected
776
				// "+id, line);
777
				Composite pparent = (Composite) page.getControl();
778
				controls = locateVisibleChild(pparent, null, wid);
779
				if (controls != null)
780
				{
781
					WizardCommandTarget[] wizardCommandTarget = new WizardCommandTarget[controls.length];
782
					for (int i = 0; i < controls.length; i++)
783
					{
784
						wizardCommandTarget[i] = new WizardCommandTarget(controls[i], wdialog);
785
					}
786
					return wizardCommandTarget;
787
				}
788
			}
789
		}
790
		catch (Throwable t)
791
		{
792
			
793
		}
794
		if (controls == null)
795
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD_CON, wid.getObjectId().toString()), line);
796
		return null;
797
	}
798
		
799
	private static void forceMenuOpen(Control c, Menu menu)
800
	{
801
		Event e = new Event();
802
		e.type = SWT.Show;
803
		e.widget = menu;
804
805
		menu.notifyListeners(e.type, e);
806
		MacroUtil.processDisplayEvents(menu.getDisplay());
807
	}
808
809
	private static void forceMenuClosed(Menu menu)
810
	{
811
		Event e = new Event();
812
		e.type = SWT.Hide;
813
		e.widget = menu;
814
		
815
		menu.notifyListeners(e.type, e);
816
		MacroUtil.processDisplayEvents(menu.getDisplay());
817
	}	
818
	
819
	
820
	/**
821
	 * If the node passed in has a reference id, then this method looks up the id in 
822
	 * the object mine and attempts to find the object that is referenced.
823
	 * 
824
	 * @param node Represents the XML node
825
	 * @param lineTable Contains line level information
826
	 * 
827
	 * @return A String[] of length 2, where String[0] = context id and String[1] = object
828
	 * id.  If the node does not have a reference id, then null is returned.
829
	 * 
830
	 * @throws CoreException If the node contains a reference id attribute but the 
831
	 * corresponding object mine does not have any such object.
832
	 */
833
	public static IUIObject lookupReferenceId(IUIObject parent, Node node, Hashtable lineTable) throws CoreException
834
	{
835
		String referenceId =  MacroUtil.getAttribute(node, MacroConstants.REFERENCE_ID_ATTRIBUTE);
836
		if (referenceId == null)
837
			return null;
838
		
839
		IUIObject correspondingObject = MacroManager.getInstance().getObjectMine().lookupUIObject(parent, referenceId);
840
		if (correspondingObject == null)
841
		{
842
			Integer[] lineLevelDetail = (Integer[]) lineTable.get(node);
843
			AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, referenceId), lineLevelDetail == null ? 0 : lineLevelDetail[0].intValue());
844
		}
845
		else
846
		{
847
			return correspondingObject;
848
		}
849
		
850
		/* Code not reached beyond this point */
851
		return null;
852
	}
853
	
854
	
855
	/**
856
	 * We have to use internal APIs here to get the controls of a part
857
	 */
858
	public static Composite getWorkbenchPartControl (IWorkbenchPart part)
859
	{
860
		IWorkbenchPartTestable testable = (IWorkbenchPartTestable)part.getSite().getAdapter(IWorkbenchPartTestable.class);
861
		return testable.getControl().getParent();
862
	}
863
	
864
	/**
865
	 * Returns true if the id computed for 'item' matches 'id'
866
	 * 
867
	 * @param item The tool item
868
	 * @param resolverId The resolver id -- can be null
869
	 * @param id The id that should be matched against
870
	 * @return true if there is a match, and false otherwise
871
	 */
872
	public static boolean foundItem(Item item, String resolverId, Object id) 
873
	{
874
		/* Try the widget resolvers first */
875
		if (foundWidget(item, resolverId, id))
876
			return true;
877
		
878
		/* Give the old policy a try */
879
		String toolItemIdStr = MacroUtil.getActionId(item).toString();
880
		if (toolItemIdStr != null && toolItemIdStr.equals(id))
881
			return true;
882
		
883
		return false;
884
	}
885
886
	/**
887
	 * Returns true iff the widget matches the id passed in.
888
	 * 
889
	 * @param widget The widget
890
	 * @param resolverId The resolver id -- can be null
891
	 * @param id The id
892
	 * @return true iff the widget matches the id passed in.
893
	 */
894
	public static boolean foundWidget(Widget widget, String resolverId, Object id)
895
	{			
896
		MacroManager macroManager = MacroManager.getInstance();
897
		Hashtable widgetResolvers = macroManager.getWidgetResolvers();
898
		
899
		if (resolverId != null)
900
		{
901
			WidgetResolverLoader loader = (WidgetResolverLoader)widgetResolvers.get(resolverId);
902
			if (loader != null)
903
				return loader.getWidgetResolver().foundWidget(widget, id);
904
			return false;
905
		}
906
		
907
		Enumeration keys = widgetResolvers.keys();
908
		while (keys.hasMoreElements())
909
		{
910
			if (((WidgetResolverLoader)widgetResolvers.get(keys.nextElement())).getWidgetResolver().foundWidget(widget, id))
911
				return true;
912
		}		
913
		return false;
914
	}
915
916
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/ObjectMineManager.java (-395 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.io.ByteArrayInputStream;
14
import java.io.IOException;
15
import java.util.Hashtable;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
21
import org.eclipse.emf.common.util.URI;
22
import org.eclipse.emf.ecore.EObject;
23
import org.eclipse.emf.ecore.resource.Resource;
24
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
25
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
26
import org.eclipse.hyades.test.core.util.EMFUtil;
27
import org.eclipse.osgi.util.NLS;
28
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
29
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
30
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
31
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
32
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
33
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException;
34
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound;
35
import org.w3c.dom.NamedNodeMap;
36
import org.w3c.dom.Node;
37
import org.w3c.dom.NodeList;
38
import org.xml.sax.SAXException;
39
40
41
/**
42
 * In addition to the macro of each test case, a test suite also contains an object
43
 * mine keeps a reference of all resolved objects.  The purpose of the object mine
44
 * is to resolve a widget once and use it many times. 
45
 * <p/>
46
 * This is a singleton class that can be accessed via <code>getInstance()</code>
47
 * <p/>
48
 * 
49
 * 
50
 * @author  Ali Mehregani
51
 * @author  Paul E. Slauenwhite
52
 * @version March 7, 2008
53
 * @since   July 10, 2006
54
 */
55
public class ObjectMineManager 
56
{	
57
	/** The instance of this class */
58
	private static ObjectMineManager instance = new ObjectMineManager();
59
		
60
	
61
	/** Cached object mines 
62
	 * KEY = Test suite id
63
	 * VALUE = An object of type IObjectMine that represents the object mine of the test suite */	
64
	private Hashtable cachedObjectMines;
65
	
66
	
67
	/** Indicates whether a test suite's object mine is dirty or not
68
	 * KEY = test suite id
69
	 * VALUE = Boolean.TRUE if object mine is dirty; Boolean.FALSE otherwise  
70
	 */
71
	private Hashtable dirtyStateTable;
72
	
73
	
74
	/**
75
	 * Restrict the visibility of the constructor
76
	 */
77
	private ObjectMineManager()
78
	{
79
		cachedObjectMines = new Hashtable();
80
		dirtyStateTable = new Hashtable();
81
	}
82
	
83
	
84
	/**
85
	 * Return the instance of this singleton class
86
	 * 
87
	 * @return The instance of this class
88
	 */
89
	public static ObjectMineManager getInstance()
90
	{
91
		return instance;
92
	}
93
	
94
	
95
	/**
96
	 * Load the object mine of the passed in test suite
97
	 * 
98
	 * @param testSuite The test suite whose object mine is requested
99
	 * @param useCache Uses the cached value if this is set to true; otherwise the
100
	 * object mine is reloaded and returned.
101
	 * 
102
	 * @return the object mine of the test suite that is passed in.
103
	 * 
104
	 * @throws UIObjectNotFound In case an expected object is not found
105
	 * @throws IDCollisionException  In case there is a collision id
106
	 * @throws CoreException In case of any unexpected error
107
	 */
108
	public IObjectMine loadObjectMine (ITestSuite testSuite, boolean useCache) throws UIObjectNotFound, IDCollisionException, CoreException
109
	{
110
		/* Is the object mine in cache? */
111
		String testSuiteId = testSuite.getId();
112
		IObjectMine objectMine = null;
113
		if (useCache && (objectMine = (IObjectMine)cachedObjectMines.get(testSuiteId)) != null)
114
		{
115
			objectMine.setOwner(testSuite);
116
			return objectMine;
117
		}
118
			
119
		
120
		/* Otherwise, it needs to be loaded.  We need:
121
		 * - Get the object mine XML fragment
122
		 * - Parse it and load it */
123
		String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuite, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
124
		if (objectMineXML == null || objectMineXML.length() <= 0)
125
		{
126
			/* Return a fresh object mine */
127
			objectMine = new ObjectMine(testSuite, null);			
128
		}
129
			
130
		if (objectMine == null)
131
		{
132
			objectMine = loadObjectMine (testSuite, objectMineXML);
133
		}
134
		
135
		if (objectMine != null)
136
		{
137
			cachedObjectMines.put(testSuiteId, objectMine);
138
		}
139
		
140
		return objectMine;
141
	}
142
143
	private IObjectMine loadObjectMine (ITestSuite testSuite, String objectMineXML) throws UIObjectNotFound, IDCollisionException, CoreException
144
	{
145
		if (objectMineXML == null || objectMineXML.length() <= 0)
146
			return new ObjectMine(testSuite, null);
147
		
148
		XMLDefaultHandler handler = null;
149
150
		try
151
		{
152
			handler = MacroUtil.createXMLDocument(new ByteArrayInputStream(objectMineXML.getBytes("UTF-8")));
153
		}
154
		catch (SAXException e)
155
		{
156
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
157
		}
158
		catch (IOException e)
159
		{
160
			AutoGUIUtil.throwCoreException(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
161
		}
162
			
163
		/* Walk through the elemets and parse the document */
164
		Node rootElement = handler.getDocumentElement();
165
		NodeList children = rootElement.getChildNodes();
166
		
167
		IObjectMine objectMine = new ObjectMine(testSuite, handler);
168
		for (int i = 0, childCount = children.getLength(); i < childCount; i++)
169
		{
170
			Node currentChild = children.item(i);
171
			String nodeName = currentChild.getNodeName();
172
			if (MacroConstants.HEADER_ELEMENT.equals(nodeName))
173
			{
174
				loadHeader(objectMine, currentChild);
175
			}
176
			else if (MacroConstants.OBJECTS_ELEMENT.equals(nodeName))
177
			{
178
				loadObjects (objectMine, currentChild);
179
			}
180
		}
181
		
182
		
183
		return objectMine;
184
	}
185
	
186
	
187
	/**
188
	 * This method should be used if the object mine will be loaded for reading purposes.
189
	 * Contributors will not be able to use this returned object mine to write any objects.
190
	 * 
191
	 * @param objectMineXML The XML string representing the object mine 
192
	 * 
193
	 * @return the object mine of the test suite that is passed in.
194
	 * 
195
	 * @throws UIObjectNotFound In case an expected object is not found
196
	 * @throws IDCollisionException  In case there is a collision id
197
	 * @throws CoreException In case of any unexpected error
198
	 */
199
	public IObjectMine loadObjectMine (String objectMineXML) throws UIObjectNotFound, IDCollisionException, CoreException
200
	{
201
		return loadObjectMine(null, objectMineXML);
202
	}
203
	
204
	
205
	private void loadHeader(IObjectMine objectMine, Node headerNode) throws CoreException, UIObjectNotFound, IDCollisionException
206
	{
207
		/* Let's first read in the contribute attribute */
208
		NamedNodeMap attributes = headerNode.getAttributes();
209
		Node contributeAtt = attributes.getNamedItem(MacroConstants.OUTPUT_ATTRIBUTE);
210
		if (contributeAtt != null)
211
		{
212
			ITestSuite testSuite = loadTestSuite(contributeAtt.getNodeValue());
213
			if (testSuite == null)
214
			{
215
				AutoGUIUtil.openErrorWithDetail(
216
						AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
217
						AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUT_NF, 
218
						null);
219
				
220
			}
221
			else
222
			{
223
				try
224
				{
225
					IObjectMine outputObjectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite);
226
					objectMine.setOutputSource(outputObjectMine);
227
				} 
228
				catch (Exception e)
229
				{					
230
					objectMine.setOutputSource(null);
231
					AutoGUIUtil.openErrorWithDetail(
232
							AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
233
							NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, testSuite.getName()), 
234
							e);
235
				} 
236
			}			
237
		}
238
		
239
		/* Now load in all includes */
240
		NodeList children = headerNode.getChildNodes();
241
		for (int i = 0, childCount = children.getLength(); i < childCount; i++)
242
		{
243
			Node currentChild = children.item(i);
244
			String nodeName = currentChild.getNodeName();
245
			if (MacroConstants.INCLUDE_ELEMENT.equals(nodeName))
246
			{
247
				Node pathAttribute = currentChild.getAttributes().getNamedItem(MacroConstants.PATH_ATTRIBUTE);
248
				if (pathAttribute != null)
249
				{
250
					ITestSuite testSuite = loadTestSuite(pathAttribute.getNodeValue());
251
					IObjectMine includedObjectMine = loadObjectMine(testSuite);
252
					objectMine.addInclude(includedObjectMine);
253
				}
254
			}
255
		}
256
	}
257
	
258
	
259
	private void loadObjects(IObjectMine objectMine, Node objectsNode) throws CoreException, UIObjectNotFound, IDCollisionException 
260
	{
261
		NodeList children = objectsNode.getChildNodes();		
262
		registerObjects(objectMine, null, children);
263
	}
264
	
265
	
266
	private void registerObjects(IObjectMine objectMine, IUIObject parent, NodeList children) throws CoreException, UIObjectNotFound, IDCollisionException
267
	{
268
		/* For every object */
269
		for (int i = 0, childCount = children.getLength(); i < childCount; i++)
270
		{
271
			Node currentNode = children.item(i);	
272
273
			NamedNodeMap attributes = currentNode.getAttributes();
274
			Node referenceIdNode = attributes.getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE);
275
			String referenceId = null;
276
			if (referenceIdNode == null || (referenceId = referenceIdNode.getNodeValue()) == null)
277
			{
278
				Node idAttribute = attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE);
279
				String objectId = idAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN : idAttribute.getNodeValue(); 
280
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REF, objectId), 0);
281
			}
282
				
283
			IUIObject guiObject = objectMine.lookupUIObject(parent, referenceId);
284
				
285
			/* Register the object if it's not yet registered */
286
			if (guiObject == null)
287
			{
288
				guiObject = objectMine.registerObject(parent, currentNode);
289
			}
290
			/* Otherwise throw an exception if there is an id collision */
291
			else
292
			{
293
				Node contextIdNode = attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
294
				Node objectIdNode = attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE);
295
				String contextId = contextIdNode == null ? null : contextIdNode.getNodeValue();
296
				String objectId = objectIdNode.getNodeValue();
297
				
298
				if (((contextId == null && guiObject.getContextId() != null) || 
299
					(contextId != null && !contextId.equals(guiObject.getContextId()))) ||
300
					!objectId.equals(guiObject.getObjectId()))
301
				{
302
					throw new IDCollisionException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, referenceId));
303
				}
304
			}
305
306
			/* Load the children of this object */
307
			if (currentNode.getChildNodes().getLength() > 0)
308
				registerObjects(objectMine, guiObject, currentNode.getChildNodes());				
309
		}			
310
	}
311
312
313
	private ITestSuite loadTestSuite(String testSuitePath) throws CoreException
314
	{
315
		if (testSuitePath == null || testSuitePath.length() <= 0)
316
			return null;
317
		
318
		IPath path = new Path(testSuitePath);
319
		URI uri = URI.createPlatformResourceURI(path.toString());
320
		EObject[] eObjects = EMFUtil.getEObjects(uri, true);
321
		return eObjects != null && eObjects.length > 0 && eObjects[0] instanceof ITestSuite ? (ITestSuite)eObjects[0] : null;
322
	}
323
	
324
	
325
	public void writeObjectMine(IObjectMine objectMine)
326
	{
327
		writeObjectMine (objectMine, false);
328
	}
329
	
330
	private void writeObjectMine(IObjectMine objectMine, boolean autoSave)
331
	{
332
		ITestSuite testSuite = objectMine.getOwner();
333
		Resource testSuiteResource = ((EObject)testSuite).eResource();
334
		autoSave = autoSave && (testSuiteResource != null && !testSuiteResource.isModified());
335
		
336
		String xmlSerialization = objectMine.serializeToString();
337
		HyadesUtil.setTestSuiteVariable(testSuite, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE, xmlSerialization);		
338
		
339
		if (autoSave)
340
		{			
341
			try
342
			{
343
				EMFUtil.save(testSuiteResource);
344
			} catch (Exception e)
345
			{
346
				/* Shouldn't happen */
347
				e.printStackTrace();
348
			}
349
		}
350
		
351
		/* We also need to update all object mines included by the object mine passed in */
352
		List includes = objectMine.getIncludes();
353
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++)
354
		{
355
			IObjectMine currentObjectMine = (IObjectMine)includes.get(i);
356
			writeObjectMine (currentObjectMine, true);
357
		}
358
		
359
		
360
		dirtyStateTable.put(testSuite.getId(), Boolean.TRUE);
361
	}
362
363
364
	public IObjectMine loadObjectMine(ITestSuite testSuite) throws UIObjectNotFound, IDCollisionException, CoreException
365
	{
366
		Boolean dirtyState = (Boolean)dirtyStateTable.get(testSuite.getId());
367
		boolean isObjectMineDirty = dirtyState == null ? false : dirtyState.booleanValue();
368
		dirtyStateTable.put(testSuite.getId(), Boolean.FALSE);
369
		return loadObjectMine(testSuite, !isObjectMineDirty);
370
	}
371
372
373
	/**
374
	 * Marks the object mine of the passed in test suite as dirty
375
	 * 
376
	 * @param testSuite The test suite
377
	 */
378
	public void markObjectMineDirty(ITestSuite testSuite)
379
	{
380
		if (testSuite == null)
381
			return;
382
		
383
		dirtyStateTable.put(testSuite.getId(), Boolean.TRUE);	
384
	}
385
	
386
	
387
	/**
388
	 * Removes all entries in cache.
389
	 * This should be carefully used.
390
	 */
391
	public void clearCache()
392
	{
393
		cachedObjectMines.clear();
394
	}
395
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/Macro.java (-405 / +429 lines)
Lines 1-406 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
12
13
import java.io.PrintWriter;
13
import java.io.PrintWriter;
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.Hashtable;
15
import java.util.Hashtable;
16
import java.util.Stack;
16
import java.util.Stack;
17
17
18
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.SubProgressMonitor;
20
import org.eclipse.core.runtime.SubProgressMonitor;
21
import org.eclipse.jface.dialogs.Dialog;
21
import org.eclipse.jface.dialogs.Dialog;
22
import org.eclipse.jface.window.Window;
22
import org.eclipse.jface.window.Window;
23
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.SWT;
24
import org.eclipse.swt.widgets.Composite;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.swt.widgets.Display;
26
import org.eclipse.swt.widgets.Display;
26
import org.eclipse.swt.widgets.Event;
27
import org.eclipse.swt.widgets.Event;
27
import org.eclipse.swt.widgets.Shell;
28
import org.eclipse.swt.widgets.Shell;
28
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
29
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
29
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
30
import org.eclipse.tptp.test.auto.gui.internal.commands.MacroCommandShell;
30
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
31
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
31
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
32
import org.eclipse.tptp.test.auto.gui.internal.core.IPlayable;
32
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
33
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
33
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException;
34
import org.eclipse.tptp.test.auto.gui.internal.core.IWritable;
34
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound;
35
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
35
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
36
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.IDCollisionException;
36
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMine.UIObjectNotFound;
37
import org.eclipse.ui.PlatformUI;
38
import org.eclipse.ui.PlatformUI;
38
import org.w3c.dom.Node;
39
import org.w3c.dom.Node;
39
40
40
/**
41
/**
41
 * Models a macro
42
 * Models a macro
42
 */
43
 */
43
public class Macro implements IPersistable, IPlayable {
44
public class Macro implements IWritable, IPlayable
44
45
{
45
	public static final String SYNTAX_VERSION = "1.1";
46
	private static final String SYNTAX_VERSION = "1.0";
46
47
47
	/* An array of shells */
48
	/* Custom event types */
48
	private ArrayList shells;
49
	/* Indicates that a workbnech part has been closed */
49
50
	public static final int WORKBENCH_PART_CLOSED = -1;
50
	/* The name of this macro */
51
51
	private String name;
52
	/* An array of shells */
52
53
	private ArrayList shells;
53
	/* Keeps track of the stack of shells (This is used during recording) */
54
54
	private Stack shellStack;
55
	/* The name of this macro */
55
56
	private String name;
56
	public Macro() {
57
57
		shells = new ArrayList();
58
	/* Keeps track of the stack of shells (This is used during recording) */
58
	}
59
	private Stack shellStack;
59
60
	
60
	public Macro(String name) {
61
	public Macro()
61
		this();
62
	{
62
		this.name = name;
63
		shells = new ArrayList();
63
	}
64
	}
64
65
65
	/**
66
	public Macro(String name)
66
	 * {@inheritDoc}
67
	{
67
	 * 
68
		this();
68
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IReadable#load(org.w3c.dom.Node,
69
		this.name = name;
69
	 *      java.util.Hashtable)
70
	}
70
	 */
71
71
	public void load(Node node, Hashtable lineTable) throws CoreException {
72
	protected void addShell(Node node, Hashtable lineTable) throws CoreException
72
		MacroCommandShell shell = new MacroCommandShell(null, null, null);
73
	{
73
		shell.load(node, lineTable);
74
		MacroCommandShell shell = new MacroCommandShell(null, null, null);
74
		shells.add(shell);
75
		shell.load(node, lineTable);
75
	}
76
		shells.add(shell);
76
77
	}
77
	public void initializeForRecording(Display display) {
78
78
		shellStack = new Stack();
79
	public void initializeForRecording(Display display)
79
		shells.clear();
80
	{
80
		Shell currentShell = display.getActiveShell();
81
		shellStack = new Stack();
81
82
		shells.clear();
82
		if (currentShell == null)
83
		Shell currentShell = display.getActiveShell();
83
			return;
84
84
85
		if (currentShell == null)
85
		/*
86
			return;
86
		 * In case we are suppose to ignore the shell, then don't add it to our
87
		
87
		 * stack
88
		/* In case we are suppose to ignore the shell, then don't add it to our stack */
88
		 */
89
		Object data = currentShell.getData(MacroManager.IGNORE);
89
		Object data = currentShell.getData(MacroManager.IGNORE);
90
		
90
91
		if (data != null && data instanceof Boolean && ((Boolean)data).booleanValue())
91
		if (data != null && data instanceof Boolean
92
			return;
92
				&& ((Boolean) data).booleanValue())
93
		
93
			return;
94
		pushStack(createCommandShell(currentShell));
94
95
	}
95
		// hook the workbench listener
96
96
		MacroUtil.hookWorkbenchPartListener(currentShell);
97
	private MacroCommandShell createCommandShell(Shell shell)
97
98
	{
98
		pushStack(createCommandShell(currentShell));
99
		WidgetIdentifier wi = MacroUtil.getWidgetIdentifier(shell);
99
	}
100
		if (wi == null)
100
101
			return null;
101
	private MacroCommandShell createCommandShell(Shell shell) {
102
		return new MacroCommandShell(null, shell, wi);
102
		IMacroObjectIdentifier wi = null;
103
	}
103
		try {
104
104
			wi = MacroObjectResolver.resolve(shell, new MacroObject(
105
	private boolean isCurrent(Shell shell)
105
					new UIObject(shell)));
106
	{
106
		} catch (Exception e) {
107
		if (shellStack.isEmpty())
107
			e.printStackTrace();
108
			return false;
108
		}
109
		MacroCommandShell cshell = (MacroCommandShell) shellStack.peek();
109
		if (wi == null)
110
		return cshell.tracks(shell);
110
			return null;
111
	}
111
		return new MacroCommandShell(null, shell, wi);
112
112
	}
113
	public void stopRecording()
113
114
	{
114
	private boolean isCurrent(Shell shell) {
115
		reset();
115
		if (shellStack.isEmpty())
116
	}
116
			return false;
117
117
		MacroCommandShell cshell = (MacroCommandShell) shellStack.peek();
118
	public boolean addEvent(Event event) throws Exception
118
		return cshell.tracks(shell);
119
	{
119
	}
120
		if (MacroUtil.isIgnorableEvent(event))
120
121
			return false;
121
	public void stopRecording() {
122
		try
122
		reset();
123
		{			
123
	}
124
			/*
124
125
			 * A new shell is in the picture now (i.e. a new shell is closed or
125
	public void addEvent(Event event) throws Exception {
126
			 * activated). We need to modify the shell stack
126
		if (MacroUtil.isIgnorableEvent(event)) {
127
			 */
127
			return;
128
			if (event.widget instanceof Shell)
128
		}
129
			{
129
130
				switch (event.type)
130
		if (event.type != EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) {
131
				{
131
			// hook the workbench listener, if not already registered at the
132
				case SWT.Activate:
132
			// widget
133
					activateShell((Shell) event.widget);
133
			MacroUtil.hookWorkbenchPartListener(event.widget);
134
					break;
134
		}
135
				case SWT.Close:
135
136
					boolean stop = closeShell((Shell) event.widget);
136
		/*
137
					if (stop)
137
		 * A new shell is in the picture now (i.e. a new shell is closed or
138
						return true;
138
		 * activated). We need to modify the shell stack
139
					break;
139
		 */
140
				}
140
		if (event.widget instanceof Shell) {
141
			}
141
			switch (event.type) {
142
142
			case SWT.Activate:
143
			/* Otherwise we have performed a command within the current shell */
143
				activateShell((Shell) event.widget);
144
			else 
144
				break;
145
			{
145
			case SWT.Close:
146
				/* Make sure that the command sent over belongs to the top shell */
146
				boolean stop = closeShell((Shell) event.widget);
147
				MacroCommandShell topCommandShell = getTopShell();
147
				if (stop)
148
				if (topCommandShell != null)
148
					return;
149
				{
149
				break;
150
					Shell topShell = topCommandShell.getShell();
150
			}
151
					Shell widgetShell = (!(event.widget instanceof Control) ? null : ((Control)event.widget).getShell());
151
		}
152
					
152
153
					/* Add the event only if the widget shell could not be resolved or the widget shell is the same
153
		// TODO: See if the following can be simplified
154
					 * as the top shell */
154
		/* Otherwise we have performed a command within the current shell */
155
					if (widgetShell == null || topShell == widgetShell)
155
		if (!(event.widget instanceof Shell)
156
					{
156
				&& event.detail != EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) {
157
						topCommandShell.addEvent(event);
157
			/* Make sure that the command sent over belongs to the top shell */
158
					}
158
			MacroCommandShell topCommandShell = getTopShell();
159
				}
159
			if (topCommandShell != null) {
160
			}
160
				Shell topShell = topCommandShell.getShell();
161
		} catch (Exception e)
161
				Shell widgetShell = (!(event.widget instanceof Control) ? null
162
		{
162
						: ((Control) event.widget).getShell());
163
			throw e;
163
164
		}
164
				/*
165
		return false;
165
				 * Add the event only if the widget shell could not be resolved
166
	}
166
				 * or the widget shell is the same as the top shell
167
167
				 */
168
168
				if (widgetShell == null || topShell == widgetShell) {
169
169
					topCommandShell.addEvent(event);
170
	public void addPause()
170
				}
171
	{
171
			}
172
		MacroCommandShell topShell = getTopShell();
172
		} else if (event.detail == EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) {
173
		if (topShell != null)
173
			MacroCommandShell topShell = getTopShell();
174
			topShell.addPause();
174
			/*
175
	}
175
			 * There is a chance that the macro does not have a top shell. We'll
176
176
			 * attempt to resolve its top shell, if unsuccessful, then we'll
177
177
			 * prompt the user with an error.
178
	public MacroCommandShell getTopShell()
178
			 */
179
	{
179
			if (topShell == null && event.widget instanceof Control) {
180
		if (shellStack.isEmpty())
180
				Event artificialEvent = new Event();
181
			return null;
181
				artificialEvent.type = SWT.Activate;
182
		return (MacroCommandShell) shellStack.peek();
182
				artificialEvent.display = event.widget.getDisplay();
183
	}
183
				artificialEvent.widget = ((Control) event.widget).getShell();
184
184
				addEvent(artificialEvent);
185
	private void activateShell(Shell shell)
185
				topShell = getTopShell();
186
	{
186
			}
187
		if (shell.isDisposed())
187
			if (topShell != null) {
188
			return;
188
				topShell.addEvent(event);
189
		
189
			}
190
		Object data = shell.getData();
190
191
		if (data instanceof Dialog)
191
		}
192
		{
192
		return;
193
			if (!isCurrent(shell))
193
	}
194
			{
194
195
				/* Before adding the shell to the stack, make sure that it is not a parent of the current shell */
195
	public void addPause() {
196
				MacroCommandShell parentOfCurrentShell = null;
196
		MacroCommandShell topShell = getTopShell();
197
				if (shellStack.size() - 2 >= 0)
197
		if (topShell != null)
198
				{
198
			topShell.addPause();
199
					parentOfCurrentShell = (MacroCommandShell)shellStack.get(shellStack.size() - 2);
199
	}
200
				}
200
201
				
201
	public MacroCommandShell getTopShell() {
202
				/* If the new shell happens to be the parent of the current shell, then we just need to pop the stack */
202
		if (shellStack.isEmpty())
203
				if (parentOfCurrentShell != null && parentOfCurrentShell.tracks(shell))
203
			return null;
204
				{
204
		return (MacroCommandShell) shellStack.peek();
205
					popStack();
205
	}
206
				}			
206
207
				else
207
	private void activateShell(Shell shell) {
208
				{
208
		if (shell.isDisposed())
209
					
209
			return;
210
					MacroCommandShell commandShell = createCommandShell(shell);
210
211
					
211
		Object data = shell.getData();
212
					/* Initialize for recording failed to find the top shell */
212
		if (data instanceof Dialog) {
213
					if (getTopShell() == null)
213
			if (!isCurrent(shell)) {
214
					{
214
				/*
215
						pushStack(commandShell);			
215
				 * Before adding the shell to the stack, make sure that it is
216
					}
216
				 * not a parent of the current shell
217
					else
217
				 */
218
					{						
218
				MacroCommandShell parentOfCurrentShell = null;
219
						getTopShell().addCommandShell(commandShell);
219
				if (shellStack.size() - 2 >= 0) {
220
						shellStack.push(commandShell);
220
					parentOfCurrentShell = (MacroCommandShell) shellStack
221
						updateObjectMine(commandShell);				
221
							.get(shellStack.size() - 2);
222
					}
222
				}
223
				}
223
224
			}
224
				/*
225
		}
225
				 * If the new shell happens to be the parent of the current
226
		else if (data instanceof Window)
226
				 * shell, then we just need to pop the stack
227
		{				
227
				 */
228
			updateStack();
228
				if (parentOfCurrentShell != null
229
			if (!isCurrent(shell))
229
						&& parentOfCurrentShell.tracks(shell)) {
230
			{
230
					popStack();
231
				popStack();
231
				} else {
232
				
232
233
				MacroCommandShell newCommandShell = createCommandShell(shell);
233
					MacroCommandShell commandShell = createCommandShell(shell);
234
				MacroCommandShell topCommandShell = getTopShell();
234
235
				if (topCommandShell == null || !topCommandShell.getWidgetId().getObjectId().equals(newCommandShell.getWidgetId().getObjectId()))
235
					/* Initialize for recording failed to find the top shell */
236
				{					
236
					if (getTopShell() == null) {
237
					pushStack(createCommandShell(shell));
237
						pushStack(commandShell);
238
				}			
238
					} else {
239
			}
239
						getTopShell().addCommandShell(commandShell);
240
240
						shellStack.push(commandShell);
241
		}
241
						updateObjectMine(commandShell);
242
	}
242
					}
243
243
				}
244
	private void popStack()
244
			}
245
	{
245
		} else if (data instanceof Window) {
246
		if (shellStack.isEmpty())
246
			updateStack();
247
			return;
247
			if (!isCurrent(shell)) {
248
		MacroCommandShell top = (MacroCommandShell) shellStack.pop();
248
				popStack();
249
		top.extractExpectedReturnCode();
249
250
		updateObjectMine(getTopShell());
250
				MacroCommandShell newCommandShell = createCommandShell(shell);
251
	}
251
				MacroCommandShell topCommandShell = getTopShell();
252
	
252
				if (topCommandShell == null
253
	
253
						|| !topCommandShell.getMacroObjectIdentifier()
254
	private void pushStack(MacroCommandShell commandShell)
254
								.getObjectIdentifier().getWidgetId().equals(
255
	{		
255
										newCommandShell
256
		shellStack.push(commandShell);
256
												.getMacroObjectIdentifier()
257
		shells.add(commandShell);
257
												.getObjectIdentifier()
258
		updateObjectMine(commandShell);
258
												.getWidgetId())) {
259
	}
259
					pushStack(createCommandShell(shell));
260
260
				}
261
	private void updateObjectMine(MacroCommandShell commandShell)
261
			}
262
	{
262
263
		IObjectMine objectMine = MacroManager.getInstance().getObjectMine();
263
		}
264
		MacroCommandShell macroCommandShell = getTopShell();
264
	}
265
		final String SHELL = "Shell";
265
266
		IUIObject shellObject = null;
266
	private void popStack() {
267
		if (objectMine != null && macroCommandShell != null)
267
		if (shellStack.isEmpty())
268
		{
268
			return;
269
			try
269
		MacroCommandShell top = (MacroCommandShell) shellStack.pop();
270
			{
270
		top.extractExpectedReturnCode();
271
				String macroShellObjectId = macroCommandShell.getWidgetId().getObjectId().toString();
271
		updateObjectMine(getTopShell());
272
				shellObject = objectMine.lookupUIObject(null, null, macroShellObjectId);
272
	}
273
				if (shellObject == null)
273
274
				{
274
	private void pushStack(MacroCommandShell commandShell) {
275
					shellObject = new UIObject(null);
275
		shellStack.push(commandShell);
276
					shellObject.setDescriptive(SHELL + (macroCommandShell.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING : ": " + macroCommandShell.getDescriptiveField()));
276
		shells.add(commandShell);
277
					shellObject.setObjectId(macroShellObjectId);
277
		updateObjectMine(commandShell);
278
					shellObject.setReferenceId(objectMine.getUniqueReferenceId());
278
	}
279
					shellObject.setResolver(macroCommandShell.getWidgetId().getResolverId());
279
280
					shellObject = objectMine.registerObject(shellObject);					
280
	private void updateObjectMine(MacroCommandShell commandShell) {
281
				}
281
		MacroObjectDescriptorMine objectMine = MacroManager.getInstance()
282
				objectMine.setActiveObject(shellObject);
282
				.getObjectMine();
283
			} 
283
		MacroCommandShell macroCommandShell = getTopShell();
284
			catch (UIObjectNotFound e)
284
		final String SHELL = "Shell";
285
			{
285
		MacroObjectDescriptor shellObject = null;
286
				/* Shouldn't happen */
286
		if (objectMine != null && macroCommandShell != null) {
287
				e.printStackTrace();
287
			try {
288
			} catch (IDCollisionException e)
288
				IMacroObjectIdentifier macroShellObjectId = macroCommandShell
289
			{
289
						.getMacroObjectIdentifier();
290
				/* Shouldn't happen */
290
				shellObject = objectMine.lookupMacroObjectDescriptor(null,
291
				e.printStackTrace();
291
						null, macroShellObjectId.getObjectIdentifier()
292
			} catch (CoreException e)
292
								.getWidgetId(), null);
293
			{
293
				if (shellObject == null) {
294
				/* Shouldn't happen */
294
					shellObject = new MacroObjectDescriptor(null);
295
				e.printStackTrace();
295
					((MacroObjectDescriptor) shellObject)
296
			}
296
							.setDescriptive(SHELL
297
		}
297
									+ (macroCommandShell.getDescriptiveField() == null ? MacroConstants.EMPTY_STRING
298
		
298
											: ": "
299
		/* Update the reference id of the widget identifier for the macro command shell */
299
													+ macroCommandShell
300
		if (shellObject != null)
300
															.getDescriptiveField()));
301
		{
301
					((MacroObjectDescriptor) shellObject)
302
			commandShell.getWidgetId().setReferenceId(shellObject.getReferenceId());
302
							.setWidgetId(macroShellObjectId
303
		}
303
									.getObjectIdentifier().getWidgetId());
304
	}
304
					((MacroObjectDescriptor) shellObject)
305
305
					.setObjectId(macroShellObjectId
306
	private boolean closeShell(Shell shell)
306
							.getObjectIdentifier().getObjectId());
307
	{
307
					((MacroObjectDescriptor) shellObject)
308
		if (shellStack.isEmpty())
308
							.setResolver(macroCommandShell
309
			return false;
309
									.getMacroObjectIdentifier()
310
		MacroCommandShell top = (MacroCommandShell) shellStack.peek();
310
									.getObjectIdentifier().getResolverId());
311
		if (top.tracks(shell))
311
					shellObject = objectMine
312
			popStack();
312
							.registerObject((MacroObjectDescriptor) shellObject);
313
		return shellStack.isEmpty();
313
				}
314
	}
314
				objectMine.setActiveObject(shellObject);
315
315
			} catch (UIObjectNotFound e) {
316
	private void updateStack()
316
				/* Shouldn't happen */
317
	{
317
				e.printStackTrace();
318
		while (shellStack.size() > 0)
318
			} catch (IDCollisionException e) {
319
		{
319
				/* Shouldn't happen */
320
			MacroCommandShell top = getTopShell();
320
				e.printStackTrace();
321
			if (top.isDisposed())
321
			} catch (CoreException e) {
322
				popStack();
322
				/* Shouldn't happen */
323
			else
323
				e.printStackTrace();
324
				break;
324
			}
325
		}
325
		}
326
	}
326
327
327
		/*
328
	public boolean playback(Display display, Composite parent, IProgressMonitor monitor) throws CoreException
328
		 * Update the reference id of the widget identifier for the macro
329
	{
329
		 * command shell
330
		reset();
330
		 */
331
		String mname = name != null ? name : "macro";
331
		if (shellObject != null) {
332
		monitor.beginTask(AutoGUIMessages.AUTO_GUI_MACRO_EXECUTING + mname + " ...", shells.size());
332
			// seems to be more appropriate to set the corrsponding object for
333
		for (int i = 0; i < shells.size(); i++)
333
			// the shell
334
		{
334
			commandShell.setCorrespondingMacroObjectDescriptor(shellObject);
335
			MacroCommandShell shell = (MacroCommandShell) shells.get(i);
335
			// CHANGED BY ANY:
336
			final Shell[] sh = new Shell[1];
336
			// commandShell.getWidgetId().setReferenceId(shellObject.getReferenceId());
337
			display.syncExec(new Runnable()
337
		}
338
			{
338
	}
339
				public void run()
339
340
				{
340
	private boolean closeShell(Shell shell) {
341
					sh[0] = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
341
		if (shellStack.isEmpty())
342
				}
342
			return false;
343
			});
343
		MacroCommandShell top = (MacroCommandShell) shellStack.peek();
344
			try
344
		if (top.tracks(shell))
345
			{
345
			popStack();
346
				boolean result = shell.playback(display, sh[0], new SubProgressMonitor(monitor, 1));
346
		return shellStack.isEmpty();
347
				if (!result)
347
	}
348
					return false;
348
349
			} catch (CoreException e)
349
	private void updateStack() {
350
			{				
350
		while (shellStack.size() > 0) {
351
				throw e;
351
			MacroCommandShell top = getTopShell();
352
			}
352
			if (top.isDisposed())
353
		}
353
				popStack();
354
		return true;
354
			else
355
	}
355
				break;
356
356
		}
357
	private void reset()
357
	}
358
	{
358
359
		shellStack = null;
359
	public boolean playback(Display display, Shell parent,
360
	}
360
			IProgressMonitor monitor) throws CoreException {
361
361
		reset();
362
	public void write(int indent, PrintWriter writer)
362
		String mname = name != null ? name : "macro";
363
	{
363
		monitor.beginTask(AutoGUIMessages.AUTO_GUI_MACRO_EXECUTING + mname
364
		StringBuffer sb = new StringBuffer();
364
				+ " ...", shells.size());
365
		write (indent, sb);
365
		for (int i = 0; i < shells.size(); i++) {
366
		writer.write(sb.toString());
366
			MacroCommandShell shell = (MacroCommandShell) shells.get(i);
367
	}
367
			final Shell[] sh = new Shell[1];
368
368
			display.syncExec(new Runnable() {
369
	public void write(int indent, StringBuffer sb)
369
370
	{
370
				public void run() {
371
		/* Add <macro version="..." */
371
					sh[0] = PlatformUI.getWorkbench()
372
		MacroUtil.addElement(sb, indent, MacroConstants.MACRO_ELEMENT, false, false);
372
							.getActiveWorkbenchWindow().getShell();
373
		MacroUtil.addAttribute(sb, new String[] {MacroConstants.VERSION_ATTRIBUTE}, new String[] {SYNTAX_VERSION}, false, true);
373
				}
374
374
			});
375
		int cindent = 1;
375
			try {
376
		/* For every macro command shell */
376
				boolean result = shell.playback(display, sh[0],
377
		for (int i = 0; i < shells.size(); i++)
377
						new SubProgressMonitor(monitor, 1));
378
		{
378
				if (!result)
379
			MacroCommandShell cshell = (MacroCommandShell) shells.get(i);
379
					return false;
380
			cshell.write(cindent, sb);
380
			} catch (CoreException e) {
381
		}
381
				throw e;
382
		MacroUtil.addElement(sb, 0, MacroConstants.MACRO_ELEMENT, true, true);		
382
			}
383
	}
383
		}
384
	
384
		return true;
385
	
385
	}
386
	public String getName()
386
387
	{
387
	private void reset() {
388
		return name;
388
		shellStack = null;
389
	}
389
	}
390
390
391
	public void writeStart(int indent, StringBuffer writer)
391
	public void write(int indent, PrintWriter writer) {
392
	{
392
		StringBuffer sb = new StringBuffer();
393
		/* Doesn't need to be implemented */		
393
		write(indent, sb);
394
	}
394
		writer.write(sb.toString());
395
395
	}
396
	public void writeFinish(int indent, StringBuffer writer)
396
397
	{
397
	public void write(int indent, StringBuffer sb) {
398
		/* Doesn't need to be implemented */	
398
		/* Add <macro version="..." */
399
	}
399
		MacroUtil.addElement(sb, indent, MacroConstants.MACRO_ELEMENT, false,
400
	
400
				false);
401
	public int getShellStackSize()
401
		MacroUtil.addAttribute(sb,
402
	{
402
				new String[] { MacroConstants.VERSION_ATTRIBUTE },
403
		return shellStack.size();
403
				new String[] { SYNTAX_VERSION }, false, true);
404
	}
404
405
405
		int cindent = 1;
406
		/* For every macro command shell */
407
		for (int i = 0; i < shells.size(); i++) {
408
			MacroCommandShell cshell = (MacroCommandShell) shells.get(i);
409
			cshell.write(cindent, sb);
410
		}
411
		MacroUtil.addElement(sb, 0, MacroConstants.MACRO_ELEMENT, true, true);
412
	}
413
414
	public String getName() {
415
		return name;
416
	}
417
418
	public void writeStart(int indent, StringBuffer writer) {
419
		/* Doesn't need to be implemented */
420
	}
421
422
	public void writeFinish(int indent, StringBuffer writer) {
423
		/* Doesn't need to be implemented */
424
	}
425
426
	public int getShellStackSize() {
427
		return shellStack.size();
428
	}
429
406
}
430
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/AbstractMacroInstruction.java (-122 / +73 lines)
Lines 1-123 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
12
13
import java.util.Hashtable;
13
import java.util.Hashtable;
14
import java.util.Map;
14
import java.util.Map;
15
15
16
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction;
17
import org.w3c.dom.Node;
18
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
18
19
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
19
/**
20
import org.w3c.dom.Node;
20
 * Provides an abstract implementation of {@link IMacroInstruction}. Contributors can subclass {@link AbstractMacroInstruction} or provide a direct
21
21
 * implementaion of {@link IMacroInstruction}.
22
/**
22
 * 
23
 * Provides an abstract implementation of {@link IMacroInstruction}.  Contributors
23
 * @author Ali Mehregani
24
 * can subclass {@link AbstractMacroInstruction} or provide a direct implementaion 
24
 */
25
 * of {@link IMacroInstruction}.
25
public abstract class AbstractMacroInstruction implements IMacroInstruction {
26
 * 
26
27
 * @author Ali Mehregani
27
	/** The line range of this macro instruction relative to the macro script */
28
 */
28
	private int[] range;
29
public abstract class AbstractMacroInstruction implements IMacroInstruction
29
30
{      
30
	/**
31
	/** The widget id associated with this command */
31
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable)
32
	private WidgetIdentifier widgetId;
32
	 */
33
		
33
	public void load(Node node, Hashtable lineTable) throws CoreException {
34
    /** The corresponding UI object for this macro instruction*/
34
		bindSourceLocation(node,
35
	private IUIObject uiObject;
35
			lineTable);
36
36
	}
37
	/** The line range of this macro instruction relative to the macro script */ 
37
38
    private int [] range;
38
	/**
39
    
39
	 * Binds the line details with this macro instruction
40
    
40
	 * 
41
    /**
41
	 * @param node
42
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#load(org.w3c.dom.Node, java.util.Hashtable)
42
	 *            The node of this instruction
43
     */
43
	 * @param lineTable
44
	public void load(Node node, Hashtable lineTable) throws CoreException
44
	 *            The line level information
45
	{        
45
	 */
46
        bindSourceLocation(node, lineTable);        
46
	protected void bindSourceLocation(Node node, Map lineTable) {
47
	}
47
		Integer[] lines = (Integer[]) lineTable.get(node);
48
48
		if (lines != null) {
49
	
49
			range = new int[2];
50
	/**
50
			range[0] = lines[0].intValue();
51
	 * Binds the line details with this macro instruction
51
			range[1] = lines[1].intValue();
52
	 * 
52
		}
53
	 * @param node The node of this instruction
53
	}
54
	 * @param lineTable The line level information
54
55
	 */
55
	/**
56
    protected void bindSourceLocation(Node node, Map lineTable) 
56
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getStartLine()
57
    {
57
	 */
58
        Integer[] lines = (Integer[]) lineTable.get(node);
58
	public int getStartLine() {
59
        if (lines != null) {
59
		if (range == null)
60
            range = new int[2];
60
			return -1;
61
            range[0] = lines[0].intValue();
61
		return range[0];
62
            range[1] = lines[1].intValue();
62
	}
63
        }
63
64
    }
64
	/**
65
65
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getStopLine()
66
    
66
	 */
67
    /**
67
	public int getStopLine() {
68
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getStartLine()
68
		if (range == null)
69
     */
69
			return -1;
70
    public int getStartLine() 
70
		return range[1];
71
    {
71
	}
72
        if (range == null)
72
73
            return -1;
73
	
74
        return range[0];
75
    }
76
    
77
    
78
    /**
79
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getStopLine()
80
     */
81
    public int getStopLine() 
82
    {
83
        if (range == null)
84
            return -1;
85
        return range[1];
86
    }
87
 
88
    
89
    /**
90
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getCorrespondingObject()
91
     */
92
    public IUIObject getCorrespondingObject()
93
    {
94
    	return uiObject;
95
    }
96
    
97
    
98
    /**
99
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#setCorrespondingObject(org.eclipse.tptp.test.auto.gui.internal.core.IUIObject)
100
     */
101
    public void setCorrespondingObject(IUIObject uiObject)
102
    {
103
    	this.uiObject = uiObject;
104
    }
105
    
106
    
107
    /**
108
     * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#getWidgetId()
109
     */
110
	public WidgetIdentifier getWidgetId()
111
	{
112
		return widgetId;
113
	}
114
		
115
	
116
	/**
117
	 * @see org.eclipse.tptp.test.auto.gui.internal.core.IMacroInstruction#setWidgetId(org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier)
118
	 */
119
	public void setWidgetId(WidgetIdentifier widgetIdentifier)
120
	{
121
		this.widgetId = widgetIdentifier;
122
	}
123
}
74
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroConstants.java (-81 / +91 lines)
Lines 1-81 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
12
13
13
14
/**
14
/**
15
 * Defines macro constants used to construct the macro
15
 * Defines macro constants used to construct the macro
16
 * 
16
 * 
17
 * @author Ali Mehregani
17
 * @author Ali Mehregani
18
 */
18
 */
19
public class MacroConstants 
19
public class MacroConstants 
20
{	
20
{	
21
	/** Common constants */
21
	/** Common constants */
22
	public static final String OPEN_ANGLE_BRACKET = "<";
22
	public static final String OPEN_ANGLE_BRACKET = "<";
23
	public static final String CLOSE_ANGLE_BRACKET = ">";
23
	public static final String CLOSE_ANGLE_BRACKET = ">";
24
	public static final String FORWARD_SLASH = "/";
24
	public static final String FORWARD_SLASH = "/";
25
	public static final String EQUAL_SIGN = "=";
25
	public static final String EQUAL_SIGN = "=";
26
	public static final String EMPTY_STRING = "";
26
	public static final String EMPTY_STRING = "";
27
	public static final String SINGLE_SPACE = " ";
27
	public static final String SINGLE_SPACE = " ";
28
	public static final String DOUBLE_QUOTE = "\"";
28
	public static final String DOUBLE_QUOTE = "\"";
29
	public static final String TRUE_VALUE = "true";
29
	public static final String TRUE_VALUE = "true";
30
	public static final String FALSE_VALUE = "false";
30
	public static final String FALSE_VALUE = "false";
31
	
31
	
32
	/** XML Elements */
32
	/** XML Elements */
33
	public static final String MACRO_ELEMENT = "macro";
33
	public static final String MACRO_ELEMENT = "macro";
34
	public static final String SHELL_ELEMENT = "shell";
34
	public static final String SHELL_ELEMENT = "shell";
35
	public static final String COMMAND_ELEMENT = "command";	
35
	public static final String COMMAND_ELEMENT = "command";	
36
	public static final String OBJECT_MINE_ELEMENT = "object-mine";
36
	public static final String OBJECT_MINE_ELEMENT = "object-mine";
37
	public static final String HEADER_ELEMENT = "header";
37
	public static final String HEADER_ELEMENT = "header";
38
	public static final String INCLUDE_ELEMENT = "include";
38
	public static final String INCLUDE_ELEMENT = "include";
39
	public static final String OBJECTS_ELEMENT = "objects";
39
	public static final String OBJECTS_ELEMENT = "objects";
40
	public static final String OBJECT_ELEMENT = "object";	
40
	public static final String OBJECT_ELEMENT = "object";	
41
	public static final String ITEM_ELEMENT = "item";
41
	public static final String ITEM_ELEMENT = "item";
42
	public static final String SELECT_ITEM_ELEMENT = "selected-item";
42
	public static final String SELECT_ITEM_ELEMENT = "selected-item";
43
	public static final String PARENT_ELEMENT = "parent";
43
	//ANy: was never used: public static final String PARENT_ELEMENT = "parent";
44
44
45
	/** XML Attributes */
45
	/** XML Attributes */
46
	public static final String DESCRIPTIVE_ATTRIBUTE = "descriptive";
46
	public static final String DESCRIPTIVE_ATTRIBUTE = "descriptive";
47
	public static final String TYPE_ATTRIBUTE = "type";
47
	public static final String TYPE_ATTRIBUTE = "type";
48
	public static final String CONTEXT_ID_ATTRIBUTE = "contextId";
48
	public static final String CONTEXT_ID_ATTRIBUTE = "contextId";
49
	public static final String WIDGET_ID_ATTRIBUTE = "widgetId";	
49
	public static final String WIDGET_ID_ATTRIBUTE = "widgetId";
50
	public static final String ID_ATTRIBUTE = "id";
50
	public static final String OBJECT_ID_ATTRIBUTE = "objectId";
51
	public static final String RETURN_CODE_ATTRIBUTE = "return-code";
51
	public static final String ID_ATTRIBUTE = "id";
52
	public static final String TIME_TO_WAIT_ATTRIBUTE = "time-to-wait";
52
	public static final String RETURN_CODE_ATTRIBUTE = "return-code";
53
	public static final String OUTPUT_ATTRIBUTE = "output";
53
	public static final String TIME_TO_WAIT_ATTRIBUTE = "time-to-wait";
54
	public static final String PATH_ATTRIBUTE = "path";
54
	public static final String OUTPUT_ATTRIBUTE = "output";
55
	public static final String REFERENCE_ID_ATTRIBUTE = "referenceId";
55
	public static final String PATH_ATTRIBUTE = "path";
56
	public static final String RESOLVER_ATTRIBUTE = "resolverId";	
56
	public static final String REFERENCE_ID_ATTRIBUTE = "referenceId";
57
	public static final String VERSION_ATTRIBUTE = "version";
57
	public static final String RESOLVER_ID_ATTRIBUTE = "resolverId";	
58
	public static final String X_COORD_ATTRIBUTE = "x-coord";
58
	public static final String VERSION_ATTRIBUTE = "version";
59
	public static final String Y_COORD_ATTRIBUTE = "y-coord";
59
	public static final String X_COORD_ATTRIBUTE = "x-coord";
60
	public static final String DETAIL_ATTRIBUTE = "detail";
60
	public static final String Y_COORD_ATTRIBUTE = "y-coord";
61
	public static final String SELECTION_ATTRIBUTE = "selection";
61
	public static final String DETAIL_ATTRIBUTE = "detail";
62
	public static final String VALUE_ATTRIBUTE = "value";
62
	public static final String SELECTION_ATTRIBUTE = "selection";
63
	public static final String CHOICE_ID_ATTRIBUTE = "choiceId";
63
	public static final String VALUE_ATTRIBUTE = "value";
64
	public static final String LOCATION_ATTRIBUTE = "location";
64
	public static final String CHOICE_ID_ATTRIBUTE = "choiceId";
65
	public static final String RESOURCE_ATTRIBUTE = "resource";
65
	public static final String LOCATION_ATTRIBUTE = "location";
66
	public static final String HOOK_ATTRIBUTE = "hook";
66
	public static final String RESOURCE_ATTRIBUTE = "resource";
67
	public static final String IS_CHAR_SET_ATTRIBUTE = "ischarset";
67
	public static final String HOOK_ATTRIBUTE = "hook";
68
	
68
	public static final String IS_CHAR_SET_ATTRIBUTE = "ischarset";
69
	/** Values */
69
	
70
	public static final String VIEW_VALUE = "view";
70
	/** Values */
71
	public static final String EDITOR_VALUE = "editor";
71
	public static final String VIEW_VALUE = "view";
72
	public static final String SHELL_VALUE = "shell";
72
	public static final String EDITOR_VALUE = "editor";
73
	public static final String MENUS_VALUE = "menus";
73
	public static final String SHELL_VALUE = "shell";
74
	public static final String POPUP_VALUE = "popup";
74
	public static final String MENUS_VALUE = "menus";
75
	public static final String LOCAL_TOOLBAR_MENU_VALUE = "local-toolbar-menu";
75
	public static final String POPUP_VALUE = "popup";
76
	public static final String TOOLBAR_VALUE = "toolbar";
76
	public static final String LOCAL_TOOLBAR_MENU_VALUE = "local-toolbar-menu";
77
	public static final String LOCAL_TOOLBAR_VALUE = "local-toolbar";
77
	public static final String TOOLBAR_VALUE = "toolbar";
78
	public static final String WIZARD_VALUE = "wizard";
78
	public static final String LOCAL_TOOLBAR_VALUE = "local-toolbar";
79
	public static final String WIZARD_PAGE_VALUE = "wizard-page";
79
	public static final String TAB_VALUE = "tab"; // ANy: introduced for TabItems and CTabItems
80
	
80
	public static final String WIZARD_VALUE = "wizard";
81
}
81
	public static final String WIZARD_PAGE_VALUE = "wizard-page";
82
	
83
	
84
	public static final String RESOLVER_ID_SUFFIX_SEPARATOR = "@@@";
85
	public static final String WIDGET_ID_SUFFIX_SEPARATOR = "%%%";
86
	public static final String OBJECT_ID_SUFFIX_SEPARATOR = "$$$";
87
	public static final String WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR = "!!!";
88
	
89
	
90
	
91
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/UIObject.java (-260 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.LinkedList;
16
import java.util.Map;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.osgi.util.NLS;
20
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
22
import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand;
23
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
24
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
25
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetIdentifier;
26
27
public class UIObject implements IUIObject
28
{
29
	/** The context id */
30
	private String contextId;
31
	
32
	/** The id of the object being resolved */
33
	private String objectId;
34
	
35
	/** The reference id of this UI object */
36
	private String referenceId;
37
	
38
	/** The descriptive attribute (a human readable identification) of this UI object */
39
	private String descriptive;
40
	
41
	/** Keeps track of the hierarchical relationship */
42
	private LinkedList hierarchicalRelation;
43
	
44
	/** The parent of this UI object */
45
	private IUIObject parent;
46
	
47
	/** The properties of this UI Object */
48
	private Hashtable properties;
49
50
	/** The id of the resolver that has resolved this object */
51
	private String resolverId;
52
	
53
	/** The children of this object */
54
	private ArrayList children;
55
56
	/** The associated data of this object */
57
	private Object data;
58
	
59
	/** Children indexed based on their reference id
60
	 * KEY = Reference id
61
	 * VALUE = IUIObject that is a child of this object
62
	 */
63
	private Hashtable idIndexedChildren;
64
	
65
	public UIObject(IUIObject parent)
66
	{
67
		this.parent = parent;
68
		properties = new Hashtable();
69
		children = new ArrayList();
70
		idIndexedChildren = new Hashtable();
71
	}
72
	
73
	
74
	/**
75
	 * Creates an instace of this class based on a command passed in.
76
	 * 
77
	 * @param objectMine The object mine that this object will be registered with
78
	 * @param command The command that this object will be based on
79
	 * @param parent The parent of this object
80
	 * 
81
	 * @return An instance of this class based on widgetIdentifier 
82
	 */
83
	public static IUIObject createInstance(IObjectMine objectMine, AbstractMacroCommand command, IUIObject parent)
84
	{
85
		WidgetIdentifier widgetIdentifier = command.getWidgetId();
86
		IUIObject uiObject = new UIObject (parent);
87
		uiObject.setContextId(widgetIdentifier.getContextId() != null ? widgetIdentifier.getContextId().toString() : MacroConstants.EMPTY_STRING);
88
		uiObject.setObjectId(widgetIdentifier.getObjectId().toString());
89
		uiObject.setReferenceId(objectMine.getUniqueReferenceId());
90
		uiObject.setDescriptive(command.getDescriptiveField());
91
		uiObject.setResolver(widgetIdentifier.getResolverId());
92
				
93
		return uiObject;
94
	}
95
	
96
	
97
	public String getContextId()
98
	{
99
		return contextId;
100
	}
101
102
	public String getDescriptive()
103
	{
104
		return descriptive;
105
	}
106
107
	public LinkedList getHierarchicalRelation()
108
	{
109
		if (hierarchicalRelation != null)
110
			return hierarchicalRelation;
111
		
112
		hierarchicalRelation = new LinkedList();
113
		findHierarchicalRelation(this);
114
		
115
		return hierarchicalRelation;
116
	}
117
	
118
	private void findHierarchicalRelation(IUIObject currentObject)
119
	{
120
		if (currentObject == null)
121
			return;
122
		hierarchicalRelation.addFirst(currentObject);
123
		findHierarchicalRelation(currentObject.getParent());
124
	}
125
126
	public String getObjectId()
127
	{
128
		return objectId;
129
	}
130
131
	public Map getProperties()
132
	{
133
		return properties;
134
	}
135
136
	public String getProperty(String name)
137
	{
138
		return (String)properties.get(name);
139
	}
140
141
	public String getReferenceId()
142
	{
143
		return referenceId;
144
	}
145
146
	public void setContextId(String contextId)
147
	{
148
		this.contextId = contextId;
149
	}
150
151
	public void setDescriptive(String descriptive)
152
	{
153
		this.descriptive = descriptive;
154
	}
155
156
	public void setObjectId(String id)
157
	{
158
		this.objectId = id;
159
	}
160
161
	public void addProperty(String name, String value)
162
	{
163
		properties.put(name, value);
164
	}
165
166
	public void setReferenceId(String referenceId)
167
	{
168
		this.referenceId = referenceId;
169
	}
170
	
171
	public IUIObject getParent()
172
	{
173
		return parent;
174
	}
175
176
	public void setParent(IUIObject parent)
177
	{
178
		this.parent = parent;
179
	}
180
181
182
	public String getResolverId()
183
	{		
184
		return resolverId;
185
	}
186
187
188
	public void setResolver(String resolverId)
189
	{
190
		this.resolverId = resolverId;
191
	}
192
193
194
	public void addChild(IUIObject child) throws CoreException
195
	{
196
		if (!children.contains(child))
197
		{
198
			try
199
			{
200
				/* If there is a collision, then try to resolve it */
201
				int referenceId = Integer.parseInt(child.getReferenceId());
202
				while (idIndexedChildren.get(child.getReferenceId()) != null)
203
				{
204
					referenceId++; 
205
				}
206
				child.setReferenceId(String.valueOf(referenceId));
207
			}
208
			catch (NumberFormatException nfe)
209
			{
210
				/* Ignore the error */
211
			}
212
			
213
			/* If there is still a collision, then throw an exception */
214
			if (idIndexedChildren.get(child.getReferenceId()) != null)
215
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID, child.getReferenceId()));
216
			
217
			idIndexedChildren.put(child.getReferenceId(), child);
218
			children.add(child);
219
		}
220
	}
221
222
223
	public int childCount()
224
	{
225
		return children.size();
226
	}
227
228
229
	public IUIObject[] getChildren()
230
	{
231
		IUIObject[] objects = new IUIObject[children.size()];
232
		children.toArray(objects);
233
		return objects;
234
	}
235
236
237
	public IUIObject removeChild(IUIObject child)
238
	{
239
		children.remove(child);
240
		return child;
241
	}
242
243
244
	public Object getData()
245
	{
246
		return data;
247
	}
248
249
250
	public void setData(Object data)
251
	{
252
		this.data = data;
253
	}
254
255
256
	public IUIObject findChild(String referenceId)
257
	{
258
		return (IUIObject) idIndexedChildren.get(referenceId);
259
	}
260
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIMessages.java (-245 / +253 lines)
Lines 1-245 Link Here
1
/********************************************************************** 
1
/********************************************************************** 
2
 * Copyright (c) 2005, 2008 IBM Corporation and others. 
2
 * Copyright (c) 2005, 2009 IBM Corporation and others. 
3
 * All rights reserved.   This program and the accompanying materials 
3
 * All rights reserved.   This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0 
4
 * are made available under the terms of the Eclipse Public License v1.0 
5
 * which accompanies this distribution, and is available at 
5
 * which accompanies this distribution, and is available at 
6
 * http://www.eclipse.org/legal/epl-v10.html         
6
 * http://www.eclipse.org/legal/epl-v10.html         
7
 * $Id: AutoGUIMessages.java,v 1.24 2008/07/14 19:18:57 paules Exp $ 
7
 * $Id: AutoGUIMessages.java,v 1.24 2008/07/14 19:18:57 paules Exp $ 
8
 * 
8
 * 
9
 * Contributors: 
9
 * Contributors: 
10
 * IBM - Initial API and implementation 
10
 * IBM - Initial API and implementation 
11
 **********************************************************************/ 
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal;
12
package org.eclipse.tptp.test.auto.gui.internal;
13
13
14
import org.eclipse.osgi.util.NLS;
14
import org.eclipse.osgi.util.NLS;
15
15
16
/**
16
/**
17
 * AGR resource bundle.
17
 * AGR resource bundle.
18
 * <p>
18
 * <p>
19
 * 
19
 * 
20
 * 
20
 * 
21
 * @author      Paul E. Slauenwhite
21
 * @author      Paul E. Slauenwhite
22
 * @version     July 14, 2008
22
 * @author      Alexander Nyssen
23
 * @since       August 19, 2005
23
 * @version     July 14, 2008
24
 */
24
 * @since       August 19, 2005
25
public class AutoGUIMessages extends NLS {
25
 */
26
26
public class AutoGUIMessages extends NLS {
27
	private static final String BUNDLE_NAME = "org.eclipse.tptp.test.auto.gui.internal.messages";//$NON-NLS-1$
27
28
	
28
	private static final String BUNDLE_NAME = "org.eclipse.tptp.test.auto.gui.internal.messages";//$NON-NLS-1$
29
	private AutoGUIMessages() {
29
	
30
		// Do not instantiate
30
	private AutoGUIMessages() {
31
	}
31
		// Do not instantiate
32
	
32
	}
33
	public static String AUTO_GUI_COMMON_UNKNOWN;
33
	
34
	
34
	public static String AUTO_GUI_COMMON_UNKNOWN;
35
	public static String AUTO_GUI_WIZARD_SRC_PAGE_TITLE;
35
	
36
	public static String AUTO_GUI_WIZARD_SUITE_PG_TTL;
36
	public static String AUTO_GUI_WIZARD_SRC_PAGE_TITLE;
37
	public static String AUTO_GUI_WIZARD_LOC_PG_DSC;
37
	public static String AUTO_GUI_WIZARD_SUITE_PG_TTL;
38
	public static String AUTO_GUI_WIZARD_ATT_PG_DSC;
38
	public static String AUTO_GUI_WIZARD_LOC_PG_DSC;
39
39
	public static String AUTO_GUI_WIZARD_ATT_PG_DSC;
40
	public static String TST_SUITE_AUTO_GENERAL_TITLE;
40
41
	
41
	public static String TST_SUITE_AUTO_GENERAL_TITLE;
42
	public static String TST_SUITE_AUTO_OVERVIEW_OPT;		
42
	
43
	public static String TST_SUITE_AUTO_OVERVIEW_CTX_WS;
43
	public static String TST_SUITE_AUTO_OVERVIEW_OPT;		
44
	public static String TST_SUITE_AUTO_OVERVIEW_CTX;
44
	public static String TST_SUITE_AUTO_OVERVIEW_CTX_WS;
45
	public static String TST_SUITE_AUTO_OVERVIEW_BROWSE; 
45
	public static String TST_SUITE_AUTO_OVERVIEW_CTX;
46
	public static String TST_SUITE_AUTO_OVERVIEW_OPEN;	
46
	public static String TST_SUITE_AUTO_OVERVIEW_BROWSE; 
47
	public static String TST_SUITE_AUTO_OVERVIEW_SRC_LNK;
47
	public static String TST_SUITE_AUTO_OVERVIEW_OPEN;	
48
	public static String TST_SUITE_AUTO_OVERVIEW_CONFIG_T;
48
	public static String TST_SUITE_AUTO_OVERVIEW_SRC_LNK;
49
	public static String TST_SUITE_AUTO_OVERVIEW_WS_C;
49
	public static String TST_SUITE_AUTO_OVERVIEW_CONFIG_T;
50
	public static String TST_SUITE_AUTO_OVERVIEW_ECL_LOC;
50
	public static String TST_SUITE_AUTO_OVERVIEW_WS_C;
51
	public static String TST_SUITE_AUTO_OVERVIEW_WS_LOC;
51
	public static String TST_SUITE_AUTO_OVERVIEW_ECL_LOC;
52
	public static String TST_SUITE_AUTO_OVERVIEW_WS_VAR;
52
	public static String TST_SUITE_AUTO_OVERVIEW_WS_LOC;
53
	public static String TST_SUITE_AUTO_OVERVIEW_JVM_ARG;
53
	public static String TST_SUITE_AUTO_OVERVIEW_WS_VAR;
54
		
54
	public static String TST_SUITE_AUTO_OVERVIEW_JVM_ARG;
55
	public static String TST_SUITE_AUTO_BEHAVIOR_UI;		
55
		
56
	public static String TST_SUITE_AUTO_BEHAVIOR_LTD;	
56
	public static String TST_SUITE_AUTO_BEHAVIOR_UI;		
57
	public static String TST_SUITE_AUTO_BEHAVIOR_LTCI;
57
	public static String TST_SUITE_AUTO_BEHAVIOR_LTD;	
58
	public static String TST_SUITE_AUTO_BEHAVIOR_BL;
58
	public static String TST_SUITE_AUTO_BEHAVIOR_LTCI;
59
	public static String TST_SUITE_AUTO_BEHAVIOR_TIMEOUT;
59
	public static String TST_SUITE_AUTO_BEHAVIOR_BL;
60
	public static String TST_SUITE_AUTO_BEHAVIOR_TIME_T;
60
	public static String TST_SUITE_AUTO_BEHAVIOR_TIMEOUT;
61
	public static String TST_SUITE_AUTO_BEHAVIOR_TIME;
61
	public static String TST_SUITE_AUTO_BEHAVIOR_TIME_T;
62
	
62
	public static String TST_SUITE_AUTO_BEHAVIOR_TIME;
63
	public static String TST_SUITE_AUTO_MACRO_TESTS;
63
	
64
	public static String TST_SUITE_AUTO_MACRO_MACRO;
64
	public static String TST_SUITE_AUTO_MACRO_TESTS;
65
	public static String TST_SUITE_AUTO_MACRO_LINE_NUM;
65
	public static String TST_SUITE_AUTO_MACRO_MACRO;
66
	public static String TST_SUITE_AUTO_MACRO_DELETE;
66
	public static String TST_SUITE_AUTO_MACRO_LINE_NUM;
67
	public static String TST_SUITE_AUTO_MACRO_REFRESH;
67
	public static String TST_SUITE_AUTO_MACRO_DELETE;
68
	public static String TST_SUITE_AUTO_MACRO_SHELL;
68
	public static String TST_SUITE_AUTO_MACRO_REFRESH;
69
	public static String TST_SUITE_AUTO_MACRO_SECONDS;
69
	public static String TST_SUITE_AUTO_MACRO_SHELL;
70
	public static String TST_SUITE_AUTO_MACRO_RECORD;
70
	public static String TST_SUITE_AUTO_MACRO_SECONDS;
71
	public static String TST_SUITE_AUTO_MACRO_UP;
71
	public static String TST_SUITE_AUTO_MACRO_RECORD;
72
	public static String TST_SUITE_AUTO_MACRO_DOWN;
72
	public static String TST_SUITE_AUTO_MACRO_UP;
73
	public static String TST_SUITE_AUTO_MACRO_OBJ_MINE;
73
	public static String TST_SUITE_AUTO_MACRO_DOWN;
74
	public static String TST_SUITE_AUTO_MACRO_OBJ_OBJECT;
74
	public static String TST_SUITE_AUTO_MACRO_OBJ_MINE;
75
	public static String TST_SUITE_AUTO_MACRO_MESSAGE;
75
	public static String TST_SUITE_AUTO_MACRO_OBJ_OBJECT;
76
	public static String TST_SUITE_AUTO_MACRO_INSTRUCTION;
76
	public static String TST_SUITE_AUTO_MACRO_MESSAGE;
77
	public static String TST_SUITE_AUTO_MACRO_TEST_CASE;
77
	public static String TST_SUITE_AUTO_MACRO_INSTRUCTION;
78
	public static String TST_SUITE_AUTO_MACRO_UPDATE;
78
	public static String TST_SUITE_AUTO_MACRO_TEST_CASE;
79
	public static String TST_SUITE_AUTO_MACRO_FIND;
79
	public static String TST_SUITE_AUTO_MACRO_UPDATE;
80
	
80
	public static String TST_SUITE_AUTO_MACRO_FIND;
81
	public static String AUTO_GUI_EDT_QUICK_RUN_TOOL_TIP; 
81
	
82
82
	public static String AUTO_GUI_EDT_QUICK_RUN_TOOL_TIP; 
83
	public static String AUTO_GUI_TST_CASE_UPDATE_TITLE;
83
84
	public static String AUTO_GUI_TST_CASE_UPDATE;
84
	public static String AUTO_GUI_TST_CASE_UPDATE_TITLE;
85
	public static String AUTO_GUI_TST_CASE_NO_UPDATE;
85
	public static String AUTO_GUI_TST_CASE_UPDATE;
86
	
86
	public static String AUTO_GUI_TST_CASE_NO_UPDATE;
87
	public static String AUTO_GUI_NEW_TEST_CASE;          
87
	
88
	public static String AUTO_GUI_NEW_DIALOG_NAME; 	
88
	public static String AUTO_GUI_NEW_TEST_CASE;          
89
	public static String AUTO_GUI_NEW_DIALOG_DESC;		
89
	public static String AUTO_GUI_NEW_DIALOG_NAME; 	
90
	public static String AUTO_GUI_NEW_DIALOG_STPT;				
90
	public static String AUTO_GUI_NEW_DIALOG_DESC;		
91
	public static String AUTO_GUI_NEW_DIALOG_DEFAULT_NAME;
91
	public static String AUTO_GUI_NEW_DIALOG_STPT;				
92
	public static String AUTO_GUI_NEW_DIALOG_OPTIONS;
92
	public static String AUTO_GUI_NEW_DIALOG_DEFAULT_NAME;
93
	public static String AUTO_GUI_NEW_DIALOG_USE_OM;
93
	public static String AUTO_GUI_NEW_DIALOG_OPTIONS;
94
	public static String AUTO_GUI_NEW_DIALOG_USE_TC;
94
	public static String AUTO_GUI_NEW_DIALOG_USE_OM;
95
	
95
	public static String AUTO_GUI_NEW_DIALOG_USE_TC;
96
	public static String AUTO_GUI_COMMON_OK;			
96
	
97
	public static String AUTO_GUI_COMMON_CANCEL;
97
	public static String AUTO_GUI_COMMON_OK;			
98
	public static String AUTO_GUI_COMMON_COPY;
98
	public static String AUTO_GUI_COMMON_CANCEL;
99
	public static String AUTO_GUI_COMMON_ERROR;
99
	public static String AUTO_GUI_COMMON_COPY;
100
	public static String AUTO_GUI_COMMON_INFORMATION;
100
	public static String AUTO_GUI_COMMON_ERROR;
101
101
	public static String AUTO_GUI_COMMON_INFORMATION;
102
	public static String AUTO_GUI_DP_DIALOG_DP_SHELL_T;	
102
103
	public static String AUTO_GUI_DP_DIALOG_DP_AVAIL_LBL; 
103
	public static String AUTO_GUI_DP_DIALOG_DP_SHELL_T;	
104
	public static String AUTO_GUI_DP_DIALOG_DP_NAME_COL;	
104
	public static String AUTO_GUI_DP_DIALOG_DP_AVAIL_LBL; 
105
	public static String AUTO_GUI_DP_DIALOG_DPC_CONTENT;	
105
	public static String AUTO_GUI_DP_DIALOG_DP_NAME_COL;	
106
	public static String AUTO_GUI_DP_DIALOG_DPC_VAR_COL;	
106
	public static String AUTO_GUI_DP_DIALOG_DPC_CONTENT;	
107
	public static String AUTO_GUI_DP_DIALOG_DPC_VAR_N_COL;
107
	public static String AUTO_GUI_DP_DIALOG_DPC_VAR_COL;	
108
	
108
	public static String AUTO_GUI_DP_DIALOG_DPC_VAR_N_COL;
109
	public static String AUTO_GUI_CILINK_DIALOG_SHELL_T;	
109
	
110
	public static String AUTO_GUI_CILINK_DIALOG_ADD_VAR;
110
	public static String AUTO_GUI_CILINK_DIALOG_SHELL_T;	
111
	public static String AUTO_GUI_CILINK_VAR_CONTEXT_WS;
111
	public static String AUTO_GUI_CILINK_DIALOG_ADD_VAR;
112
	public static String AUTO_GUI_CILINK_VAR_TS_PROJECT;
112
	public static String AUTO_GUI_CILINK_VAR_CONTEXT_WS;
113
	
113
	public static String AUTO_GUI_CILINK_VAR_TS_PROJECT;
114
	public static String AUTO_GUI_TST_DIALOG_TREE_LABEL;
114
	
115
	public static String AUTO_GUI_TST_DIALOG_TREE_ITITLE;
115
	public static String AUTO_GUI_TST_DIALOG_TREE_LABEL;
116
	public static String AUTO_GUI_TST_DIALOG_TREE_INCL;
116
	public static String AUTO_GUI_TST_DIALOG_TREE_ITITLE;
117
	public static String AUTO_GUI_TST_DIALOG_TREE_OUPUT;
117
	public static String AUTO_GUI_TST_DIALOG_TREE_INCL;
118
	
118
	public static String AUTO_GUI_TST_DIALOG_TREE_OUPUT;
119
	public static String AUTO_GUI_MACRO_EXECUTING;		
119
	
120
	public static String AUTO_GUI_MACRO_WAITING;			
120
	public static String AUTO_GUI_MACRO_EXECUTING;		
121
121
	public static String AUTO_GUI_MACRO_WAITING;			
122
	public static String AUTO_GUI_ERROR_DP_PROJ_NF;		
122
123
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_LD_T;	
123
	public static String AUTO_GUI_ERROR_DP_PROJ_NF;		
124
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_LD;	
124
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_LD_T;	
125
	public static String AUTO_GUI_ERROR_DP_NO_SELECT_T;	
125
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_LD;	
126
	public static String AUTO_GUI_ERROR_DP_NO_SELECT;		
126
	public static String AUTO_GUI_ERROR_DP_NO_SELECT_T;	
127
	public static String AUTO_GUI_ERROR_DP_DATAPOOL;		
127
	public static String AUTO_GUI_ERROR_DP_NO_SELECT;		
128
	public static String AUTO_GUI_ERROR_DP_RECORD_NO;		
128
	public static String AUTO_GUI_ERROR_DP_DATAPOOL;		
129
	public static String AUTO_GUI_ERROR_DP_VARIABLE_NAME; 
129
	public static String AUTO_GUI_ERROR_DP_RECORD_NO;		
130
	public static String AUTO_GUI_ERROR_DP_NOT_FOUND;
130
	public static String AUTO_GUI_ERROR_DP_VARIABLE_NAME; 
131
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_NF_T;
131
	public static String AUTO_GUI_ERROR_DP_NOT_FOUND;
132
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_NF;
132
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_NF_T;
133
133
	public static String AUTO_GUI_ERROR_DP_DATAPOOL_NF;
134
	public static String AUTO_GUI_ERROR_DIALOG_TST_INCL;
134
135
	
135
	public static String AUTO_GUI_ERROR_DIALOG_TST_INCL;
136
	public static String AUTO_GUI_ERROR_NEW_NOT_PLUGIN;	
136
	
137
	public static String AUTO_GUI_ERROR_NEW_NOT_SRC;
137
	public static String AUTO_GUI_ERROR_NEW_NOT_PLUGIN;	
138
138
	public static String AUTO_GUI_ERROR_NEW_NOT_SRC;
139
	public static String AUTO_GUI_ERROR_PERS_SWITCH_TITLE;
139
140
	public static String AUTO_GUI_ERROR_PERS_SWITCH;		
140
	public static String AUTO_GUI_ERROR_PERS_SWITCH_TITLE;
141
141
	public static String AUTO_GUI_ERROR_PERS_SWITCH;		
142
	public static String AUTO_GUI_ERROR_MACRO_REC_TITLE;
142
143
	public static String AUTO_GUI_ERROR_MACRO_REC;
143
	public static String AUTO_GUI_ERROR_MACRO_REC_TITLE;
144
	public static String AUTO_GUI_ERROR_MACRO_STOP_TITLE; 
144
	public static String AUTO_GUI_ERROR_MACRO_REC;
145
	public static String AUTO_GUI_ERROR_MACRO_STOP;		
145
	public static String AUTO_GUI_ERROR_MACRO_STOP_TITLE; 
146
	public static String AUTO_GUI_ERROR_MACRO_GENERATE_T;	
146
	public static String AUTO_GUI_ERROR_MACRO_STOP;		
147
	public static String AUTO_GUI_ERROR_MACRO_GENERATE;	
147
	public static String AUTO_GUI_ERROR_MACRO_GENERATE_T;	
148
	public static String AUTO_GUI_ERROR_MACRO_RUNNING_T;	
148
	public static String AUTO_GUI_ERROR_MACRO_GENERATE;	
149
	public static String AUTO_GUI_ERROR_MACRO_RUNNING;	
149
	public static String AUTO_GUI_ERROR_MACRO_RUNNING_T;	
150
	public static String AUTO_GUI_ERROR_MACRO_INITIALIZE;
150
	public static String AUTO_GUI_ERROR_MACRO_RUNNING;	
151
	public static String AUTO_GUI_ERROR_MACRO_UNCAP_T;	
151
	public static String AUTO_GUI_ERROR_MACRO_INITIALIZE;
152
	public static String AUTO_GUI_ERROR_MACRO_UNCAP;		
152
	public static String AUTO_GUI_ERROR_MACRO_UNCAP_T;	
153
	public static String AUTO_GUI_ERROR_MACRO_COMMAND;	
153
	public static String AUTO_GUI_ERROR_MACRO_UNCAP;		
154
	public static String AUTO_GUI_ERROR_MACRO_MENU;		
154
	public static String AUTO_GUI_ERROR_MACRO_COMMAND;	
155
	public static String AUTO_GUI_ERROR_MACRO_TOOL;		
155
	public static String AUTO_GUI_ERROR_MACRO_MENU;		
156
	public static String AUTO_GUI_ERROR_MACRO_TOOL_BAR;	
156
	public static String AUTO_GUI_ERROR_MACRO_TOOL;		
157
	public static String AUTO_GUI_ERROR_MACRO_WIZARD;		
157
	public static String AUTO_GUI_ERROR_MACRO_TOOL_BAR;	
158
	public static String AUTO_GUI_ERROR_MACRO_WIZARD_CON; 
158
	public static String AUTO_GUI_ERROR_MACRO_TAB;
159
	public static String AUTO_GUI_ERROR_MACRO_SHELL;		
159
	public static String AUTO_GUI_ERROR_MACRO_WIZARD;		
160
	public static String AUTO_GUI_ERROR_MACRO_SHELL_DIS;	
160
	public static String AUTO_GUI_ERROR_MACRO_WIZARD_CON; 
161
	public static String AUTO_GUI_ERROR_MACRO_VIEW;		
161
	public static String AUTO_GUI_ERROR_MACRO_SHELL;		
162
	public static String AUTO_GUI_ERROR_MACRO_VIEW_CON;	
162
	public static String AUTO_GUI_ERROR_MACRO_SHELL_DIS;	
163
	public static String AUTO_GUI_ERROR_MACRO_EDITOR;		
163
	public static String AUTO_GUI_ERROR_MACRO_VIEW;		
164
	public static String AUTO_GUI_ERROR_MACRO_EDITOR_CON; 
164
	public static String AUTO_GUI_ERROR_MACRO_VIEW_CON;	
165
	public static String AUTO_GUI_ERROR_MACRO_GENERAL;	
165
	public static String AUTO_GUI_ERROR_MACRO_EDITOR;		
166
	public static String AUTO_GUI_ERROR_MACRO_MISS_SP_T;	
166
	public static String AUTO_GUI_ERROR_MACRO_EDITOR_CON; 
167
	public static String AUTO_GUI_ERROR_MACRO_MISS_SP;	
167
	public static String AUTO_GUI_ERROR_MACRO_GENERAL;	
168
	public static String AUTO_GUI_ERROR_MACRO_PARSING;	
168
	public static String AUTO_GUI_ERROR_MACRO_MISS_SP_T;	
169
	public static String AUTO_GUI_ERROR_MACRO_TIME_OUT;
169
	public static String AUTO_GUI_ERROR_MACRO_MISS_SP;	
170
	public static String AUTO_GUI_ERROR_MACRO_NEST_TOUT;
170
	public static String AUTO_GUI_ERROR_MACRO_PARSING;	
171
	public static String AUTO_GUI_ERROR_MACRO_DISABLE;
171
	public static String AUTO_GUI_ERROR_MACRO_TIME_OUT;
172
	public static String AUTO_GUI_ERROR_MACRO_ITEM;
172
	public static String AUTO_GUI_ERROR_MACRO_NEST_TOUT;
173
173
	public static String AUTO_GUI_ERROR_MACRO_DISABLE;
174
	public static String AUTO_GUI_ERROR_OBJ_MINE_NF;
174
	public static String AUTO_GUI_ERROR_MACRO_ITEM;
175
	public static String AUTO_GUI_ERROR_OBJ_MINE_OUTPUT;
175
176
	public static String AUTO_GUI_ERROR_OBJ_MINE_OUT_NF;
176
	public static String AUTO_GUI_ERROR_OBJ_MINE_NF;
177
	
177
	public static String AUTO_GUI_ERROR_OBJ_MINE_OUTPUT;
178
	public static String AUTO_GUI_ERROR_VER_NOT_SUPP_CON;
178
	public static String AUTO_GUI_ERROR_OBJ_MINE_OUT_NF;
179
	public static String AUTO_GUI_ERROR_VER_WRONG_EVENT;	
179
	
180
	public static String AUTO_GUI_ERROR_VER_INVALID_NM_T; 
180
	public static String AUTO_GUI_ERROR_VER_NOT_SUPP_CON;
181
	public static String AUTO_GUI_ERROR_VER_INVALID_NM;	
181
	public static String AUTO_GUI_ERROR_VER_WRONG_EVENT;	
182
	public static String AUTO_GUI_ERROR_VER_GEN_SRC_T;	
182
	public static String AUTO_GUI_ERROR_VER_INVALID_NM_T; 
183
	public static String AUTO_GUI_ERROR_VER_GEN_SRC;	
183
	public static String AUTO_GUI_ERROR_VER_INVALID_NM;	
184
	public static String AUTO_GUI_ERROR_VER_GEN_METHOD_T;	
184
	public static String AUTO_GUI_ERROR_VER_GEN_SRC_T;	
185
	public static String AUTO_GUI_ERROR_VER_GEN_METHOD;	
185
	public static String AUTO_GUI_ERROR_VER_GEN_SRC;	
186
	public static String AUTO_GUI_ERROR_VER_TOP_SHELL_T;	
186
	public static String AUTO_GUI_ERROR_VER_GEN_METHOD_T;	
187
	public static String AUTO_GUI_ERROR_VER_TOP_SHELL;	
187
	public static String AUTO_GUI_ERROR_VER_GEN_METHOD;	
188
	public static String AUTO_GUI_ERROR_VER_CONTEXT;		
188
	public static String AUTO_GUI_ERROR_VER_TOP_SHELL_T;	
189
	public static String AUTO_GUI_ERROR_VER_CLASS_NOT_F;	
189
	public static String AUTO_GUI_ERROR_VER_TOP_SHELL;	
190
	public static String AUTO_GUI_ERROR_VER_CLASS_NOT_FS;	
190
	public static String AUTO_GUI_ERROR_VER_CONTEXT;		
191
	public static String AUTO_GUI_ERROR_VER_ARG_EXCEPT;	
191
	public static String AUTO_GUI_ERROR_VER_CLASS_NOT_F;	
192
	public static String AUTO_GUI_ERROR_VER_INSTANTIATE;	
192
	public static String AUTO_GUI_ERROR_VER_CLASS_NOT_FS;	
193
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY_T; 
193
	public static String AUTO_GUI_ERROR_VER_ARG_EXCEPT;	
194
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY;	
194
	public static String AUTO_GUI_ERROR_VER_INSTANTIATE;	
195
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY_W; 
195
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY_T; 
196
	public static String AUTO_GUI_ERROR_VER_METHOD_NF_T;	
196
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY;	
197
	public static String AUTO_GUI_ERROR_VER_METHOD_NF;
197
	public static String AUTO_GUI_ERROR_VER_DEPENDENCY_W; 
198
	public static String AUTO_GUI_ERROR_VER_METHOD_NOT_F;
198
	public static String AUTO_GUI_ERROR_VER_METHOD_NF_T;	
199
	public static String AUTO_GUI_ERROR_VER_METHOD_MODIF;
199
	public static String AUTO_GUI_ERROR_VER_METHOD_NF;
200
200
	public static String AUTO_GUI_ERROR_VER_METHOD_NOT_F;
201
	public static String AUTO_GUI_ERROR_PLAYBACK_PROP_T;  
201
	public static String AUTO_GUI_ERROR_VER_METHOD_MODIF;
202
	public static String AUTO_GUI_ERROR_PLAYBACK_PROP;    
202
203
	public static String AUTO_GUI_ERROR_PLAYBACK_SCRIPT;	
203
	public static String AUTO_GUI_ERROR_PLAYBACK_PROP_T;  
204
204
	public static String AUTO_GUI_ERROR_PLAYBACK_PROP;    
205
	public static String AUTO_GUI_ERROR_WID_RESOLVER_T;	
205
	public static String AUTO_GUI_ERROR_PLAYBACK_SCRIPT;	
206
	public static String AUTO_GUI_ERROR_WID_RESOLVER;		
206
207
207
	public static String AUTO_GUI_ERROR_WID_RESOLVER_T;	
208
	public static String AUTO_GUI_ERROR_TST_PATH_SEG;
208
	public static String AUTO_GUI_ERROR_WID_RESOLVER;		
209
	public static String AUTO_GUI_ERROR_TST_WRONG_PROJ;
209
210
	public static String AUTO_GUI_ERROR_TST_WRONG_SRC;
210
	public static String AUTO_GUI_ERROR_TST_PATH_SEG;
211
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_T;
211
	public static String AUTO_GUI_ERROR_TST_WRONG_PROJ;
212
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE;
212
	public static String AUTO_GUI_ERROR_TST_WRONG_SRC;
213
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_REF;
213
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_T;
214
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_ID;
214
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE;
215
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_REG;
215
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_REF;
216
	
216
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_ID;
217
	public static String AUTO_GUI_ERROR_TST_MACRO_XML;
217
	public static String AUTO_GUI_ERROR_TST_OBJ_MINE_REG;
218
	
218
	
219
	public static String AUTO_GUI_CONTROL_DIALOG_TITLE; 
219
	public static String AUTO_GUI_ERROR_TST_MACRO_XML;
220
	public static String AUTO_GUI_CONTROL_VER_HOOK;		
220
	
221
	public static String AUTO_GUI_CONTROL_VER_INSERT;		
221
	public static String AUTO_GUI_CONTROL_DIALOG_TITLE; 
222
	public static String AUTO_GUI_CONTROL_TERMINATE;		
222
	public static String AUTO_GUI_CONTROL_VER_HOOK;		
223
	public static String AUTO_GUI_CONTROL_RESTART;
223
	public static String AUTO_GUI_CONTROL_VER_INSERT;
224
	public static String AUTO_GUI_CONTROL_POSITION_BASED;
224
	public static String AUTO_GUI_CONTROL_VER_INCLUDE_UI_OBJECT;	
225
	public static String AUTO_GUI_CONTROL_WAIT_TIME;
225
	public static String AUTO_GUI_CONTROL_TERMINATE;		
226
	public static String AUTO_GUI_CONTROL_RESTART_MSG_T;	
226
	public static String AUTO_GUI_CONTROL_RESTART;
227
	public static String AUTO_GUI_CONTROL_RESTART_MSG;	
227
	public static String AUTO_GUI_CONTROL_POSITION_BASED;
228
	public static String AUTO_GUI_CONTROL_CONT;			
228
	public static String AUTO_GUI_CONTROL_WAIT_TIME;
229
	public static String AUTO_GUI_CONTROL_STATUS_BASE;	
229
	public static String AUTO_GUI_CONTROL_RESTART_MSG_T;	
230
	public static String AUTO_GUI_CONTROL_STATUS_REC;		
230
	public static String AUTO_GUI_CONTROL_RESTART_MSG;	
231
	public static String AUTO_GUI_CONTROL_STATUS_VER; 
231
	public static String AUTO_GUI_CONTROL_CONT;			
232
	public static String AUTO_GUI_CONTROL_STATUS_INS;		
232
	public static String AUTO_GUI_CONTROL_STATUS_BASE;	
233
	public static String AUTO_GUI_CONTROL_STATUS_GEN;		
233
	public static String AUTO_GUI_CONTROL_STATUS_REC;		
234
	public static String AUTO_GUI_CONTROL_STATUS_POS;
234
	public static String AUTO_GUI_CONTROL_STATUS_VER; 
235
	public static String AUTO_GUI_CONTROL_STATUS_BROWSE;
235
	public static String AUTO_GUI_CONTROL_STATUS_INS;		
236
	
236
	public static String AUTO_GUI_CONTROL_STATUS_GEN;		
237
	public static String AUTO_GUI_DETAILS_STARTPT;	
237
	public static String AUTO_GUI_CONTROL_STATUS_POS;
238
	
238
	public static String AUTO_GUI_CONTROL_STATUS_BROWSE;
239
	public static String AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL;
239
	
240
	
240
	public static String AUTO_GUI_DETAILS_STARTPT;	
241
	static {
241
	
242
		NLS.initializeMessages(BUNDLE_NAME, AutoGUIMessages.class);
242
	public static String AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL;
243
	}
243
	
244
}
244
	public static String AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE;
245
245
	
246
	public static String AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS;
247
	public static String AUTO_GUI_RESOLVER_IDENTIFIER_MISSING;
248
	
249
	static {
250
		NLS.initializeMessages(BUNDLE_NAME, AutoGUIMessages.class);
251
	}
252
}
253
(-)src/org/eclipse/tptp/test/auto/gui/internal/messages.properties (+7 lines)
Lines 226-228 Link Here
226
AUTO_GUI_DETAILS_STARTPT		= Starting Point:
226
AUTO_GUI_DETAILS_STARTPT		= Starting Point:
227
227
228
AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL = Undoable Text Operation
228
AUTO_GUI_UNDOABLE_TEXT_OPERATION_LABEL = Undoable Text Operation
229
230
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.
231
AUTO_GUI_ERROR_MACRO_TAB        = Cannot locate tab item: {0}
232
AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE = The macro object {0} could not be resolved.
233
AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS = The UI object with widget id {0} and object id {1} could not be unambigously identified.
234
AUTO_GUI_RESOLVER_IDENTIFIER_MISSING = The resolver {0} did not set its id on the resolved UI object identifier.
235
(-)src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIUtil.java (-641 / +651 lines)
Lines 1-642 Link Here
1
/**********************************************************************
1
/**********************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved.   This program and the accompanying materials
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUIUtil.java,v 1.10 2006/08/08 17:56:06 amehregani Exp $
7
 * $Id: AutoGUIUtil.java,v 1.10 2006/08/08 17:56:06 amehregani Exp $
8
 * 
8
 * 
9
 * Contributors: 
9
 * Contributors: 
10
 * IBM - Initial API and implementation
10
 * IBM - Initial API and implementation
11
 **********************************************************************/
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal;
12
package org.eclipse.tptp.test.auto.gui.internal;
13
13
14
import java.io.File;
14
import java.io.File;
15
import java.io.PrintWriter;
15
import java.io.PrintWriter;
16
import java.io.StringWriter;
16
import java.io.StringWriter;
17
import java.lang.reflect.InvocationTargetException;
17
import java.lang.reflect.InvocationTargetException;
18
import java.util.ArrayList;
18
import java.util.ArrayList;
19
import java.util.Hashtable;
19
import java.util.Hashtable;
20
import java.util.List;
20
import java.util.List;
21
import java.util.Map;
21
import java.util.Map;
22
import java.util.StringTokenizer;
22
import java.util.StringTokenizer;
23
import java.util.Vector;
23
import java.util.Vector;
24
24
25
import org.eclipse.core.resources.IFile;
25
import org.eclipse.core.resources.IFile;
26
import org.eclipse.core.resources.IProject;
26
import org.eclipse.core.resources.IProject;
27
import org.eclipse.core.resources.IWorkspaceRoot;
27
import org.eclipse.core.resources.IWorkspaceRoot;
28
import org.eclipse.core.resources.ResourcesPlugin;
28
import org.eclipse.core.resources.ResourcesPlugin;
29
import org.eclipse.core.runtime.CoreException;
29
import org.eclipse.core.runtime.CoreException;
30
import org.eclipse.core.runtime.IPath;
30
import org.eclipse.core.runtime.IPath;
31
import org.eclipse.core.runtime.IStatus;
31
import org.eclipse.core.runtime.IStatus;
32
import org.eclipse.core.runtime.Path;
32
import org.eclipse.core.runtime.Path;
33
import org.eclipse.core.runtime.Platform;
33
import org.eclipse.core.runtime.Platform;
34
import org.eclipse.core.runtime.Status;
34
import org.eclipse.core.runtime.Status;
35
import org.eclipse.emf.ecore.EObject;
35
import org.eclipse.emf.ecore.EObject;
36
import org.eclipse.hyades.models.common.facades.behavioral.IImplementor;
36
import org.eclipse.hyades.models.common.facades.behavioral.IImplementor;
37
import org.eclipse.hyades.models.common.facades.behavioral.IProperty;
37
import org.eclipse.hyades.models.common.facades.behavioral.IProperty;
38
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
38
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
39
import org.eclipse.hyades.test.core.util.EMFUtil;
39
import org.eclipse.hyades.test.core.util.EMFUtil;
40
import org.eclipse.jdt.core.IClasspathContainer;
40
import org.eclipse.jdt.core.IClasspathContainer;
41
import org.eclipse.jdt.core.IClasspathEntry;
41
import org.eclipse.jdt.core.IClasspathEntry;
42
import org.eclipse.jdt.core.IJavaProject;
42
import org.eclipse.jdt.core.IJavaProject;
43
import org.eclipse.jdt.core.JavaCore;
43
import org.eclipse.jdt.core.JavaCore;
44
import org.eclipse.jface.dialogs.ErrorDialog;
44
import org.eclipse.jface.dialogs.ErrorDialog;
45
import org.eclipse.jface.dialogs.IDialogConstants;
45
import org.eclipse.jface.dialogs.IDialogConstants;
46
import org.eclipse.jface.dialogs.MessageDialog;
46
import org.eclipse.jface.dialogs.MessageDialog;
47
import org.eclipse.osgi.util.NLS;
47
import org.eclipse.osgi.util.NLS;
48
import org.eclipse.swt.SWT;
48
import org.eclipse.swt.SWT;
49
import org.eclipse.swt.dnd.Clipboard;
49
import org.eclipse.swt.dnd.Clipboard;
50
import org.eclipse.swt.dnd.TextTransfer;
50
import org.eclipse.swt.dnd.TextTransfer;
51
import org.eclipse.swt.dnd.Transfer;
51
import org.eclipse.swt.dnd.Transfer;
52
import org.eclipse.swt.events.SelectionEvent;
52
import org.eclipse.swt.events.SelectionEvent;
53
import org.eclipse.swt.events.SelectionListener;
53
import org.eclipse.swt.events.SelectionListener;
54
import org.eclipse.swt.graphics.Image;
54
import org.eclipse.swt.graphics.Image;
55
import org.eclipse.swt.layout.GridData;
55
import org.eclipse.swt.layout.GridData;
56
import org.eclipse.swt.widgets.Composite;
56
import org.eclipse.swt.widgets.Composite;
57
import org.eclipse.swt.widgets.Menu;
57
import org.eclipse.swt.widgets.Menu;
58
import org.eclipse.swt.widgets.MenuItem;
58
import org.eclipse.swt.widgets.MenuItem;
59
import org.eclipse.swt.widgets.Shell;
59
import org.eclipse.swt.widgets.Shell;
60
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
60
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
61
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
61
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
62
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
62
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
63
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
63
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
64
import org.eclipse.ui.IWorkbench;
64
import org.eclipse.ui.IWorkbench;
65
import org.eclipse.ui.PlatformUI;
65
import org.eclipse.ui.PlatformUI;
66
import org.osgi.framework.Bundle;
66
import org.osgi.framework.Bundle;
67
import org.w3c.dom.Element;
67
import org.w3c.dom.Element;
68
import org.w3c.dom.Node;
68
import org.w3c.dom.Node;
69
import org.w3c.dom.NodeList;
69
import org.w3c.dom.NodeList;
70
70
71
/**
71
/**
72
 * A primitive utility class that is commonly shared between the auto gui classes
72
 * A primitive utility class that is commonly shared between the auto gui classes
73
 * 
73
 * 
74
 * @author Ali Mehregani
74
 * @author Ali Mehregani
75
 */
75
 * @author Alexander Nyssen
76
public class AutoGUIUtil
76
 */
77
{
77
public class AutoGUIUtil
78
	/**
78
{
79
	 * Find the plugin name from the path that is passed in
79
	/**
80
	 * 
80
	 * Find the plugin name from the path that is passed in
81
	 * @param The classpath entry representing the plugin
81
	 * 
82
	 * @return The bundle representing the plugin.  Null if it can't be
82
	 * @param The classpath entry representing the plugin
83
	 * recognized.
83
	 * @return The bundle representing the plugin.  Null if it can't be
84
	 */
84
	 * recognized.
85
	public static String findPlugin (String path)
85
	 */
86
	{
86
	public static String findPlugin (String path)
87
		String currentToken;
87
	{
88
		int inx = path.lastIndexOf('/');
88
		String currentToken;
89
		
89
		int inx = path.lastIndexOf('/');
90
		while (inx != -1)
90
		
91
		{
91
		while (inx != -1)
92
			currentToken = path.substring(inx + 1, path.length());
92
		{
93
			if (currentToken.endsWith(".jar") && currentToken.length() > 4)
93
			currentToken = path.substring(inx + 1, path.length());
94
				currentToken = currentToken.substring(0, currentToken.length() - 4);
94
			if (currentToken.endsWith(".jar") && currentToken.length() > 4)
95
			int versionInx = currentToken.indexOf('_');
95
				currentToken = currentToken.substring(0, currentToken.length() - 4);
96
			if (versionInx != -1)
96
			int versionInx = currentToken.indexOf('_');
97
				currentToken = currentToken.substring(0, versionInx);
97
			if (versionInx != -1)
98
			
98
				currentToken = currentToken.substring(0, versionInx);
99
			Bundle bundle = Platform.getBundle(currentToken);
99
			
100
			if (bundle != null)
100
			Bundle bundle = Platform.getBundle(currentToken);
101
				return currentToken;
101
			if (bundle != null)
102
							
102
				return currentToken;
103
			path = path.substring(0, inx);
103
							
104
			inx = path.lastIndexOf('/');
104
			path = path.substring(0, inx);
105
		}
105
			inx = path.lastIndexOf('/');
106
		
106
		}
107
		return null;
107
		
108
	}
108
		return null;
109
	
109
	}
110
	
110
	
111
	/**
111
	
112
	 * A helper method with a dual purpose:  Used to return the classpath of the project containing the test suite
112
	/**
113
	 * and stores the required plugins of the project in 'reqPlugins'.
113
	 * A helper method with a dual purpose:  Used to return the classpath of the project containing the test suite
114
	 * 
114
	 * and stores the required plugins of the project in 'reqPlugins'.
115
	 * @param javaProject The project containing the test suite.
115
	 * 
116
	 * @param reqPlugins A vector used to store the required plugins
116
	 * @param javaProject The project containing the test suite.
117
	 * @param isClassPathReq returns the class if set; othewise null is returned.
117
	 * @param reqPlugins A vector used to store the required plugins
118
	 * 
118
	 * @param isClassPathReq returns the class if set; othewise null is returned.
119
	 * @return The classpath of the project
119
	 * 
120
	 * @throws CoreException if any errors occur in retrieving the classpath
120
	 * @return The classpath of the project
121
	 */
121
	 * @throws CoreException if any errors occur in retrieving the classpath
122
	public static String findDependencies (IJavaProject javaProject, Vector reqPlugins, boolean isClassPathRes) throws CoreException
122
	 */
123
	{
123
	public static String findDependencies (IJavaProject javaProject, Vector reqPlugins, boolean isClassPathRes) throws CoreException
124
		try
124
	{
125
		{
125
		try
126
			IClasspathEntry[] classpath = javaProject.getRawClasspath();
126
		{
127
			String classPath = "";
127
			IClasspathEntry[] classpath = javaProject.getRawClasspath();
128
			
128
			String classPath = "";
129
			for (int i  = 0; i < classpath.length; i++)
129
			
130
			{
130
			for (int i  = 0; i < classpath.length; i++)
131
				if (classpath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
131
			{
132
				{
132
				if (classpath[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
133
					/* Find the required plugins of this container */
133
				{
134
					if (classpath[i].getPath().toString().equalsIgnoreCase("org.eclipse.pde.core.requiredPlugins"))
134
					/* Find the required plugins of this container */
135
					{
135
					if (classpath[i].getPath().toString().equalsIgnoreCase("org.eclipse.pde.core.requiredPlugins"))
136
						IClasspathContainer container = JavaCore.getClasspathContainer(classpath[i].getPath(), javaProject);
136
					{
137
						IClasspathEntry[] classEntries = container.getClasspathEntries();
137
						IClasspathContainer container = JavaCore.getClasspathContainer(classpath[i].getPath(), javaProject);
138
						for (int j = 0; j < classEntries.length; j++)
138
						IClasspathEntry[] classEntries = container.getClasspathEntries();
139
						{
139
						for (int j = 0; j < classEntries.length; j++)
140
							String pluginName = AutoGUIUtil.findPlugin(classEntries[j].getPath().toString());
140
						{
141
							if (pluginName != null)
141
							String pluginName = AutoGUIUtil.findPlugin(classEntries[j].getPath().toString());
142
								reqPlugins.add(pluginName);
142
							if (pluginName != null)
143
						}																
143
								reqPlugins.add(pluginName);
144
					}
144
						}																
145
					
145
					}
146
					/* Not interested in adding the container to our classpath */
146
					
147
					continue;
147
					/* Not interested in adding the container to our classpath */
148
					
148
					continue;
149
				}
149
					
150
				
150
				}
151
				if (isClassPathRes)
151
				
152
				{
152
				if (isClassPathRes)
153
					if (i > 0 || (i == 0 && classpath[i].getPath().toString().length() > 0))
153
				{
154
						classPath += File.pathSeparator;
154
					if (i > 0 || (i == 0 && classpath[i].getPath().toString().length() > 0))
155
					
155
						classPath += File.pathSeparator;
156
					/* Resolve the classpath by replacing all variables with appropriate values */						
156
					
157
					classPath += JavaCore.getResolvedClasspathEntry(classpath[i]).getPath().toString();
157
					/* Resolve the classpath by replacing all variables with appropriate values */						
158
				}				
158
					classPath += JavaCore.getResolvedClasspathEntry(classpath[i]).getPath().toString();
159
			}						
159
				}				
160
			
160
			}						
161
			if (isClassPathRes)
161
			
162
				return classPath;
162
			if (isClassPathRes)
163
			return null;
163
				return classPath;
164
		}
164
			return null;
165
		catch (Throwable t)
165
		}
166
		{
166
		catch (Throwable t)
167
			Status s = new Status(IStatus.ERROR, GuiPlugin.getID(), IStatus.OK, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_DEPENDENCY, javaProject.getElementName()), t);
167
		{
168
			throw new CoreException(s);			
168
			Status s = new Status(IStatus.ERROR, GuiPlugin.getID(), IStatus.OK, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_DEPENDENCY, javaProject.getElementName()), t);
169
		}		
169
			throw new CoreException(s);			
170
	}
170
		}		
171
	
171
	}
172
	
172
	
173
	public static String appendWSProjOutputFolder (String classPath) throws CoreException
173
	
174
	{		
174
	public static String appendWSProjOutputFolder (String classPath) throws CoreException
175
		if (classPath == null)
175
	{		
176
			classPath = "";
176
		if (classPath == null)
177
		
177
			classPath = "";
178
		IProject[] workspaceProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
178
		
179
		for (int i = 0; i < workspaceProjects.length; i++)
179
		IProject[] workspaceProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
180
		{
180
		for (int i = 0; i < workspaceProjects.length; i++)
181
			if (workspaceProjects[i].getNature(JavaCore.NATURE_ID) == null)
181
		{
182
				continue;
182
			// fix for bug #206768 
183
			IJavaProject javaProject = JavaCore.create(workspaceProjects[i]);
183
			if (!workspaceProjects[i].isOpen())
184
			
184
				continue;
185
			if (javaProject == null || !javaProject.exists())
185
			
186
				continue;
186
			if( workspaceProjects[i].getNature(JavaCore.NATURE_ID) == null)
187
			
187
				continue;
188
			IPath classFileLocation = javaProject.getOutputLocation();
188
			
189
			if (classFileLocation != null)
189
			IJavaProject javaProject = JavaCore.create(workspaceProjects[i]);
190
			{
190
			
191
				if (classPath.length() > 0)
191
			if (javaProject == null || !javaProject.exists())
192
					classPath += File.pathSeparator; 
192
				continue;
193
				classPath += ResourcesPlugin.getWorkspace().getRoot().getRawLocation() + classFileLocation.toString();
193
			
194
			}
194
			IPath classFileLocation = javaProject.getOutputLocation();
195
		}
195
			if (classFileLocation != null)
196
		
196
			{
197
		return classPath;
197
				if (classPath.length() > 0)
198
	}
198
					classPath += File.pathSeparator; 
199
	
199
				classPath += ResourcesPlugin.getWorkspace().getRoot().getRawLocation() + classFileLocation.toString();
200
	/**
200
			}
201
	 * Find the java project corresponding to the path.
201
		}
202
	 *  
202
		
203
	 * @param path
203
		return classPath;
204
	 */
204
	}
205
	public static IJavaProject findJavaProject(String path)
205
	
206
	{
206
	/**
207
		if (path == null || path.length() <= 0)
207
	 * Find the java project corresponding to the path.
208
			return null;
208
	 *  
209
		
209
	 * @param path
210
		/* Skip the first slash */
210
	 */
211
		path = path.substring(1);
211
	public static IJavaProject findJavaProject(String path)
212
		int index = path.indexOf('/');
212
	{
213
		if (index != -1)
213
		if (path == null || path.length() <= 0)
214
			path = path.substring(0, index);
214
			return null;
215
		
215
		
216
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
216
		/* Skip the first slash */
217
		IProject location = root.getProject(path);
217
		path = path.substring(1);
218
		
218
		int index = path.indexOf('/');
219
		/* The project is expected to be a java project */		
219
		if (index != -1)
220
		return JavaCore.create (location);
220
			path = path.substring(0, index);
221
	}
221
		
222
	
222
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
223
	
223
		IProject location = root.getProject(path);
224
	/**
224
		
225
	 * Show an error message 
225
		/* The project is expected to be a java project */		
226
	 * @param title The title of the error message
226
		return JavaCore.create (location);
227
	 * @param errorMsg The actual error message
227
	}
228
	 * @param mode Can be MessageDialog.ERROR, MessageDialog.WARNING, or MessageDialog.INFORMATION
228
	
229
	 */
229
	
230
	public static void showMessage (final String title, final String errorMsg, final int mode)
230
	/**
231
	{
231
	 * Show an error message 
232
		final IWorkbench workbench = PlatformUI.getWorkbench();			
232
	 * @param title The title of the error message
233
		workbench.getDisplay().syncExec(new Runnable() {
233
	 * @param errorMsg The actual error message
234
	    public void run() 
234
	 * @param mode Can be MessageDialog.ERROR, MessageDialog.WARNING, or MessageDialog.INFORMATION
235
	    {
235
	 */
236
	    	class CustomMessageDialog extends MessageDialog
236
	public static void showMessage (final String title, final String errorMsg, final int mode)
237
	    	{
237
	{
238
	    		public CustomMessageDialog(Shell parentShell, String dialogTitle,
238
		final IWorkbench workbench = PlatformUI.getWorkbench();			
239
	    	            Image dialogTitleImage, String dialogMessage, int dialogImageType,
239
		workbench.getDisplay().syncExec(new Runnable() {
240
	    	            String[] dialogButtonLabels, int defaultIndex)
240
	    public void run() 
241
	    		{
241
	    {
242
	    			super (parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType,
242
	    	class CustomMessageDialog extends MessageDialog
243
	    	            dialogButtonLabels, defaultIndex);
243
	    	{
244
	    			setShellStyle(SWT.RESIZE|SWT.CLOSE);
244
	    		public CustomMessageDialog(Shell parentShell, String dialogTitle,
245
	    		}
245
	    	            Image dialogTitleImage, String dialogMessage, int dialogImageType,
246
	    		
246
	    	            String[] dialogButtonLabels, int defaultIndex)
247
	    		
247
	    		{
248
	    	    public void openMessageDialog(Shell parent, String title, String message, int messageType) 
248
	    			super (parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType,
249
	    	    {
249
	    	            dialogButtonLabels, defaultIndex);
250
	    	    	CustomMessageDialog dialog = new CustomMessageDialog(parent, title, null, 
250
	    			setShellStyle(SWT.RESIZE|SWT.CLOSE);
251
	    	                message, messageType, new String[] { IDialogConstants.OK_LABEL }, 0);
251
	    		}
252
	    	      
252
	    		
253
	    	        dialog.open();
253
	    		
254
	    	        return;
254
	    	    public void openMessageDialog(Shell parent, String title, String message, int messageType) 
255
	    	    }	    
255
	    	    {
256
	    	    
256
	    	    	CustomMessageDialog dialog = new CustomMessageDialog(parent, title, null, 
257
	    	    /**
257
	    	                message, messageType, new String[] { IDialogConstants.OK_LABEL }, 0);
258
	    	     * We need to over-write this method in order to inject a data in that will cause the macro recorder to ignore it
258
	    	      
259
	    	     */
259
	    	        dialog.open();
260
	    		public void create() 
260
	    	        return;
261
	    		{
261
	    	    }	    
262
	    			super.create();
262
	    	    
263
	    			Shell shell = super.getShell();
263
	    	    /**
264
	    	    	if (shell != null)
264
	    	     * We need to over-write this method in order to inject a data in that will cause the macro recorder to ignore it
265
	    	    		shell.setData(MacroManager.IGNORE, Boolean.TRUE);	    			
265
	    	     */
266
	    		}	    	    
266
	    		public void create() 
267
	    	}
267
	    		{
268
268
	    			super.create();
269
    		CustomMessageDialog dummyInstance = new  CustomMessageDialog (null,null,null,null,0,null,0);	    	            
269
	    			Shell shell = super.getShell();
270
    		dummyInstance.openMessageDialog(workbench.getDisplay().getActiveShell(), title, errorMsg, mode);
270
	    	    	if (shell != null)
271
271
	    	    		shell.setData(MacroManager.IGNORE, Boolean.TRUE);	    			
272
	    }
272
	    		}	    	    
273
	    });
273
	    	}
274
	}
274
275
	
275
    		CustomMessageDialog dummyInstance = new  CustomMessageDialog (null,null,null,null,0,null,0);	    	            
276
	/**
276
    		dummyInstance.openMessageDialog(workbench.getDisplay().getActiveShell(), title, errorMsg, mode);
277
	 * Given an exception, the following method returns a string indicating the 
277
278
	 * class name, method name, and the line number that caused the exception along with
278
	    }
279
	 * the exception's message.  The values of these fields are set to 'unknown' if 
279
	    });
280
	 * this information cannot be determined.
280
	}
281
	 * 
281
	
282
	 * @param throwable The Exception
282
	/**
283
	 * @return A string indicating the origin along with the message of the exception
283
	 * Given an exception, the following method returns a string indicating the 
284
	 */
284
	 * class name, method name, and the line number that caused the exception along with
285
	public static String getOriginOfException(Throwable throwable)
285
	 * the exception's message.  The values of these fields are set to 'unknown' if 
286
	{
286
	 * this information cannot be determined.
287
		StackTraceElement[] stackTrace = throwable.getStackTrace();
287
	 * 
288
		String className = "(unknown)", methodName = "(unknown)", lineNumber = "(unknown)";
288
	 * @param throwable The Exception
289
		if (stackTrace.length > 0)
289
	 * @return A string indicating the origin along with the message of the exception
290
		{
290
	 */
291
			className = stackTrace[0].getClassName();
291
	public static String getOriginOfException(Throwable throwable)
292
			methodName = stackTrace[0].getMethodName();
292
	{
293
			lineNumber = String.valueOf(stackTrace[0].getLineNumber());
293
		StackTraceElement[] stackTrace = throwable.getStackTrace();
294
		}
294
		String className = "(unknown)", methodName = "(unknown)", lineNumber = "(unknown)";
295
		
295
		if (stackTrace.length > 0)
296
		String space = "  ";
296
		{
297
		String exceptionMessgae = (throwable.getLocalizedMessage() == null ? "" : throwable.getLocalizedMessage());
297
			className = stackTrace[0].getClassName();
298
		String message = exceptionMessgae + space +
298
			methodName = stackTrace[0].getMethodName();
299
						"Class: " + className + space +
299
			lineNumber = String.valueOf(stackTrace[0].getLineNumber());
300
						"Method: " + methodName + space +
300
		}
301
						"Line No.: " + lineNumber;
301
		
302
		return message;
302
		String space = "  ";
303
	}
303
		String exceptionMessgae = (throwable.getLocalizedMessage() == null ? "" : throwable.getLocalizedMessage());
304
	
304
		String message = exceptionMessgae + space +
305
	/**
305
						"Class: " + className + space +
306
	 * Walk the dom tree and add all modifiable fields to the vector argument passed in
306
						"Method: " + methodName + space +
307
	 * 
307
						"Line No.: " + lineNumber;
308
	 * @param elementChildren A list of elements
308
		return message;
309
	 * @param modifiableFields Stores the modifiable fields.  
309
	}
310
	 * KEY = The command type (e.g. {@link WaitCommand#TYPE} or {@link ModifyCommand#TYPE})
310
	
311
	 * VALUE = An ordered list of the KEY commands that occur after elementChildren.
311
	/**
312
	 * @param orderedModifiableFields An list of the modifiable commands that occur after 
312
	 * Walk the dom tree and add all modifiable fields to the vector argument passed in
313
	 * elementChildren.  This is mainly used for display purposes.
313
	 * 
314
	 */
314
	 * @param elementChildren A list of elements
315
	public static void walkDomTree(NodeList elementChildren, Map modifiableFields, List orderedModifiableFields) 
315
	 * @param modifiableFields Stores the modifiable fields.  
316
	{
316
	 * KEY = The command type (e.g. {@link WaitCommand#TYPE} or {@link ModifyCommand#TYPE})
317
		if (elementChildren == null)
317
	 * VALUE = An ordered list of the KEY commands that occur after elementChildren.
318
			return;
318
	 * @param orderedModifiableFields An list of the modifiable commands that occur after 
319
		String waitTime = null;
319
	 * elementChildren.  This is mainly used for display purposes.
320
		for (int i = 0, elementListSize = elementChildren.getLength(); i < elementListSize; i++)
320
	 */
321
		{
321
	public static void walkDomTree(NodeList elementChildren, Map modifiableFields, List orderedModifiableFields) 
322
			Node node = elementChildren.item(i);			
322
	{
323
			if (node instanceof Element)
323
		if (elementChildren == null)
324
			{
324
			return;
325
				Element commandElement= (Element)node;
325
		String waitTime = null;
326
				String commandType = commandElement.getAttribute(MacroConstants.TYPE_ATTRIBUTE);
326
		for (int i = 0, elementListSize = elementChildren.getLength(); i < elementListSize; i++)
327
				String commandTypeToAdd = null;
327
		{
328
				
328
			Node node = elementChildren.item(i);			
329
				if (ModifyCommand.TYPE.equals(commandType))
329
			if (node instanceof Element)
330
				{
330
			{
331
					commandTypeToAdd = ModifyCommand.TYPE;
331
				Element commandElement= (Element)node;
332
					
332
				String commandType = commandElement.getAttribute(MacroConstants.TYPE_ATTRIBUTE);
333
				}
333
				String commandTypeToAdd = null;
334
				else if ((WaitCommand.TYPE.equals(commandType) && (waitTime = commandElement.getAttribute(MacroConstants.TIME_TO_WAIT_ATTRIBUTE)) != null && waitTime.length() > 0))
334
				
335
				{
335
				if (ModifyCommand.TYPE.equals(commandType))
336
					commandTypeToAdd = WaitCommand.TYPE;			
336
				{
337
				}
337
					commandTypeToAdd = ModifyCommand.TYPE;
338
				
338
					
339
				if (commandTypeToAdd != null)
339
				}
340
				{
340
				else if ((WaitCommand.TYPE.equals(commandType) && (waitTime = commandElement.getAttribute(MacroConstants.TIME_TO_WAIT_ATTRIBUTE)) != null && waitTime.length() > 0))
341
					addCommandEntry (modifiableFields, orderedModifiableFields, commandTypeToAdd, commandElement);					
341
				{
342
				}
342
					commandTypeToAdd = WaitCommand.TYPE;			
343
			}
343
				}
344
			
344
				
345
			walkDomTree(node.getChildNodes(), modifiableFields, orderedModifiableFields);
345
				if (commandTypeToAdd != null)
346
		}
346
				{
347
	}
347
					addCommandEntry (modifiableFields, orderedModifiableFields, commandTypeToAdd, commandElement);					
348
	
348
				}
349
	private static void addCommandEntry (Map modifiableFields, List orderedModifiableFields, String commandType, Element commandEntry)
349
			}
350
	{
350
			
351
		List commandList = (List)modifiableFields.get(commandType);
351
			walkDomTree(node.getChildNodes(), modifiableFields, orderedModifiableFields);
352
		if (commandList == null)
352
		}
353
		{
353
	}
354
			commandList = new ArrayList();
354
	
355
			modifiableFields.put(commandType, commandList);
355
	private static void addCommandEntry (Map modifiableFields, List orderedModifiableFields, String commandType, Element commandEntry)
356
		}
356
	{
357
		
357
		List commandList = (List)modifiableFields.get(commandType);
358
		commandList.add(commandEntry);		
358
		if (commandList == null)
359
		orderedModifiableFields.add(commandEntry);
359
		{
360
	}
360
			commandList = new ArrayList();
361
	
361
			modifiableFields.put(commandType, commandList);
362
	public static Hashtable indexProperties(List properties)
362
		}
363
	{
363
		
364
		Hashtable retValue = new Hashtable();
364
		commandList.add(commandEntry);		
365
		for (int i = 0; i < properties.size(); i++)
365
		orderedModifiableFields.add(commandEntry);
366
		{
366
	}
367
			IProperty property = (IProperty)properties.get(i);
367
	
368
			if (property.getName() != null && property.getName().length() > 0)
368
	public static Hashtable indexProperties(List properties)
369
				retValue.put(property.getName(), new Object[] {new Integer(i), property.getValue()});
369
	{
370
		}
370
		Hashtable retValue = new Hashtable();
371
		return retValue;
371
		for (int i = 0; i < properties.size(); i++)
372
	}
372
		{
373
	
373
			IProperty property = (IProperty)properties.get(i);
374
	
374
			if (property.getName() != null && property.getName().length() > 0)
375
	public static Object[] parsePropertyFields(String propertyValue)
375
				retValue.put(property.getName(), new Object[] {new Integer(i), property.getValue()});
376
	{
376
		}
377
		final String sepChar = "::";
377
		return retValue;
378
		String currentField = propertyValue;
378
	}
379
		Vector fields = new Vector (3);
379
	
380
		
380
	
381
		do
381
	public static Object[] parsePropertyFields(String propertyValue)
382
		{
382
	{
383
			int inx = currentField.indexOf(sepChar);
383
		final String sepChar = "::";
384
			if (inx > 0 && currentField.length() > inx + 2)
384
		String currentField = propertyValue;
385
			{
385
		Vector fields = new Vector (3);
386
				fields.add (currentField.substring(0, inx));
386
		
387
				currentField = currentField.substring(inx + 2);
387
		do
388
			}
388
		{
389
			else if (currentField.length() > 0)
389
			int inx = currentField.indexOf(sepChar);
390
			{
390
			if (inx > 0 && currentField.length() > inx + 2)
391
				fields.add (currentField);
391
			{
392
				currentField = null;
392
				fields.add (currentField.substring(0, inx));
393
			}
393
				currentField = currentField.substring(inx + 2);
394
		}while (currentField != null);
394
			}
395
		
395
			else if (currentField.length() > 0)
396
		return fields.toArray();
396
			{
397
	}
397
				fields.add (currentField);
398
	
398
				currentField = null;
399
	public static IProperty findProperty (List propertyList, String propertyName)
399
			}
400
	{
400
		}while (currentField != null);
401
		if (propertyList == null || propertyList.isEmpty())
401
		
402
			return null;
402
		return fields.toArray();
403
		
403
	}
404
		for (int i = 0, propertyListCount = propertyList.size(); i < propertyListCount; i++)
404
	
405
		{
405
	public static IProperty findProperty (List propertyList, String propertyName)
406
			IProperty property = (IProperty)propertyList.get(i);
406
	{
407
			if (property.getName().equals(propertyName))
407
		if (propertyList == null || propertyList.isEmpty())
408
				return property;
408
			return null;
409
		}
409
		
410
		return null;
410
		for (int i = 0, propertyListCount = propertyList.size(); i < propertyListCount; i++)
411
	}
411
		{
412
	
412
			IProperty property = (IProperty)propertyList.get(i);
413
	public static void openErrorWithDetail(Shell parent, String title, String message, String cause)
413
			if (property.getName().equals(propertyName))
414
	{
414
				return property;
415
		
415
		}
416
		class CustomErrorDialog extends ErrorDialog
416
		return null;
417
		{
417
	}
418
			private String cause;
418
	
419
			private static final int LIST_ITEM_COUNT = 7;
419
	public static void openErrorWithDetail(Shell parent, String title, String message, String cause)
420
			private org.eclipse.swt.widgets.List list;
420
	{
421
			private boolean isListDisplayed;
421
		
422
			private Clipboard clipboard;
422
		class CustomErrorDialog extends ErrorDialog
423
			
423
		{
424
			public CustomErrorDialog(Shell parentShell, int severity, String dialogTitle, String message, String cause) 
424
			private String cause;
425
			{
425
			private static final int LIST_ITEM_COUNT = 7;
426
				super (parentShell, dialogTitle, message, new Status(severity, GuiPlugin.getID(), severity, "", new Throwable(cause)), IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR);
426
			private org.eclipse.swt.widgets.List list;
427
				this.cause = cause;
427
			private boolean isListDisplayed;
428
				isListDisplayed = false;
428
			private Clipboard clipboard;
429
			}
429
			
430
			
430
			public CustomErrorDialog(Shell parentShell, int severity, String dialogTitle, String message, String cause) 
431
			public void openErrorDialog()
431
			{
432
			{
432
				super (parentShell, dialogTitle, message, new Status(severity, GuiPlugin.getID(), severity, "", new Throwable(cause)), IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR);
433
				this.open();
433
				this.cause = cause;
434
			}			
434
				isListDisplayed = false;
435
			
435
			}
436
		    			
436
			
437
		    protected org.eclipse.swt.widgets.List createDropDownList(Composite parent) 
437
			public void openErrorDialog()
438
		    {
438
			{
439
		    	if (isListDisplayed)
439
				this.open();
440
		    	{
440
			}			
441
		    		isListDisplayed = false;		    		
441
			
442
		    		list.dispose();
442
		    			
443
		    		return list;
443
		    protected org.eclipse.swt.widgets.List createDropDownList(Composite parent) 
444
		    	}
444
		    {
445
		    	
445
		    	if (isListDisplayed)
446
		    	isListDisplayed = true;
446
		    	{
447
		    	
447
		    		isListDisplayed = false;		    		
448
		    	// create the list
448
		    		list.dispose();
449
		    	list = new org.eclipse.swt.widgets.List(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
449
		    		return list;
450
450
		    	}
451
		    	// fill the list
451
		    	
452
		    	if (cause != null)
452
		    	isListDisplayed = true;
453
		    	{
453
		    	
454
			    	StringTokenizer st = new StringTokenizer (cause, "\n");
454
		    	// create the list
455
			    	String indents = "";
455
		    	list = new org.eclipse.swt.widgets.List(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
456
			    	boolean addedIndentation = false;
456
457
			    	while (st.hasMoreTokens())
457
		    	// fill the list
458
			    	{
458
		    	if (cause != null)
459
			    		String currentToken = st.nextToken();
459
		    	{
460
			    		currentToken = currentToken.replace ('\r', ' ');
460
			    	StringTokenizer st = new StringTokenizer (cause, "\n");
461
			    		currentToken = currentToken.trim();
461
			    	String indents = "";
462
			    		if (!addedIndentation && currentToken.startsWith("at"))
462
			    	boolean addedIndentation = false;
463
			    		{
463
			    	while (st.hasMoreTokens())
464
			    			indents += "  ";
464
			    	{
465
			    			addedIndentation = true;
465
			    		String currentToken = st.nextToken();
466
			    		}
466
			    		currentToken = currentToken.replace ('\r', ' ');
467
			    		else if (addedIndentation && !currentToken.startsWith("at"))
467
			    		currentToken = currentToken.trim();
468
			    			addedIndentation = false;
468
			    		if (!addedIndentation && currentToken.startsWith("at"))
469
			    		
469
			    		{
470
			    		
470
			    			indents += "  ";
471
			    		list.add(indents + currentToken);
471
			    			addedIndentation = true;
472
			    	}
472
			    		}
473
		    	}
473
			    		else if (addedIndentation && !currentToken.startsWith("at"))
474
		    	
474
			    			addedIndentation = false;
475
		        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
475
			    		
476
		                | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL
476
			    		
477
		                | GridData.GRAB_VERTICAL);
477
			    		list.add(indents + currentToken);
478
		        data.heightHint = list.getItemHeight() * LIST_ITEM_COUNT;
478
			    	}
479
		        data.horizontalSpan = 2;
479
		    	}
480
		        list.setLayoutData(data);
480
		    	
481
		        list.setFont(parent.getFont());
481
		        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
482
		        
482
		                | GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL
483
		        Menu copyMenu = new Menu(list);
483
		                | GridData.GRAB_VERTICAL);
484
		        MenuItem copyItem = new MenuItem(copyMenu, SWT.NONE);
484
		        data.heightHint = list.getItemHeight() * LIST_ITEM_COUNT;
485
		        copyItem.addSelectionListener(new SelectionListener() {
485
		        data.horizontalSpan = 2;
486
		            /*
486
		        list.setLayoutData(data);
487
		             * @see SelectionListener.widgetSelected (SelectionEvent)
487
		        list.setFont(parent.getFont());
488
		             */
488
		        
489
		            public void widgetSelected(SelectionEvent e) {
489
		        Menu copyMenu = new Menu(list);
490
		                copyToClipboard();
490
		        MenuItem copyItem = new MenuItem(copyMenu, SWT.NONE);
491
		            }
491
		        copyItem.addSelectionListener(new SelectionListener() {
492
492
		            /*
493
		            /*
493
		             * @see SelectionListener.widgetSelected (SelectionEvent)
494
		             * @see SelectionListener.widgetDefaultSelected(SelectionEvent)
494
		             */
495
		             */
495
		            public void widgetSelected(SelectionEvent e) {
496
		            public void widgetDefaultSelected(SelectionEvent e) {
496
		                copyToClipboard();
497
		                copyToClipboard();
497
		            }
498
		            }
498
499
		        });
499
		            /*
500
		        copyItem.setText(AutoGUIMessages.AUTO_GUI_COMMON_COPY);
500
		             * @see SelectionListener.widgetDefaultSelected(SelectionEvent)
501
		        list.setMenu(copyMenu);
501
		             */
502
		    	
502
		            public void widgetDefaultSelected(SelectionEvent e) {
503
		        return list;
503
		                copyToClipboard();
504
		    }
504
		            }
505
		    
505
		        });
506
		    private void copyToClipboard() {
506
		        copyItem.setText(AutoGUIMessages.AUTO_GUI_COMMON_COPY);
507
		        if (clipboard != null)
507
		        list.setMenu(copyMenu);
508
		            clipboard.dispose();
508
		    	
509
		        StringBuffer clipBoardBuffer = new StringBuffer();		       
509
		        return list;
510
		        
510
		    }
511
		        String[] listEntrySelections = list.getSelection();
511
		    
512
		        for (int i = 0; i < listEntrySelections.length; i++)
512
		    private void copyToClipboard() {
513
		        	clipBoardBuffer.append(listEntrySelections[i] + GlobalConstants.LINE_SEPARATOR);
513
		        if (clipboard != null)
514
		        clipboard = new Clipboard(list.getDisplay());
514
		            clipboard.dispose();
515
		        clipboard.setContents(new Object[] { clipBoardBuffer.toString() },
515
		        StringBuffer clipBoardBuffer = new StringBuffer();		       
516
		                new Transfer[] { TextTransfer.getInstance() });
516
		        
517
		    }
517
		        String[] listEntrySelections = list.getSelection();
518
518
		        for (int i = 0; i < listEntrySelections.length; i++)
519
519
		        	clipBoardBuffer.append(listEntrySelections[i] + GlobalConstants.LINE_SEPARATOR);
520
		}
520
		        clipboard = new Clipboard(list.getDisplay());
521
				
521
		        clipboard.setContents(new Object[] { clipBoardBuffer.toString() },
522
		CustomErrorDialog errorDialog = new CustomErrorDialog (parent, IStatus.ERROR, title, message, cause);
522
		                new Transfer[] { TextTransfer.getInstance() });
523
		errorDialog.openErrorDialog();
523
		    }
524
	}
524
525
	
525
526
	public static void openErrorWithDetail(final String title, final String message, Throwable t)
526
		}
527
	{		
527
				
528
		String stackTrace =getExceptionStackTrace(t);
528
		CustomErrorDialog errorDialog = new CustomErrorDialog (parent, IStatus.ERROR, title, message, cause);
529
		Throwable exceptionCause = (t.getCause() != null ? t.getCause() : t);
529
		errorDialog.openErrorDialog();
530
			
530
	}
531
		final String cause = exceptionCause.getClass().getName() + "\n" + exceptionCause.getMessage() + "\n" + stackTrace;
531
	
532
		
532
	public static void openErrorWithDetail(final String title, final String message, Throwable t)
533
		GuiPlugin.getDefault().getWorkbench().getDisplay().syncExec(new Runnable()
533
	{		
534
		{
534
		String stackTrace =getExceptionStackTrace(t);
535
535
		Throwable exceptionCause = (t.getCause() != null ? t.getCause() : t);
536
			public void run() 
536
			
537
			{
537
		final String cause = exceptionCause.getClass().getName() + "\n" + exceptionCause.getMessage() + "\n" + stackTrace;
538
				openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), title, message, cause);
538
		
539
				
539
		GuiPlugin.getDefault().getWorkbench().getDisplay().syncExec(new Runnable()
540
			}});
540
		{
541
		
541
542
	}
542
			public void run() 
543
543
			{
544
	public static String getExceptionStackTrace(Throwable t)
544
				openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), title, message, cause);
545
	{
545
				
546
		Throwable throwable = findCause(t);
546
			}});
547
				
547
		
548
		StringWriter stackTrace = new StringWriter(); 
548
	}
549
		throwable.printStackTrace(new PrintWriter(stackTrace));	
549
550
		
550
	public static String getExceptionStackTrace(Throwable t)
551
		return stackTrace.toString();
551
	{
552
	}
552
		Throwable throwable = findCause(t);
553
	
553
				
554
	public static Throwable findCause (Throwable t)
554
		StringWriter stackTrace = new StringWriter(); 
555
	{
555
		throwable.printStackTrace(new PrintWriter(stackTrace));	
556
		Throwable cause = null;
556
		
557
		if (t instanceof InvocationTargetException)
557
		return stackTrace.toString();
558
			cause = ((InvocationTargetException)t).getTargetException();			
558
	}
559
		else if (t instanceof CoreException)
559
	
560
			cause = ((CoreException)t).getStatus().getException();				
560
	public static Throwable findCause (Throwable t)
561
		
561
	{
562
		if (cause == null)
562
		Throwable cause = null;
563
			return t;
563
		if (t instanceof InvocationTargetException)
564
		return findCause(cause);
564
			cause = ((InvocationTargetException)t).getTargetException();			
565
	}
565
		else if (t instanceof CoreException)
566
	
566
			cause = ((CoreException)t).getStatus().getException();				
567
	public static String getWorkspaceLocation ()
567
		
568
	{
568
		if (cause == null)
569
		IPath rootpath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
569
			return t;
570
		String workspaceString = rootpath.toOSString();
570
		return findCause(cause);
571
				
571
	}
572
		return workspaceString;
572
	
573
	}
573
	public static String getWorkspaceLocation ()
574
	
574
	{
575
	public static String getTestSuiteProjectLocation (ITestSuite testSuite)
575
		IPath rootpath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
576
	{
576
		String workspaceString = rootpath.toOSString();
577
		String workspaceString = getWorkspaceLocation();
577
				
578
		
578
		return workspaceString;
579
		/* Append a slash to the end if it doesn't have one */
579
	}
580
		if (!(workspaceString.endsWith("\\") || workspaceString.endsWith("/")))
580
	
581
			workspaceString += File.separatorChar;
581
	public static String getTestSuiteProjectLocation (ITestSuite testSuite)
582
		
582
	{
583
		IImplementor implementor = testSuite.getImplementor(); 
583
		String workspaceString = getWorkspaceLocation();
584
		String projectLocation = null;
584
		
585
		if (implementor != null && implementor.getLocation() != null)
585
		/* Append a slash to the end if it doesn't have one */
586
		{
586
		if (!(workspaceString.endsWith("\\") || workspaceString.endsWith("/")))
587
			IPath sourcePath = new Path(testSuite.getImplementor().getLocation());
587
			workspaceString += File.separatorChar;
588
			String projectName;
588
		
589
			if (sourcePath.segmentCount() > 0)
589
		IImplementor implementor = testSuite.getImplementor(); 
590
			{
590
		String projectLocation = null;
591
				projectName = sourcePath.segment(0);
591
		if (implementor != null && implementor.getLocation() != null)
592
				projectLocation = workspaceString + projectName;
592
		{
593
			}			
593
			IPath sourcePath = new Path(testSuite.getImplementor().getLocation());
594
		}
594
			String projectName;
595
		
595
			if (sourcePath.segmentCount() > 0)
596
		return projectLocation;
596
			{
597
	}
597
				projectName = sourcePath.segment(0);
598
	
598
				projectLocation = workspaceString + projectName;
599
	
599
			}			
600
	public static void throwCoreException(String message) throws CoreException
600
		}
601
	{
601
		
602
		throwCoreException(message, 0, null);
602
		return projectLocation;
603
	}
603
	}
604
	
604
	
605
	
605
	
606
	public static void throwCoreException(String message, int line) throws CoreException
606
	public static void throwCoreException(String message) throws CoreException
607
	{
607
	{
608
		throwCoreException(message, line, null);
608
		throwCoreException(message, 0, null);
609
	}
609
	}
610
610
	
611
	public static void throwCoreException(String message, int line, Throwable t) throws CoreException
611
	public static void throwCoreException(String message, Throwable t) throws CoreException
612
	{
612
	{
613
		if (line > 0)
613
		throwCoreException(message, 0, t);
614
			message = NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERAL, new String[] {String.valueOf(line), message});
614
	}	
615
		Status s = new Status(IStatus.ERROR, GuiPlugin.getID(), IStatus.OK, message, t);
615
	
616
		CoreException coreException = new CoreException(s);
616
	public static void throwCoreException(String message, int line) throws CoreException
617
		if (t instanceof InvocationTargetException)
617
	{
618
			coreException.initCause(t.getCause());
618
		throwCoreException(message, line, null);
619
		else
619
	}
620
			coreException.initCause(t);
620
621
		throw coreException;
621
	public static void throwCoreException(String message, int line, Throwable t) throws CoreException
622
	}
622
	{
623
	
623
		if (line > 0)
624
	
624
			message = NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERAL, new String[] {String.valueOf(line), message});
625
	/**
625
		Status s = new Status(IStatus.ERROR, GuiPlugin.getID(), IStatus.OK, message, t);
626
	 * Retuns the absolute workspace path of the test suite
626
		CoreException coreException = new CoreException(s);
627
	 * that is passed in
627
		if (t instanceof InvocationTargetException)
628
	 * 
628
			coreException.initCause(t.getCause());
629
	 * @param testSuite The test suite whose path is desired
629
		else
630
	 * 
630
			coreException.initCause(t);
631
	 * @return the absolute workspace path of the testsuite
631
		throw coreException;
632
	 */
632
	}
633
	public static String resolveTestSuitePath(ITestSuite testSuite)
633
	
634
	{
634
	
635
		if (testSuite == null)
635
	/**
636
			return MacroConstants.EMPTY_STRING;
636
	 * Retuns the absolute workspace path of the test suite
637
		
637
	 * that is passed in
638
		IFile file = EMFUtil.getWorkspaceFile((EObject)testSuite);
638
	 * 
639
		return file == null ? MacroConstants.EMPTY_STRING : file.getFullPath().toString();		
639
	 * @param testSuite The test suite whose path is desired
640
	}
640
	 * 
641
	
641
	 * @return the absolute workspace path of the testsuite
642
	 */
643
	public static String resolveTestSuitePath(ITestSuite testSuite)
644
	{
645
		if (testSuite == null)
646
			return MacroConstants.EMPTY_STRING;
647
		
648
		IFile file = EMFUtil.getWorkspaceFile((EObject)testSuite);
649
		return file == null ? MacroConstants.EMPTY_STRING : file.getFullPath().toString();		
650
	}
651
	
642
}
652
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/AutoGUIImages.java (-169 / +174 lines)
Lines 1-169 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUIImages.java,v 1.14 2008/03/05 18:27:25 paules Exp $
7
 * $Id: AutoGUIImages.java,v 1.14 2008/03/05 18:27:25 paules Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal;
12
package org.eclipse.tptp.test.auto.gui.internal;
13
13
14
import java.net.URL;
14
import java.net.URL;
15
15
16
import org.eclipse.hyades.ui.internal.util.ImageManager;
16
import org.eclipse.hyades.ui.internal.util.ImageManager;
17
17
18
/**
18
/**
19
 * Auto GUI test tools image manager.
19
 * Auto GUI test tools image manager.
20
 * 
20
 * 
21
 * 
21
 * 
22
 * @author      Paul E. Slauenwhite
22
 * @author      Paul E. Slauenwhite
23
 * @version     March 5, 2008
23
 * @author 		Alexander Nyssen
24
 * @since       August 19, 2005
24
 * @version     March 5, 2008
25
 */
25
 * @since       August 19, 2005
26
public class AutoGUIImages extends ImageManager
26
 */
27
{
27
public class AutoGUIImages extends ImageManager
28
	
28
{
29
	/**
29
	
30
	 * Singleton instance.
30
	/**
31
	 */
31
	 * Singleton instance.
32
	private static AutoGUIImages instance = null;
32
	 */
33
	
33
	private static AutoGUIImages instance = null;
34
	private AutoGUIImages(){
34
	
35
		//No-operation since a privatized constructor.
35
	private AutoGUIImages(){
36
	}
36
		//No-operation since a privatized constructor.
37
	
37
	}
38
	public static AutoGUIImages getInstance(){
38
	
39
		
39
	public static AutoGUIImages getInstance(){
40
		if(instance == null){
40
		
41
			
41
		if(instance == null){
42
			instance = new AutoGUIImages();
42
			
43
43
			instance = new AutoGUIImages();
44
			try	{
44
45
	            instance.initialize(new URL(GuiPlugin.getDefault().getBundle().getEntry("/"), "icons/full/"), GuiPlugin.getDefault().getImageRegistry()); //$NON-NLS-1$ //$NON-NLS-2$
45
			try	{
46
			}
46
	            instance.initialize(new URL(GuiPlugin.getDefault().getBundle().getEntry("/"), "icons/full/"), GuiPlugin.getDefault().getImageRegistry()); //$NON-NLS-1$ //$NON-NLS-2$
47
			catch(Exception e) {
47
			}
48
				GuiPlugin.logError(e);
48
			catch(Exception e) {
49
			}
49
				GuiPlugin.logError(e);
50
		}
50
			}
51
		
51
		}
52
		return instance;
52
		
53
	}
53
		return instance;
54
54
	}
55
	/* tool16 */
55
56
	public static final String IMG_NEW_AUTO_GUI					= "new_atestsuite.gif"; 
56
	/* tool16 */
57
	public static final String OBJECT_MINE						= "object_mine.gif"; 	
57
	public static final String IMG_NEW_AUTO_GUI					= "new_atestsuite.gif"; 
58
	public static final String POSITION_BASED					= "position_based.gif"; 
58
	public static final String OBJECT_MINE						= "object_mine.gif"; 	
59
	public static final String VARS								= "variables.gif"; 		
59
	public static final String POSITION_BASED					= "position_based.gif"; 
60
	public static final String VAR_ITEM							= "variable.gif"; 		
60
	public static final String VERIFICATION_HOOK				= "verification_hook.gif";
61
	public static final String TERMINATE						= "terminate.gif"; 	
61
	public static final String VARS								= "variables.gif"; 		
62
	
62
	public static final String VAR_ITEM							= "variable.gif"; 		
63
	/* obj16 */			
63
	public static final String TERMINATE						= "terminate.gif"; 	
64
	public static final String RESTART							= "restart.gif";
64
	
65
	public static final String DATAPOOL							= "datapool_obj.gif";
65
	/* obj16 */			
66
	public static final String ERROR							= "error.gif";
66
	public static final String RESTART							= "restart.gif";
67
	public static final String WARNING							= "warning.gif";
67
	public static final String DATAPOOL							= "datapool_obj.gif";
68
	public static final String LINK								= "link.gif";
68
	public static final String ERROR							= "error.gif";
69
	public static final String SHELL							= "shell_obj.gif";
69
	public static final String WARNING							= "warning.gif";
70
	public static final String COMMAND							= "command_obj.gif";		
70
	public static final String LINK								= "link.gif";
71
	public static final String ECLIPSE_LOC						= "eclipse_loc.gif";	
71
	public static final String SHELL							= "shell_obj.gif";
72
	public static final String WAIT_TIME						= "wait.gif";
72
	public static final String COMMAND							= "command_obj.gif";		
73
	public static final String ARGUMENTS						= "arguments.gif";
73
	public static final String ECLIPSE_LOC						= "eclipse_loc.gif";	
74
	public static final String USER_INPUT						= "user_input.gif";	
74
	public static final String WAIT_TIME						= "wait.gif";
75
	public static final String WIDGET							= "widget.gif";	
75
	public static final String ARGUMENTS						= "arguments.gif";
76
	
76
	public static final String USER_INPUT						= "user_input.gif";	
77
	/* lcl16 */
77
	public static final String WIDGET							= "widget.gif";	
78
	public static final String EXPAND							= "expand.gif";
78
	
79
	public static final String COLLAPSE							= "collapse.gif";
79
	/* lcl16 */
80
	public static final String RECORD							= "recording.gif";
80
	public static final String EXPAND							= "expand.gif";
81
	public static final String PLAY								= "resume_co.gif";
81
	public static final String COLLAPSE							= "collapse.gif";
82
	public static final String DELETE							= "delete.gif";
82
	public static final String RECORD							= "recording.gif";
83
	public static final String UP								= "up.gif";
83
	public static final String PLAY								= "resume_co.gif";
84
	public static final String DOWN								= "down.gif";
84
	public static final String DELETE							= "delete.gif";
85
	public static final String REFRESH							= "refresh.gif";
85
	public static final String UP								= "up.gif";
86
	public static final String INCLUDE							= "include.gif";
86
	public static final String DOWN								= "down.gif";
87
	public static final String OUTPUT							= "output.gif";
87
	public static final String REFRESH							= "refresh.gif";
88
	public static final String FIND								= "find.gif";
88
	public static final String INCLUDE							= "include.gif";
89
	public static final String WORKSPACE_LOC					= "workspace.gif";	
89
	public static final String OUTPUT							= "output.gif";
90
	public static final String INVOCATION						= "invocation.gif";
90
	public static final String FIND								= "find.gif";
91
	public static final String UPDATE							= "update.gif";	
91
	public static final String WORKSPACE_LOC					= "workspace.gif";	
92
	
92
	public static final String INVOCATION						= "invocation.gif";
93
	/* wizban */
93
	public static final String UPDATE							= "update.gif";	
94
	public static final String IMG_NEW_AUTO_GUI_WIZBAN			= "atestsuite_wiz.gif";
94
	
95
		
95
	/* wizban */
96
	protected void addImages() 
96
	public static final String IMG_NEW_AUTO_GUI_WIZBAN			= "atestsuite_wiz.gif";
97
	{
97
		
98
		/* tool16 */
98
	protected void addImages() 
99
		add("e", T_TOOL, IMG_NEW_AUTO_GUI);		
99
	{
100
		
100
		/* tool16 */
101
		add("d", T_TOOL, POSITION_BASED);
101
		add("e", T_TOOL, IMG_NEW_AUTO_GUI);		
102
		add("e", T_TOOL, POSITION_BASED);
102
		
103
103
		add("d", T_TOOL, POSITION_BASED);
104
		add("d", T_TOOL, TERMINATE);
104
		add("e", T_TOOL, POSITION_BASED);
105
		add("e", T_TOOL, TERMINATE);
105
		
106
		
106
		add("d", T_TOOL, VERIFICATION_HOOK);
107
		add("d", T_TOOL, VARS);
107
		add("e", T_TOOL, VERIFICATION_HOOK);
108
		add("e", T_TOOL, VARS);
108
109
		
109
		add("d", T_TOOL, TERMINATE);
110
		add("d", T_TOOL, VAR_ITEM);
110
		add("e", T_TOOL, TERMINATE);
111
		add("e", T_TOOL, VAR_ITEM);
111
		
112
		
112
		add("d", T_TOOL, VARS);
113
		/* obj16 */		
113
		add("e", T_TOOL, VARS);
114
		add(T_OBJ, RESTART);	
114
		
115
		add(T_OBJ, DATAPOOL);	
115
		add("d", T_TOOL, VAR_ITEM);
116
		add(T_OBJ, ERROR);
116
		add("e", T_TOOL, VAR_ITEM);
117
		add(T_OBJ, WARNING);
117
		
118
		add(T_OBJ, LINK);
118
		/* obj16 */		
119
		add(T_OBJ, SHELL);
119
		add(T_OBJ, RESTART);	
120
		add(T_OBJ, COMMAND);		
120
		add(T_OBJ, DATAPOOL);	
121
		add(T_OBJ, WORKSPACE_LOC);
121
		add(T_OBJ, ERROR);
122
		add(T_OBJ, ECLIPSE_LOC);
122
		add(T_OBJ, WARNING);
123
		add(T_OBJ, WAIT_TIME);
123
		add(T_OBJ, LINK);
124
		add(T_OBJ, ARGUMENTS);
124
		add(T_OBJ, SHELL);
125
		add(T_OBJ, OBJECT_MINE);
125
		add(T_OBJ, COMMAND);		
126
		add(T_OBJ, WIDGET);
126
		add(T_OBJ, WORKSPACE_LOC);
127
		add(T_OBJ, USER_INPUT);
127
		add(T_OBJ, ECLIPSE_LOC);
128
		
128
		add(T_OBJ, WAIT_TIME);
129
		/* lcl16 */
129
		add(T_OBJ, ARGUMENTS);
130
		add("c", T_LCL, EXPAND);
130
		add(T_OBJ, OBJECT_MINE);
131
		add("c", T_LCL, COLLAPSE);
131
		add(T_OBJ, WIDGET);
132
						
132
		add(T_OBJ, USER_INPUT);
133
		add("d", T_LCL, RECORD);
133
		
134
		add("e", T_LCL, RECORD);
134
		/* lcl16 */
135
		
135
		add("c", T_LCL, EXPAND);
136
		add("d", T_LCL, UPDATE);
136
		add("c", T_LCL, COLLAPSE);
137
		add("e", T_LCL, UPDATE);
137
						
138
		
138
		add("d", T_LCL, RECORD);
139
		add("c", T_LCL, PLAY);		
139
		add("e", T_LCL, RECORD);
140
		add("d", T_LCL, PLAY);
140
		
141
		
141
		add("d", T_LCL, UPDATE);
142
		add("d", T_LCL, DELETE);		
142
		add("e", T_LCL, UPDATE);
143
		add("e", T_LCL, DELETE);
143
		
144
		
144
		add("c", T_LCL, PLAY);		
145
		add("d", T_LCL, UP);		
145
		add("d", T_LCL, PLAY);
146
		add("e", T_LCL, UP);
146
		
147
		
147
		add("d", T_LCL, DELETE);		
148
		add("d", T_LCL, DOWN);		
148
		add("e", T_LCL, DELETE);
149
		add("e", T_LCL, DOWN);
149
		
150
		
150
		add("d", T_LCL, UP);		
151
		add("c", T_LCL, REFRESH);				
151
		add("e", T_LCL, UP);
152
		add("d", T_LCL, REFRESH);		
152
		
153
		
153
		add("d", T_LCL, DOWN);		
154
		add("d", T_LCL, INCLUDE);
154
		add("e", T_LCL, DOWN);
155
		add("e", T_LCL, INCLUDE);
155
		
156
		
156
		add("c", T_LCL, REFRESH);				
157
		add("d", T_LCL, OUTPUT);
157
		add("d", T_LCL, REFRESH);		
158
		add("e", T_LCL, OUTPUT);
158
		
159
		
159
		add("d", T_LCL, INCLUDE);
160
		add("d", T_LCL, FIND);
160
		add("e", T_LCL, INCLUDE);
161
		add("e", T_LCL, FIND);
161
		
162
				
162
		add("d", T_LCL, OUTPUT);
163
		add("d", T_LCL, INVOCATION);
163
		add("e", T_LCL, OUTPUT);
164
		add("e", T_LCL, INVOCATION);
164
		
165
		
165
		add("d", T_LCL, FIND);
166
		/* wizban */
166
		add("e", T_LCL, FIND);
167
		add(T_WIZBAN, IMG_NEW_AUTO_GUI_WIZBAN);					
167
				
168
	}
168
		add("d", T_LCL, INVOCATION);
169
}
169
		add("e", T_LCL, INVOCATION);
170
		
171
		/* wizban */
172
		add(T_WIZBAN, IMG_NEW_AUTO_GUI_WIZBAN);					
173
	}
174
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/resolvers/PrimitiveWidgetId.java (-80 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.resolvers;
12
13
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
14
15
16
/**
17
 * A primitive string widget id.  The string object must be an exact match
18
 * for the two given ids to equal.  Contributors can extend this class or 
19
 * provide a direct implementation of {@link IWidgetId}
20
 * 
21
 * @author Ali Mehregani
22
 */
23
public class PrimitiveWidgetId implements IWidgetId
24
{
25
	/** The resolver id */
26
	private String resolverId;
27
	
28
	/** The string id of the widget */
29
	private String id;
30
	
31
	
32
	public PrimitiveWidgetId()
33
	{
34
		
35
	}
36
	
37
	public PrimitiveWidgetId(String id)
38
	{
39
		this.id = id;
40
	}
41
	
42
	public String getResolverId()
43
	{
44
		return resolverId;
45
	}
46
47
	public void setResolverId(String resolverId)
48
	{
49
		this.resolverId = resolverId;
50
	}
51
52
	/**
53
	 * @return the id
54
	 */
55
	public String getId()
56
	{
57
		return id;
58
	}
59
60
	/**
61
	 * @param id the id to set
62
	 */
63
	public void setId(String id)
64
	{
65
		this.id = id;
66
	}
67
	
68
	public boolean equals(Object o)
69
	{
70
		if (id == null)
71
			return o == null;
72
		return id.equals(o);
73
	}
74
	
75
	public String toString()
76
	{
77
		return id;
78
	}
79
80
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/resolvers/NonTrivialWidgetResolver.java (-538 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: NonTrivialWidgetResolver.java,v 1.7 2008/04/18 13:45:30 dmorris Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.resolvers;
13
14
import org.eclipse.hyades.models.hierarchy.TRCAgentProxy;
15
import org.eclipse.swt.custom.CTabItem;
16
import org.eclipse.swt.graphics.Point;
17
import org.eclipse.swt.widgets.Button;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Control;
20
import org.eclipse.swt.widgets.Group;
21
import org.eclipse.swt.widgets.Item;
22
import org.eclipse.swt.widgets.Label;
23
import org.eclipse.swt.widgets.Menu;
24
import org.eclipse.swt.widgets.MenuItem;
25
import org.eclipse.swt.widgets.TabItem;
26
import org.eclipse.swt.widgets.Text;
27
import org.eclipse.swt.widgets.ToolBar;
28
import org.eclipse.swt.widgets.ToolItem;
29
import org.eclipse.swt.widgets.Tree;
30
import org.eclipse.swt.widgets.TreeItem;
31
import org.eclipse.swt.widgets.Widget;
32
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
33
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver;
34
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
35
import org.eclipse.tptp.trace.ui.internal.launcher.core.AnalysisType;
36
import org.eclipse.tptp.trace.ui.internal.launcher.core.DataCollectorTreeContentProvider.ParentChildNode;
37
import org.eclipse.ui.dialogs.FileSystemElement;
38
import org.eclipse.ui.model.IWorkbenchAdapter;
39
import org.eclipse.ui.views.IViewCategory;
40
41
/**
42
 * <p>
43
 * The purpose of this class is to resolve widgets that cannot be resolved using the 
44
 * AdaptiveWidgetResolver.  These widgets will likely require nested calls in order to
45
 * be determined.
46
 * </p>
47
 * <p>
48
 * Some of the properties used to resolve a widget are locale dependent (e.g. the name
49
 * of a button or the closest label to a text box)
50
 * </p>
51
 * 
52
 * @since 4.1
53
 * @author Ali Mehregani
54
 */
55
public class NonTrivialWidgetResolver implements IWidgetResolver
56
{
57
	/** 
58
	 * The id of this resolver -- must be in sync with the id registered with 
59
	 * the widgetResolver extension.
60
	 */
61
	private static final String ID = "org.eclipse.tptp.test.auto.gui.nontrivial";
62
63
	public IWidgetId getUniqueId(Widget parent, Object object)
64
	{
65
		if (!(object instanceof Widget))
66
			return null;
67
		
68
		Widget widget = (Widget) object;
69
		Object data = widget.getData();
70
		
71
		IWidgetId widgetId = null;
72
		
73
			
74
		/* Resolve the object based on the data type of the widget */
75
		/* An agent */
76
		if (data instanceof TRCAgentProxy)
77
		{
78
			widgetId = resolveAgentProxy (widget);
79
		}
80
		/* A file system element */
81
		else if (data instanceof FileSystemElement)
82
		{
83
			widgetId = resolveFileSystemElement (widget);
84
		}
85
		/* A view catgory */
86
		else if (data instanceof IViewCategory)
87
		{
88
			String id = ((IViewCategory)data).getId();
89
			if (id != null && id.length() > 0)
90
			{
91
				widgetId = new PrimitiveWidgetId();
92
				((PrimitiveWidgetId)widgetId).setId(id);
93
			}
94
		}
95
		/* Analysis type */
96
		else if (data instanceof ParentChildNode)
97
		{
98
			Object child = ((ParentChildNode)data).child;
99
			if (child instanceof AnalysisType)
100
			{
101
				widgetId = resolveAnalysisType((AnalysisType)child); 
102
			}
103
		}
104
105
		/* Resolve the object based on its widget type */
106
		/* A menu item or a tree item*/
107
		else if (widget instanceof MenuItem || widget instanceof TreeItem)
108
		{
109
			widgetId = resolveItem ((Item)widget);
110
		}
111
		/* A button */
112
		else if (widget instanceof Button)
113
		{
114
			widgetId = resolveButton (parent, (Button)widget, null);
115
		}
116
		/* A text box */
117
		else if (widget instanceof Text)
118
		{
119
			widgetId = resolveText ((Text)widget);
120
		}
121
		/* A CTab item */
122
		else if (widget instanceof CTabItem)
123
		{
124
			widgetId = validateText(((CTabItem)widget).getText());
125
		}		
126
		/* A tab item */
127
		else if (widget instanceof TabItem)
128
		{
129
			widgetId = validateText(((TabItem)widget).getText());
130
		}
131
		/* A toolbar */
132
		else if (widget instanceof ToolBar)
133
		{
134
			widgetId = resolveToolBar ((ToolBar)widget);
135
		}
136
		/* A tool item */
137
		else if (widget instanceof ToolItem)
138
		{
139
			widgetId = resolveToolbarItem ((ToolItem)widget);			
140
		}		
141
		
142
143
		if (widgetId != null)
144
		{
145
			widgetId.setResolverId(ID);
146
		}
147
		
148
		return widgetId;
149
	}
150
151
152
153
	private IWidgetId resolveAnalysisType(AnalysisType analysisType)
154
	{
155
		Object[] properties = 
156
		{
157
			new Object[] {analysisType.getId(), "1.0"},
158
		};
159
	
160
		return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
161
	}
162
163
164
165
	private IWidgetId resolveToolBar(ToolBar toolbar)
166
	{
167
		int itemCount = toolbar.getItemCount();
168
		String 	firstItem = itemCount > 1 ? limitText(toolbar.getItem(0).getToolTipText()) : null, 
169
				lastItem = itemCount > 2 ? limitText(toolbar.getItem(itemCount - 1).getToolTipText()) : null;
170
		int style = toolbar.getStyle();
171
		
172
		if (firstItem == null && lastItem == null)
173
			return null;
174
		
175
		Object[] properties = 
176
		{
177
			new Object[] {convertText(firstItem), "0.5"},
178
			new Object[] {convertText(lastItem), "0.5"},
179
			new Object[] {String.valueOf(itemCount), "0.3"},
180
			new Object[] {String.valueOf(style), "0.2"}
181
		};
182
	
183
		return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
184
	}
185
186
187
188
	private IWidgetId resolveToolbarItem(ToolItem item)
189
	{
190
		String text = convertText(limitText(item.getToolTipText()));
191
		String actionId = MacroUtil.getActionId(item).toString();
192
		String style = String.valueOf(item.getStyle());
193
		
194
		Object[] properties = 
195
		{
196
			new Object[] {text, "0.7"},
197
			new Object[] {actionId, "0.7"},
198
			new Object[] {style, "0.3"}
199
		};
200
	
201
		return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
202
	}
203
204
205
206
	private String limitText(String str)
207
	{
208
		final int MAX_HOVER_TEXT_SIZE = 20;
209
		if (str != null && str.length() > MAX_HOVER_TEXT_SIZE)
210
		{	
211
			return str.substring(0,MAX_HOVER_TEXT_SIZE) + "...";			
212
		}
213
		return str;
214
	}
215
216
217
218
	private IWidgetId resolveButton(Widget parent, Button button, Object id)
219
	{	
220
		String text = null, hoverText = null, size = null, location = null;
221
		if ((text = button.getText()) != null)
222
		{
223
			text = convertText(text.replaceAll("\\&", ""));
224
		}
225
		/* First 20 characters of the hover text */
226
		hoverText = convertText(limitText(button.getToolTipText()));
227
		Point sizePt = button.getSize();
228
		Point locationPt = button.getLocation();
229
		size = "(" + sizePt.x + "," + sizePt.y + ")";		
230
		location = "("  + locationPt.x + "," + locationPt.y + ")";		
231
		
232
		if (id != null && WeightedPropertyWidgetId.countTokens(id.toString())  == 3)
233
		{
234
			
235
			Object[] properties = 
236
				{
237
					new Object[] {text, "0.5"},
238
					new Object[] {hoverText, "0.5"},
239
					new Object[] {size, "0.5"}
240
				};
241
			
242
			return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
243
		}
244
		else
245
		{			
246
			if (parent instanceof Composite)
247
			{
248
				Control[] children = ((Composite)parent).getChildren();
249
				int buttonInx = 0;
250
				// if there are multiple buttons with the same text label
251
				int sameTextButtons = 0;
252
				String indexWeight = "0.2";
253
				String lengthWeight = "0.3";
254
				
255
				/* Find the index of the button */
256
				for (int i = 0; i < children.length; i++)
257
				{
258
					if (text != null && children[i] instanceof Button){
259
						String label = ((Button)children[i]).getText();
260
						if (label != null){
261
							label = convertText(label.replaceAll("\\&", ""));
262
							if (label.compareTo(text)  == 0)
263
								sameTextButtons++;
264
						}
265
					}
266
					if (button == children[i])
267
					{
268
						buttonInx = i;
269
						break;
270
					}
271
				}
272
				if (sameTextButtons > 0){
273
					// two or more buttons with the same label in the 
274
					// same child list under a composite parent
275
					// so shift the weighting to favor the button index
276
					// to get the right weighting
277
					indexWeight = "0.4";
278
					lengthWeight = "0.1";
279
				}
280
				
281
				Object[] properties = 
282
				{
283
						new Object[] {text, "0.3"},
284
						new Object[] {hoverText, "0.3"},
285
						new Object[] {String.valueOf(children.length), lengthWeight},
286
						new Object[] {size, "0.1"},
287
						new Object[] {location, "0.1"},
288
						new Object[] {String.valueOf(buttonInx), indexWeight},
289
				
290
				};
291
				
292
				float threshold = 0.7f;
293
				threshold += text != null ? 0.3 : 0;
294
				threshold += hoverText != null ? 0.3 : 0;
295
				
296
				if (threshold >= 1.0)
297
					return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
298
			}
299
		}
300
		
301
		return null;
302
	}
303
304
305
	/**
306
	 * Replace "#", "\n" and "\r" with space to avoid having "#" generated in the
307
	 * object id. The "#" is taken as the separator between widget Class name and
308
	 * rest of object id (see MacroObjectLocator.locateVisibleChild).
309
	 * 
310
	 * @param label
311
	 * @return
312
	 */
313
	private String convertText(String label) {
314
		return label == null ? null : label.replaceAll("#", " ").replaceAll("\n", " ").replaceAll("\r", " ");
315
	}
316
317
318
	/**
319
	 * The text of the closest label to a text box is used as a unique
320
	 * identifier of the text box.  The label must be in a limited
321
	 * vicinity of the text box for its text to be considered as an identifier.
322
	 * If the text box is owned by a group and the group only owns one text box, 
323
	 * then the group text is used to identify the widget.
324
	 * 
325
	 * @param text The text box
326
	 * @return The widget id for text
327
	 */
328
	private IWidgetId resolveText(Text text)
329
	{
330
		Composite parent = text.getParent();
331
		Control[] children = parent.getChildren();
332
		
333
		String groupText = null;
334
		if (parent instanceof Group && (groupText = ((Group)parent).getText()) != null && (groupText = groupText.replaceAll("\\&", "")).length() > 0)
335
		{
336
			int textBoxNum = 0;
337
			for (int i = 0; i < children.length && textBoxNum <= 1; i++)
338
			{
339
				if (children[i] instanceof Text)
340
					textBoxNum++;
341
			}
342
			
343
			if (textBoxNum <= 1)
344
				return new PrimitiveWidgetId(convertText(groupText));
345
		}
346
		
347
		Label closestLabel = null;
348
		Point textLocation = text.getLocation();
349
		Point currentDistance = new Point(0,0);
350
		Point tempDistance = new Point(0,0);
351
		for (int i = 0; i < children.length; i++)
352
		{
353
			Point childLocation = children[i].getLocation();
354
			if 	(children[i] instanceof Label && 
355
				(closestLabel == null || (tempDistance = isLabelCloser(childLocation, currentDistance, textLocation)) != null))
356
			{
357
				boolean firstLabel = closestLabel == null;
358
				closestLabel = (Label)children[i];;
359
				if (firstLabel)
360
				{
361
					currentDistance = new Point (Math.abs(childLocation.x - textLocation.x), Math.abs(childLocation.y - textLocation.y));
362
				}
363
				else
364
				{
365
					currentDistance = tempDistance;
366
				}
367
			}
368
		}
369
		
370
		String closestLabelText = null;
371
		if (closestLabel != null && currentDistance.x + currentDistance.y <= 100 &&  
372
			closestLabel.getText() != null && (closestLabelText = closestLabel.getText().replaceAll("\\&", "")).length() > 0)
373
			return new PrimitiveWidgetId(convertText(closestLabelText));
374
		return null;
375
	}
376
377
378
	private Point isLabelCloser(Point newlblLocation, Point currentDistance, Point textLocation)
379
	{
380
		Point tempLocation = new Point (Math.abs(newlblLocation.x - textLocation.x), Math.abs(newlblLocation.y - textLocation.y));
381
		if (tempLocation.x + tempLocation.y < currentDistance.x + currentDistance.y)
382
			return tempLocation;
383
		return null;
384
	}
385
386
387
	private IWidgetId validateText(String text)
388
	{
389
		if (text != null && (text = text.replaceAll("\\&", "")).length() > 0)
390
			return new PrimitiveWidgetId(convertText(text));		
391
		return null;
392
	}
393
394
395
	/**
396
	 * Computes the item id based on the following properties
397
	 * and weights.  The threshold is set to 1.0:
398
	 * 
399
	 * <ul>
400
	 * 	<li> (Descriptive name of the item, 1.0) </li>
401
	 * </ul>
402
	 * @param item The item
403
	 * @return The weighted id
404
	 */
405
	private IWidgetId resolveItem(Item item) 
406
	{		
407
		StringBuffer descriptiveText = new StringBuffer();
408
		findItemText(item, descriptiveText);			
409
		
410
		/* Remove the ampersands */
411
		String itemText = convertText(descriptiveText.toString().replaceAll("\\&", ""));
412
		
413
		Object[] properties = 
414
			{
415
				new Object[] {itemText, "1.0"},
416
			};
417
		
418
		return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
419
	}
420
421
	
422
	/**
423
	 * Walk through the item and return a descriptive text that corresponds
424
	 * to all item selections leading to the item. (e.g. File-New-Project)
425
	 * 
426
	 * @param item The item
427
	 * @param descriptiveText In the end, this buffer will contain a
428
	 * descriptive text of all items leading to the item that
429
	 * is passed in as argument
430
	 */
431
	private void findItemText(Item item, StringBuffer descriptiveText) 
432
	{
433
		if (item == null)
434
			return;
435
		
436
		String descriptiveTextStr = item.getText();
437
		if (descriptiveText.length() > 0)
438
			descriptiveTextStr += "-";
439
		
440
		descriptiveText.insert(0, descriptiveTextStr);
441
		
442
		Item parentItem = null;
443
		if (item instanceof MenuItem)
444
		{
445
			Menu menu = ((MenuItem)item).getParent();
446
			parentItem = (menu == null ? null : menu.getParentItem());
447
		}
448
		else if (item instanceof TreeItem)
449
		{
450
			parentItem = ((TreeItem)item).getParentItem();			
451
		}
452
				
453
		if (parentItem != null)
454
			findItemText(parentItem, descriptiveText);
455
	}
456
457
458
	private IWidgetId resolveFileSystemElement(Widget widget)
459
	{
460
			
461
		FileSystemElement fileSystemElement = (FileSystemElement) widget.getData();
462
		if (fileSystemElement.isDirectory())
463
			return null;
464
		
465
		Object[] properties = 
466
			{
467
				new Object[] {((IWorkbenchAdapter)fileSystemElement.getAdapter(IWorkbenchAdapter.class)).getLabel(null), "1.0"}
468
			};
469
		
470
		return WeightedPropertyWidgetId.constructId (properties, (float)1.0);
471
	}
472
473
	private WeightedPropertyWidgetId resolveAgentProxy(Widget widget)
474
	{	
475
		StringBuffer treeIndex = new StringBuffer();
476
		if (widget instanceof TreeItem)
477
			findTreeItemIndex((TreeItem)widget, treeIndex);
478
		else
479
			return null;
480
		
481
		TRCAgentProxy proxy = (TRCAgentProxy) widget.getData();
482
		Object[] properties = 
483
			{
484
				new Object[] {treeIndex.toString(), "0.4"},
485
				new Object[] {proxy.getProcessProxy().getName(), "0.2"},
486
				new Object[] {proxy.getProcessProxy().getVmArguments(), "0.1"},
487
				new Object[] {proxy.getProcessProxy().getClasspath(), "0.1"},
488
				new Object[] {proxy.getProcessProxy().getLocation(), "0.1"},
489
				new Object[] {proxy.getProcessProxy().getParameters(), "0.1"},
490
				new Object[] {proxy.getProfileFile(), "0.1"},
491
				new Object[] {proxy.getName(), "0.1"},
492
				new Object[] {String.valueOf(proxy.isAttached()), "0.1"},
493
				new Object[] {String.valueOf(proxy.isMonitored()), "0.1"},
494
				new Object[] {String.valueOf(proxy.isToProfileFile()), "0.1"},
495
			};
496
		
497
		return WeightedPropertyWidgetId.constructId (properties, (float)0.7);
498
	}
499
500
			
501
502
503
	private void findTreeItemIndex(TreeItem treeItem, StringBuffer sb)
504
	{
505
		TreeItem parentItem = treeItem.getParentItem();
506
		if (parentItem != null)
507
		{
508
			int index = parentItem.indexOf(treeItem);
509
			if (index != -1)
510
				sb.append("|" + String.valueOf(index + 1));
511
						
512
			findTreeItemIndex (parentItem, sb);			
513
		}
514
		Tree tree = treeItem.getParent();
515
		int index = tree.indexOf(treeItem);
516
		if (index != -1)
517
			sb.append("|" + String.valueOf(index));
518
		
519
	}
520
521
522
523
	public boolean foundWidget(Object object, Object id)
524
	{
525
		Object objectId = null;
526
		if (object instanceof Button)
527
		{
528
			Button button = (Button) object;
529
			objectId = resolveButton(button.getParent(), button, id);
530
		}
531
		
532
		if (objectId == null)
533
			objectId = getUniqueId(object instanceof Control ? ((Control)object).getParent() : null, object);
534
		return id == null ? false : objectId == null ? false : objectId.equals(id);		
535
	}
536
537
538
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/resolvers/AdaptiveWidgetResolver.java (-609 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AdaptiveWidgetResolver.java,v 1.7 2009/05/17 16:16:28 paules Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.resolvers;
13
14
import java.io.IOException;
15
import java.io.InputStream;
16
import java.lang.reflect.Method;
17
import java.net.URL;
18
import java.util.Hashtable;
19
import java.util.Vector;
20
21
import org.eclipse.hyades.test.common.util.XMLUtil;
22
import org.eclipse.jface.dialogs.MessageDialog;
23
import org.eclipse.swt.widgets.Control;
24
import org.eclipse.swt.widgets.Widget;
25
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
27
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
28
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetId;
29
import org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
31
import org.osgi.framework.Bundle;
32
import org.w3c.dom.Element;
33
import org.w3c.dom.NodeList;
34
35
/**
36
 * <p>The following widget resolver attempts to resolve widgets using a static
37
 * XML file stored under the auto-gui folder under this plug-in.</p>
38
 * 
39
 * 
40
 * @author  Ali Mehregani
41
 * @author  Paul Slauenwhite
42
 * @version May 16, 2009
43
 * @since   July 10, 2006
44
 */
45
public class AdaptiveWidgetResolver implements IWidgetResolver 
46
{
47
	/** 
48
	 * The id of this resolver -- must be in sync with the id registered with 
49
	 * the widgetResolver extension.
50
	 */
51
	private static final String ID = "org.eclipse.tptp.test.auto.gui.adaptive";
52
	
53
	/** The assumed file name relative to this plugin */
54
	public final static String WIDGET_REG_FILE = "auto-gui/widgetReg.xml";
55
	
56
	/** The widget registerations */
57
	private IWidgetRegistration widgetReg;
58
		
59
60
	public AdaptiveWidgetResolver()
61
	{		
62
		widgetReg = new WidgetRegistration (this, WIDGET_REG_FILE); 	
63
	}
64
	
65
	
66
	public IWidgetId getUniqueId(Widget parent, Object object)
67
	{
68
		if (!(object instanceof Widget))
69
			return null;
70
		
71
		widgetReg.load();
72
		IWidgetId widgetId = widgetReg.getWidgetId((Widget)object);
73
		if (widgetId != null)
74
			widgetId.setResolverId(ID);
75
		return widgetId;
76
	}
77
78
	/**
79
	 * Clients have the option of overwriting this in order to be able to locate
80
	 * the widget them self in the registeration entries that exist. 
81
	 */
82
	public WidgetRegValue findWidget (Hashtable registerations, Widget widget)
83
	{
84
		return null;
85
	}
86
	
87
	
88
	public class WidgetRegistration implements IWidgetRegistration
89
	{
90
		/* The file name */
91
		private String fileName;
92
		
93
		/* The last size of the file when it was properly read */
94
		private long lastModifiedDate;
95
		
96
		/* The file size (stored in case there was an error last time reading the file */
97
		private long lastModifiedDateDetected;
98
		
99
		/* Indicates if there was an error in parsing the file */
100
		private boolean errorOccurred;
101
		
102
		/* The data structures holding the registered widgets.
103
		 * Key = class name; Value =  WidgetRegValue */ 
104
		private Hashtable regWidgets;
105
			
106
		/* The global match threshold */
107
		private float globalMatchThreshold;
108
		
109
		/* The class name used for the default entry */
110
		public static final String DEFAULT_ENTYR = "0_DEFAULT_ENTRY";
111
		
112
		/* The adaptive widget resolver used as the driver for resolving widgets */
113
		private AdaptiveWidgetResolver adaptiveWidgetResolver; 
114
		
115
		public WidgetRegistration (AdaptiveWidgetResolver adaptiveWidgetResolver, String fileName)
116
		{
117
			this.fileName = fileName;
118
			this.lastModifiedDate = 0;
119
			this.lastModifiedDateDetected = 0;
120
			this.errorOccurred = false;
121
			this.regWidgets = new Hashtable();
122
			this.adaptiveWidgetResolver = adaptiveWidgetResolver;
123
		}
124
		
125
		
126
		public void load()
127
		{				
128
			InputStream regXMLInputStream = null;
129
			try
130
			{
131
				
132
			    
133
				Bundle guiBundle = GuiPlugin.getDefault().getBundle();
134
				long currentModifiedDate = guiBundle.getLastModified();// added for defect 169733 Liz Dancy
135
				
136
				/* Checking the file size doesn't guarantee to us that the file hasn't changed.  This is 
137
				 * the best we can do.  Replace this with last modified date if API is available. */
138
				if (currentModifiedDate > 0 && (currentModifiedDate == lastModifiedDate || (errorOccurred && lastModifiedDateDetected == currentModifiedDate)))
139
					return;
140
				
141
				URL regFileURL = GuiPlugin.getDefault().getBundle().getEntry(fileName);	
142
				lastModifiedDateDetected = currentModifiedDate;
143
				
144
				/* Parse the XML file */
145
				regXMLInputStream = regFileURL.openStream();
146
				Element rootElement = XMLUtil.loadDom(regXMLInputStream, "widgetResolverRule");
147
				if (rootElement == null)
148
				{
149
					lastModifiedDate = 0;
150
					errorOccurred = true;
151
					
152
					/* Display an error message if we are recording */
153
					if (MacroManager.getInstance().getGlobalState() == MacroManager.RECORDING_MODE)
154
					{
155
						AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, 
156
								AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, MessageDialog.WARNING);
157
					}
158
					return;
159
				}
160
				this.regWidgets.clear();
161
				parseRegFile(rootElement);
162
				lastModifiedDate = currentModifiedDate;
163
			}
164
			catch (Throwable t)
165
			{
166
				/* Set the file size to zero to invalidate this widget resolver */
167
				lastModifiedDate = 0;
168
				errorOccurred = true;
169
				
170
				/* Display an error message if we are recording */
171
				if (MacroManager.getInstance().getGlobalState() == MacroManager.RECORDING_MODE)
172
				{
173
					AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T, 
174
							AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER, MessageDialog.WARNING);
175
				}
176
			}
177
			finally
178
			{
179
				if (regXMLInputStream != null)
180
				{
181
					try
182
					{
183
						regXMLInputStream.close();
184
					} catch (IOException e)
185
					{
186
						/* Ignore the error */
187
					}
188
				}
189
			}
190
			
191
		}
192
193
		public float getGlobalThreshold()
194
		{
195
			return globalMatchThreshold;
196
		}
197
		
198
		/**
199
		 * parse the registation file that has already been loaded 
200
		 */
201
		private void parseRegFile(Element rootElement)
202
		{
203
			if (rootElement == null)
204
				return;
205
						
206
			NodeList classList = XMLUtil.getChildrenByName(rootElement, "class");
207
			parseClassElements (classList);
208
			globalMatchThreshold = Float.parseFloat(XMLUtil.getValue (rootElement, "globalMatchThreshold"));
209
			NodeList defaultList = XMLUtil.getChildrenByName(rootElement, "default");
210
			parseDefaultElements (defaultList);
211
		}
212
213
214
		private void parseDefaultElements(NodeList defaultList)
215
		{
216
			if (defaultList == null || defaultList.getLength() < 1)
217
				return;
218
			
219
			/* We only expect one default element */
220
			if(defaultList.item(0) instanceof Element)
221
			{
222
				Element defaultElement = (Element)defaultList.item(0);
223
				NodeList methodList = XMLUtil.getChildrenByName(defaultElement, "method");
224
				WidgetRegValue widgetReg = new WidgetRegValue();
225
					
226
				parseMethod (methodList, widgetReg);
227
				if (widgetReg != null)
228
					regWidgets.put(DEFAULT_ENTYR, widgetReg);
229
				
230
			}
231
		}
232
233
234
		/**
235
		 * Parse the class elements
236
		 */
237
		private void parseClassElements(NodeList classList)
238
		{
239
			if (classList == null || classList.getLength() <= 0)
240
				return;
241
			
242
			for(int i = 0; i < classList.getLength(); i++)
243
			{
244
				if(classList.item(i) instanceof Element)
245
				{
246
					
247
					Element classElement = (Element)classList.item(i);
248
					String className = XMLUtil.getValue(classElement, "name");
249
					NodeList methodList = XMLUtil.getChildrenByName(classElement, "method");
250
					WidgetRegValue widgetReg = new WidgetRegValue();
251
					String matchThreshold = XMLUtil.getValue(classElement, "matchThreshold");
252
					if (matchThreshold != null)
253
						widgetReg.setClassMatchThreshold(Float.parseFloat (matchThreshold));
254
					
255
					parseMethod (methodList, widgetReg);					
256
					if (widgetReg != null)
257
						regWidgets.put(className, widgetReg);
258
					
259
						
260
				}
261
			}
262
		}
263
264
265
		/**
266
		 * Parse the method element and return a widget registration entry
267
		 * 
268
		 * @param methodList The method list
269
		 * @param widgetReg the widget registration entry that will be augmented
270
		 * @return A widget registeration entry
271
		 */
272
		private void parseMethod(NodeList methodList, WidgetRegValue widgetReg)
273
		{
274
			if (methodList == null || methodList.getLength() <= 0)
275
				return;
276
			
277
			for(int i = 0; i < methodList.getLength(); i++)
278
			{
279
				if(methodList.item(i) instanceof Element)
280
				{
281
					Element methodElement = (Element)methodList.item(i);
282
					String methodName = XMLUtil.getValue(methodElement, "name");
283
					float weight = Float.parseFloat(XMLUtil.getValue(methodElement, "weight"));
284
					PropertyValue propertyVal = new PropertyValue();
285
					propertyVal.setWeight(weight);
286
					
287
					NodeList argumentList = XMLUtil.getChildrenByName(methodElement, "argument");
288
					if (argumentList != null)
289
						parseArguments(argumentList, propertyVal);
290
					
291
					widgetReg.addProperty(methodName, propertyVal);					
292
				}
293
			}			
294
		}
295
296
297
		/**
298
		 * Parse the arguments
299
		 * 
300
		 * @param argumentList The arugment list
301
		 * @param propertyVal The property value entry that will be augmented to.
302
		 */
303
		private void parseArguments(NodeList argumentList, PropertyValue propertyVal)
304
		{
305
			if (argumentList == null || argumentList.getLength() <= 0)
306
				return;
307
			
308
			Vector arguments = new Vector();
309
			for(int i = 0; i < argumentList.getLength(); i++)
310
			{
311
				if(argumentList.item(i) instanceof Element)
312
				{
313
					Element argumentElement = (Element)argumentList.item(i);
314
					String argumentValue = XMLUtil.getValue(argumentElement, "value");
315
					arguments.add(argumentValue);				
316
				}
317
			}	
318
			
319
			propertyVal.setArguments(arguments);			
320
		}
321
322
323
		public IWidgetId getWidgetId(Widget widget)
324
		{
325
			/* Use this resolver if we were able to successfully resolve parse the XML file */
326
			if (lastModifiedDate > 0)
327
			{
328
				/* First attempt the widget itself.  If that fails, then try its data attribute */
329
				Object data = widget;
330
331
				WidgetRegValue widgetValue = (WidgetRegValue)regWidgets.get(data.getClass().getName());
332
				if (widgetValue == null && widget.getData() != null)
333
				{
334
					data = widget.getData();
335
					widgetValue = (WidgetRegValue)regWidgets.get(data.getClass().getName());
336
					
337
					/* If that fails, then walk throught the class heirarchy (the interafaces and superclasses */
338
					if (widgetValue == null)
339
					{
340
						widgetValue = walkThroughClassHeirarchy (data.getClass());
341
342
					}					
343
				}
344
				
345
				/* As a final resolution, try and call the driver class to resolve the widget */
346
				if (widgetValue == null)
347
					widgetValue = adaptiveWidgetResolver.findWidget(regWidgets, widget);
348
				
349
				
350
				Vector propertyWeightPair = new Vector (5);
351
				WeightedPropertyWidgetId adaptiveWidgetId = new WeightedPropertyWidgetId();
352
				boolean specificValidEntry = false;
353
				boolean defaultValidEntry = false;
354
				
355
				if (widgetValue != null)
356
				{
357
					float threshold = widgetValue.getClassMatchThreshold();
358
					if (threshold == 0)
359
						threshold = globalMatchThreshold;
360
					adaptiveWidgetId.setThreshold(threshold);
361
					
362
					/* Specific properties associated with this type */
363
					specificValidEntry = appendProperties (data, propertyWeightPair, widgetValue);
364
				}
365
				
366
				/* Default properties */
367
				Vector defaultEntries = new Vector();
368
				defaultValidEntry = appendProperties (widget, defaultEntries, (WidgetRegValue)regWidgets.get(DEFAULT_ENTYR), true);
369
				if (defaultValidEntry)
370
					propertyWeightPair.addAll(propertyWeightPair);
371
				
372
				
373
				/* Return null if we weren't able to get any of the widgets properties */
374
				if (propertyWeightPair.size() <= 0)
375
					return null;
376
				
377
				adaptiveWidgetId.setPropertyWeightPair(propertyWeightPair.toArray());
378
				if (specificValidEntry || defaultValidEntry)
379
					return adaptiveWidgetId;
380
				return null;
381
			}
382
			
383
			return null;
384
		}
385
386
		
387
		private WidgetRegValue walkThroughClassHeirarchy(Class widgetClass) 
388
		{
389
			WidgetRegValue widgetValue = null;	
390
			
391
			widgetValue = (WidgetRegValue)regWidgets.get(widgetClass.getName());
392
			if (widgetValue != null)
393
				return widgetValue;
394
			
395
			Class[] interfaces = widgetClass.getInterfaces();
396
			
397
			/* Try the interfaces first */
398
			for (int i = 0; i < interfaces.length; i++)
399
			{
400
				widgetValue = (WidgetRegValue)regWidgets.get(interfaces[i].getName());
401
				widgetValue = (widgetValue == null ? walkThroughClassHeirarchy(interfaces[i]) : widgetValue);
402
				if (widgetValue != null)
403
					return widgetValue;
404
			}
405
			
406
			/* We failed with the interfaces, now try the super class */
407
			Class extendedClass = widgetClass.getSuperclass();
408
			if (extendedClass != null)
409
				widgetValue = walkThroughClassHeirarchy(extendedClass);
410
			
411
			return widgetValue;
412
		}
413
		
414
		
415
		private boolean appendProperties(Object data, Vector propertyWeightPair, WidgetRegValue widgetValue) 
416
		{
417
			return appendProperties(data, propertyWeightPair, widgetValue, false); 
418
		}
419
		
420
		private boolean appendProperties(Object data, Vector propertyWeightPair, WidgetRegValue widgetValue, boolean isDefault) 
421
		{
422
			boolean validEntry = false;
423
			if (widgetValue == null)
424
				return false;
425
			
426
			Vector properties = widgetValue.getProperties();
427
			for (int i = 0, propertySize = properties.size(); i < propertySize; i++)
428
			{
429
				String property = (String) properties.get(i);
430
				PropertyValue propertyValue = widgetValue.getPropertyValue(property);
431
				String retValue = invokeProperty (data, property, propertyValue);
432
				
433
				if ((retValue == null || retValue.length() <= 0) && isDefault)
434
					retValue = invokeProperty (((Widget)data).getData(), property, propertyValue);
435
				
436
				/* Don't add it if the return value is null or of zero length */
437
				if (retValue == null || retValue.length() <= 0)
438
					retValue = "null";				/* Set the value to the literal string 'null' */
439
				else
440
					validEntry = true;
441
				
442
				
443
				propertyWeightPair.add(new Object[] {retValue, String.valueOf(propertyValue.getWeight())});
444
			}
445
			return validEntry;
446
		}
447
448
449
		/**
450
		 * Invoke the appropriate method to get the property value
451
		 * 
452
		 * @param data The data corresponding to the widget or the data attribute of the widget
453
		 * @param theMethod The method corresponding to the property value 
454
		 * @param propertyValue The property information container
455
		 * 
456
		 * @return The returned value of the method corresponding to the argument
457
		 */
458
		private String invokeProperty(Object data, String theMethod, PropertyValue propertyValue)
459
		{
460
			try
461
			{
462
				Class theClass = data.getClass();
463
				int paramCount = 0;
464
				Vector args = propertyValue.getArguments(); 
465
				if (args != null && args.size() > 0)
466
					paramCount = args.size();
467
				
468
				/* We only support method with string parameters */
469
				Class[] params = new Class[paramCount];
470
				for (int i = 0; i < params.length; i++)
471
					params[i] = String.class;
472
				
473
				Method method = theClass.getMethod(theMethod, params);
474
				
475
				Object[] methodArgs = null;
476
				if (paramCount > 0)
477
					methodArgs = propertyValue.getArguments().toArray();
478
				
479
				Object retValue = method.invoke(data, methodArgs);
480
				return retValue.toString();
481
			}
482
			catch (Throwable t)
483
			{
484
				/* Return null if in case we can retrieve the property value */
485
				return null;	
486
			}
487
			
488
		}
489
490
491
		public WidgetRegValue getDefaultWidgetReg()
492
		{
493
			if (regWidgets == null)
494
				return null;
495
			return (WidgetRegValue)regWidgets.get(DEFAULT_ENTYR);
496
		}
497
		
498
	}
499
	
500
	
501
	/**
502
	 * Can be used to provide any alternative implementation of how the widget registration file 
503
	 * is loaded and queried.
504
	 * 
505
	 * @author Ali Mehregani
506
	 */
507
	public interface IWidgetRegistration
508
	{
509
		/**
510
		 * Used to load the necessary file and store the data in a datastructure that
511
		 * will later be used to query the registrations.
512
		 */
513
		public void load();
514
		
515
		/**
516
		 * Retrieve the widget id from the registrations
517
		 * 
518
		 * @param widget The widget in question
519
		 * @return The persistent identifier for the widget
520
		 */
521
		public IWidgetId getWidgetId (Widget widget);
522
	}
523
	
524
	
525
	/**
526
	 * A container class for the registration value of a widget
527
	 * 
528
	 * @author Ali Mehregani
529
	 */
530
	private class WidgetRegValue
531
	{
532
		/* Key = method names, value = propertyValue */
533
		private Hashtable properties;
534
		
535
		/* Class match treshold */
536
		private float classMatchThreshold;
537
		
538
		/* This vector is used to preserve the ordering of the properties inserted in the hashtable */
539
		private Vector hashKeys;
540
		
541
		public WidgetRegValue()
542
		{
543
			properties = new Hashtable();
544
			classMatchThreshold = 0;
545
			hashKeys = new Vector();
546
		}
547
		
548
		public Vector getProperties()
549
		{
550
			return hashKeys;
551
		}
552
		
553
		public PropertyValue getPropertyValue (String propertyValue)
554
		{
555
			return (PropertyValue) properties.get(propertyValue);
556
		}
557
		
558
		public void addProperty (String methodName, PropertyValue propertyValue)
559
		{
560
			hashKeys.add(methodName);
561
			properties.put (methodName, propertyValue);
562
		}
563
564
		public float getClassMatchThreshold()
565
		{
566
			return classMatchThreshold;
567
		}
568
569
		public void setClassMatchThreshold(float classMatchThreshold)
570
		{
571
			this.classMatchThreshold = classMatchThreshold;
572
		}
573
			
574
	}
575
	
576
	/**
577
	 * Container class for property values
578
	 * 
579
	 * @author Ali Mehregani
580
	 */
581
	private class PropertyValue
582
	{
583
		private Vector arguments;
584
		private float weight;
585
		
586
		public Vector getArguments()
587
		{
588
			return arguments;
589
		}
590
		public void setArguments(Vector arguments)
591
		{
592
			this.arguments = arguments;
593
		}
594
		public float getWeight()
595
		{
596
			return weight;
597
		}
598
		public void setWeight(float weight)
599
		{
600
			this.weight = weight;
601
		}			
602
	}
603
604
	public boolean foundWidget(Object object, Object id)
605
	{
606
		Object objectId = getUniqueId(object instanceof Control ? ((Control)object).getParent() : null, object);
607
		return id == null ? false : objectId == null ? false : objectId.equals(id);	
608
	}
609
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/resolvers/WeightedPropertyWidgetId.java (-230 lines)
Removed Link Here
1
/********************************************************************** 
2
 * Copyright (c) 2005, 2006 IBM Corporation and others. 
3
 * All rights reserved.   This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0 
5
 * which accompanies this distribution, and is available at 
6
 * http://www.eclipse.org/legal/epl-v10.html         
7
 * $Id: WeightedPropertyWidgetId.java,v 1.3 2006/12/04 02:55:08 amehregani Exp $ 
8
 * 
9
 * Contributors: 
10
 * IBM - Initial API and implementation 
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.resolvers;
13
14
import java.util.regex.Matcher;
15
import java.util.regex.Pattern;
16
17
import org.eclipse.hyades.test.common.util.XMLUtil;
18
19
/**
20
 * Defines a widget Id by a set of properties that the widget must have.  Each
21
 * property is assigned a weight and if the total weight exceeds the threshold, then
22
 * the widget is identified as a match
23
 * 
24
 * @author Ali Mehregani
25
 */
26
public class WeightedPropertyWidgetId extends PrimitiveWidgetId
27
{
28
	/* Stored elements are of type Object[2], where the first element is the value returned by the
29
	 * method corresponding to the property and the second value is the weight associated with that
30
	 * property. */
31
	private Object[] propertyWeightPair;
32
	private float threshold;
33
	
34
	private final static Pattern pairPattern  = Pattern.compile(".*?\\{\\{([^\\}]+)\\}\\}-\\{\\{([^\\}]+)\\}\\}.*");
35
	
36
	public boolean equals(Object obj) 
37
	{
38
		String stringToCompare = null;
39
		boolean compare = false;
40
		
41
		/* The object is of our own kind */
42
		if (obj instanceof WeightedPropertyWidgetId)
43
		{
44
			WeightedPropertyWidgetId idToCompareWith = (WeightedPropertyWidgetId)obj;
45
			
46
			if (this == idToCompareWith)
47
				return true;
48
			
49
			compare = true;
50
			stringToCompare = idToCompareWith.toString();
51
		}
52
			
53
		/* The object is a string (most likely coming from a macro) */
54
		else if (obj instanceof String)
55
		{
56
			compare = true;
57
			stringToCompare = (String)obj;
58
		}
59
		
60
		if (!compare)
61
			return false;
62
		
63
		/* Use regular expression to distinguish the returned value of each method
64
		 * from the weight */	
65
		float accumMatchRate = 0;
66
		int loopIterationNo = -1;
67
		
68
		while (stringToCompare.length() > 0 && (loopIterationNo + 1) < propertyWeightPair.length)
69
		{
70
			loopIterationNo++;
71
			Matcher pairTokenMatcher = pairPattern.matcher(stringToCompare);
72
			
73
			/* Discontinue if there is no match */
74
			if (!pairTokenMatcher.matches() || pairTokenMatcher.groupCount() != 2)
75
				break;
76
			
77
			/* Otherwise walk through each token */
78
			String originalProperty = pairTokenMatcher.group(1);
79
			String prop = originalProperty;
80
			if (prop.length() > 0)
81
				prop = XMLUtil.removeXMLSymbols(prop);
82
			float weight = Float.parseFloat(pairTokenMatcher.group(2));
83
		
84
			/* The ordering of the tokens for the IDs being compared must be the same. */
85
			Object[] propertyWeightPair = (Object[])this.propertyWeightPair[loopIterationNo];
86
			if (!prop.equals("null") && 
87
				(prop.length() > 0 ? prop.charAt(0) == ((String)propertyWeightPair[0]).charAt(0) || prop.charAt(0) == '&' : true) &&  
88
				(prop.equals(propertyWeightPair[0]) || prop.replaceAll("\\&", "").equals(propertyWeightPair[0]) || prop.replace('/', '\\').equals(propertyWeightPair[0])))
89
				accumMatchRate += Float.parseFloat((String)propertyWeightPair[1]);
90
			
91
			String currentToken = "{{" + originalProperty + "}}-{{" + weight + "}}";
92
			if (currentToken.equals(stringToCompare))
93
				break;
94
			
95
			int inx = stringToCompare.indexOf(currentToken);
96
			if (inx != -1)
97
				stringToCompare = stringToCompare.substring(inx + currentToken.length(), stringToCompare.length());
98
			
99
			else
100
				break;				/* The control flow should never reach this block */
101
			
102
		}
103
		
104
		if (accumMatchRate >= threshold)
105
			return true;
106
		return false;
107
	}
108
	
109
	
110
	/**
111
	 * Return a string representation of this identifier.  The property, weight information
112
	 * is organized in this format:  {{property-value1}}-{{weight1}}{{property-value2}}:{{weight2}}
113
	 */
114
	public String toString() 
115
	{
116
		String retValue = "";
117
		for (int i = 0; i < this.propertyWeightPair.length; i++)
118
			retValue += "{{" + ((Object[])this.propertyWeightPair[i])[0] + "}}-{{" + ((Object[])this.propertyWeightPair[i])[1] + "}}";
119
		
120
		return XMLUtil.useXMLSymbols(retValue);
121
	}
122
123
124
	public float getThreshold()
125
	{
126
		return threshold;
127
	}
128
129
130
	public void setThreshold(float threshold)
131
	{
132
		this.threshold = threshold;
133
	}
134
135
136
	public Object[] getPropertyWeightPair()
137
	{
138
		return propertyWeightPair;
139
	}
140
141
142
	public void setPropertyWeightPair(Object[] propertyWeightPair)
143
	{
144
		this.propertyWeightPair = propertyWeightPair;
145
	}
146
147
	/**
148
	 * Walk through the properties and return true for as long as one of them is not null.
149
	 * 
150
	 * @return true if at least one property is not null; false otherwise
151
	 */
152
	public boolean noValidProperties()
153
	{
154
		if (propertyWeightPair == null)
155
			return true;
156
		
157
		for (int i = 0; i < propertyWeightPair.length; i++)
158
		{
159
			String property = (String)((Object[])propertyWeightPair[i])[0];
160
			if (property != null && !property.equals("null"))
161
				return false;
162
		}
163
		return true;
164
	}
165
	
166
	
167
	/**
168
	 * Convenient method available for clients to use in order to construct a 
169
	 * weighted property id
170
	 * 
171
	 * @param properties The (properties, weight) pairs of the item (weights should be a value between (0, 1])
172
	 * @param threshold The threshold that this property should meet (should be a value between (0-1])
173
	 * @return Returns an instance of this class with the appropriate fields set.  
174
	 */
175
	protected static WeightedPropertyWidgetId constructId(Object[] properties, float threshold)
176
	{
177
		/* Step through the properties and replace null values with the literal string null */
178
		for (int i = 0; i < properties.length; i++)
179
		{
180
			String property = (String)((Object[])properties[i])[0];
181
			if (property == null || property.length() <= 0)
182
				((Object[])properties[i])[0] = "null";
183
			
184
		}
185
		
186
		WeightedPropertyWidgetId widgetId = new WeightedPropertyWidgetId ();
187
		widgetId.setPropertyWeightPair(properties);
188
		widgetId.setThreshold(threshold);
189
		
190
		if (widgetId.noValidProperties())
191
			return null;
192
		return widgetId;
193
	}
194
	
195
	
196
	/**
197
	 * Given a string representation of the id, this method will return the number of tokens
198
	 * that it contains.  A token is a name, value pair in the format.
199
	 * 
200
	 * @param id The string representation of the id
201
	 * @return The number of tokens of the id
202
	 */
203
	protected static int countTokens(String id)
204
	{
205
		if (id == null)
206
			return 0;
207
		
208
		char[] characters = id.toCharArray();
209
		boolean braceInxHit = false;
210
		int tokenCount = 0;
211
		for (int i = 0; i < characters.length; i++)
212
		{
213
			if (characters[i] == '{')
214
			{
215
				if (braceInxHit)
216
				{
217
					tokenCount++;
218
				}
219
				else
220
				{
221
					braceInxHit = true;
222
					continue;
223
				}
224
			}
225
			braceInxHit = false;			
226
		}
227
		
228
		return tokenCount / 2;
229
	}
230
}
(-)schema/widgetResolver.exsd (-134 / +137 lines)
Lines 1-134 Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.hyades.test.tools.ui">
3
<schema targetNamespace="org.eclipse.hyades.test.tools.ui">
4
<annotation>
4
<annotation>
5
      <appInfo>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.hyades.test.tools.ui" id="macroSupport" name="macroSupport"/>
6
         <meta.schema plugin="org.eclipse.hyades.test.tools.ui" id="macroSupport" name="macroSupport"/>
7
      </appInfo>
7
      </appInfo>
8
      <documentation>
8
      <documentation>
9
         Use this extension to define a class that is capable of resolving widgets.
9
         Use this extension to define a class that is capable of resolving widgets.
10
      </documentation>
10
      </documentation>
11
   </annotation>
11
   </annotation>
12
12
13
   <element name="extension">
13
   <element name="extension">
14
      <annotation>
14
      <annotation>
15
         <documentation>
15
         <appInfo>
16
            The following internal extension provides the mean for defining custom widget resolvers.
16
            <meta.element deprecated="true" replacement="uiObjectResolverDelegate" />
17
         </documentation>
17
         </appInfo>
18
      </annotation>
18
         <documentation>
19
      <complexType>
19
            The following internal extension provides the mean for defining custom widget resolvers.
20
         <sequence>
20
         </documentation>
21
            <element ref="widgetResolver" minOccurs="1" maxOccurs="unbounded"/>
21
      </annotation>
22
         </sequence>
22
      <complexType>
23
         <attribute name="point" type="string" use="required">
23
         <sequence>
24
            <annotation>
24
            <element ref="widgetResolver" minOccurs="1" maxOccurs="unbounded"/>
25
               <documentation>
25
         </sequence>
26
                  
26
         <attribute name="point" type="string" use="required">
27
               </documentation>
27
            <annotation>
28
            </annotation>
28
               <documentation>
29
         </attribute>
29
                  
30
         <attribute name="id" type="string">
30
               </documentation>
31
            <annotation>
31
            </annotation>
32
               <documentation>
32
         </attribute>
33
                  
33
         <attribute name="id" type="string">
34
               </documentation>
34
            <annotation>
35
            </annotation>
35
               <documentation>
36
         </attribute>
36
                  
37
         <attribute name="name" type="string">
37
               </documentation>
38
            <annotation>
38
            </annotation>
39
               <documentation>
39
         </attribute>
40
                  
40
         <attribute name="name" type="string">
41
               </documentation>
41
            <annotation>
42
               <appInfo>
42
               <documentation>
43
                  <meta.attribute translatable="true"/>
43
                  
44
               </appInfo>
44
               </documentation>
45
            </annotation>
45
               <appInfo>
46
         </attribute>
46
                  <meta.attribute translatable="true"/>
47
      </complexType>
47
               </appInfo>
48
   </element>
48
            </annotation>
49
49
         </attribute>
50
   <element name="widgetResolver">
50
      </complexType>
51
      <complexType>
51
   </element>
52
         <attribute name="class" type="string" use="required">
52
53
            <annotation>
53
   <element name="widgetResolver">
54
               <documentation>
54
      <complexType>
55
                  The class that is invoked to resolve a widget.
55
         <attribute name="class" type="string" use="required">
56
Must implement the following interface: org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver
56
            <annotation>
57
               </documentation>
57
               <documentation>
58
               <appInfo>
58
                  The class that is invoked to resolve a widget.
59
                  <meta.attribute kind="java" basedOn="org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver"/>
59
Must implement the following interface: org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver
60
               </appInfo>
60
               </documentation>
61
            </annotation>
61
               <appInfo>
62
         </attribute>
62
                  <meta.attribute kind="java" basedOn="org.eclipse.tptp.test.auto.gui.internal.core.IWidgetResolver"/>
63
         <attribute name="priority" type="string" use="required">
63
               </appInfo>
64
            <annotation>
64
            </annotation>
65
               <documentation>
65
         </attribute>
66
                  This attribute indicates the priority of the widget resolver relative to the other registered widget resolvers.  Widget resolvers are invoked in an descending order of their priority (e.g. The widget resolver with the highest priority attribute will be invoked first).
66
         <attribute name="priority" type="string" use="required">
67
The value of this attribute is expected to be an integer
67
            <annotation>
68
               </documentation>
68
               <documentation>
69
            </annotation>
69
                  This attribute indicates the priority of the widget resolver relative to the other registered widget resolvers.  Widget resolvers are invoked in an descending order of their priority (e.g. The widget resolver with the highest priority attribute will be invoked first).
70
         </attribute>
70
The value of this attribute is expected to be an integer
71
         <attribute name="id" type="string" use="required">
71
               </documentation>
72
            <annotation>
72
            </annotation>
73
               <documentation>
73
         </attribute>
74
                  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.
74
         <attribute name="id" type="string" use="required">
75
               </documentation>
75
            <annotation>
76
            </annotation>
76
               <documentation>
77
         </attribute>
77
                  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.
78
      </complexType>
78
               </documentation>
79
   </element>
79
            </annotation>
80
80
         </attribute>
81
   <annotation>
81
      </complexType>
82
      <appInfo>
82
   </element>
83
         <meta.section type="since"/>
83
84
      </appInfo>
84
   <annotation>
85
      <documentation>
85
      <appInfo>
86
         Since TPTP v4.1
86
         <meta.section type="since"/>
87
      </documentation>
87
      </appInfo>
88
   </annotation>
88
      <documentation>
89
89
         Since TPTP v4.1
90
   <annotation>
90
      </documentation>
91
      <appInfo>
91
   </annotation>
92
         <meta.section type="examples"/>
92
93
      </appInfo>
93
   <annotation>
94
      <documentation>
94
      <appInfo>
95
         &lt;!-- Define a widget resolver with priority 10 --&gt; 
95
         <meta.section type="examples"/>
96
  &lt;extension
96
      </appInfo>
97
  point=&quot;org.eclipse.tptp.test.auto.gui.widgetResolver&quot;&gt;
97
      <documentation>
98
     &lt;widgetResolver 
98
         &lt;!-- Define a widget resolver with priority 10 --&gt; 
99
      id = &quot;org.eclipse.tptp.test.auto.gui.adaptive&quot;
99
  &lt;extension
100
      class=&quot;org.eclipse.tptp.test.auto.gui.internal.recorder.AdaptiveWidgetResolver&quot;
100
  point=&quot;org.eclipse.tptp.test.auto.gui.widgetResolver&quot;&gt;
101
      priority=&quot;10&quot;
101
     &lt;widgetResolver 
102
     /&gt;
102
      id = &quot;org.eclipse.tptp.test.auto.gui.adaptive&quot;
103
  &lt;/extension&gt;
103
      class=&quot;org.eclipse.tptp.test.auto.gui.internal.recorder.AdaptiveWidgetResolver&quot;
104
      </documentation>
104
      priority=&quot;10&quot;
105
   </annotation>
105
     /&gt;
106
106
  &lt;/extension&gt;
107
   <annotation>
107
      </documentation>
108
      <appInfo>
108
   </annotation>
109
         <meta.section type="apiInfo"/>
109
110
      </appInfo>
110
   <annotation>
111
      <documentation>
111
      <appInfo>
112
         [Enter API information here.]
112
         <meta.section type="apiInfo"/>
113
      </documentation>
113
      </appInfo>
114
   </annotation>
114
      <documentation>
115
115
         [Enter API information here.]
116
   <annotation>
116
      </documentation>
117
      <appInfo>
117
   </annotation>
118
         <meta.section type="implementation"/>
118
119
      </appInfo>
119
   <annotation>
120
      <documentation>
120
      <appInfo>
121
         [Enter information about supplied implementation of this extension point.]
121
         <meta.section type="implementation"/>
122
      </documentation>
122
      </appInfo>
123
   </annotation>
123
      <documentation>
124
124
         [Enter information about supplied implementation of this extension point.]
125
   <annotation>
125
      </documentation>
126
      <appInfo>
126
   </annotation>
127
         <meta.section type="copyright"/>
127
128
      </appInfo>
128
   <annotation>
129
      <documentation>
129
      <appInfo>
130
         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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
130
         <meta.section type="copyright"/>
131
      </documentation>
131
      </appInfo>
132
   </annotation>
132
      <documentation>
133
133
         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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
134
</schema>
134
      </documentation>
135
   </annotation>
136
137
</schema>
(-)src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCasesForm.java (-13 / +13 lines)
Lines 1-10 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUITestCasesForm.java,v 1.24 2009/05/17 16:16:29 paules Exp $
7
 * $Id: AutoGUITestCasesForm.java,v 1.23 2008/04/10 01:28:58 paules Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
Lines 95-103 Link Here
95
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIRefreshAction;
95
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIRefreshAction;
96
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUITestCaseAction;
96
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUITestCaseAction;
97
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIUpdateTestCaseAction;
97
import org.eclipse.tptp.test.auto.gui.internal.actions.AutoGUIUpdateTestCaseAction;
98
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
99
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MacroUIInstruction;
98
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MacroUIInstruction;
100
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager;
99
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
100
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
101
import org.eclipse.ui.IActionBars;
101
import org.eclipse.ui.IActionBars;
102
import org.eclipse.ui.actions.ActionFactory;
102
import org.eclipse.ui.actions.ActionFactory;
103
import org.eclipse.ui.forms.IManagedForm;
103
import org.eclipse.ui.forms.IManagedForm;
Lines 110-122 Link Here
110
110
111
111
112
/** 
112
/** 
113
 * <p>This form provides the 'macro-examine' page that allows users to easily navigate through
113
 * This form provides the 'macro-examine' page that allows users to easily navigate through
114
 * a acro and make the appropriate adjustments.</p>
114
 * a macro and make the appropriate adjustments.
115
 * 
115
 * 
116
 * 
116
 * 
117
 * @author      Ali Mehregani
117
 * @author      Ali Mehregani
118
 * @author      Paul E. Slauenwhite
118
 * @author      Paul E. Slauenwhite
119
 * @version     May 16, 2009
119
 * @version     April 7, 2008
120
 * @since       August 19, 2006
120
 * @since       August 19, 2006
121
 */
121
 */
122
public class AutoGUITestCasesForm extends TestCasesEclipseForm implements ITextEditorExtension2
122
public class AutoGUITestCasesForm extends TestCasesEclipseForm implements ITextEditorExtension2
Lines 177-183 Link Here
177
	private Text startingPttxt;
177
	private Text startingPttxt;
178
	
178
	
179
	/* The object mine tree */
179
	/* The object mine tree */
180
	private AutoGUIObjectMineTreeStructure objectMineTree;
180
	private AutoGUIMacroObjectDescriptorMineTreeStructure objectMineTree;
181
181
182
	/* The object mine listener */
182
	/* The object mine listener */
183
	private ObjectMineTreeListener objectMineListener;
183
	private ObjectMineTreeListener objectMineListener;
Lines 213-219 Link Here
213
		lastTreeHierarchySelected = new LinkedList();
213
		lastTreeHierarchySelected = new LinkedList();
214
		logicalTreeRepresentaion = new AutoGUITestCaseTreeStructure (editor, Common_TestprofilePackage.eINSTANCE.getTPFTestSuite_TestCases());
214
		logicalTreeRepresentaion = new AutoGUITestCaseTreeStructure (editor, Common_TestprofilePackage.eINSTANCE.getTPFTestSuite_TestCases());
215
		logicalRepresentationListener = new LogicalRepresentationListener();
215
		logicalRepresentationListener = new LogicalRepresentationListener();
216
		objectMineTree = new AutoGUIObjectMineTreeStructure(this, editor);		
216
		objectMineTree = new AutoGUIMacroObjectDescriptorMineTreeStructure(this, editor);		
217
		linearOperationHistory = new DefaultOperationHistory();		
217
		linearOperationHistory = new DefaultOperationHistory();		
218
		context = new Hashtable();
218
		context = new Hashtable();
219
		isOperationHistory = true;
219
		isOperationHistory = true;
Lines 1013-1020 Link Here
1013
			{
1013
			{
1014
				Object[] selectedItems = ((StructuredSelection)selectedEntity).toArray();
1014
				Object[] selectedItems = ((StructuredSelection)selectedEntity).toArray();
1015
				Integer[] lineLevelDetail = null;
1015
				Integer[] lineLevelDetail = null;
1016
				if (selectedItems.length == 1 && selectedItems[0] instanceof IUIObject)
1016
				if (selectedItems.length == 1 && selectedItems[0] instanceof MacroObjectDescriptor)
1017
					lineLevelDetail = (Integer[])((IUIObject)selectedItems[0]).getData();
1017
					lineLevelDetail = (Integer[])((MacroObjectDescriptor)selectedItems[0]).getData();
1018
				
1018
				
1019
				/* Select the XML fragment if the line level information is available */
1019
				/* Select the XML fragment if the line level information is available */
1020
				if (lineLevelDetail != null)
1020
				if (lineLevelDetail != null)
Lines 1036-1042 Link Here
1036
				return;
1036
				return;
1037
								
1037
								
1038
			/* Update the offest that each tree item keeps track */
1038
			/* Update the offest that each tree item keeps track */
1039
			ObjectMineManager.getInstance().markObjectMineDirty (getTestSuite());
1039
			MacroObjectDescriptorMineManager.getInstance().markObjectMineDirty (getTestSuite());
1040
			if (isOperationHistory)
1040
			if (isOperationHistory)
1041
			{
1041
			{
1042
				objectMineTree.updateOffsetRelation(AutoGUITestCasesForm.this, objectMineTree.getLineOffsetRelation(), event.length, event.replacedText.length());
1042
				objectMineTree.updateOffsetRelation(AutoGUITestCasesForm.this, objectMineTree.getLineOffsetRelation(), event.length, event.replacedText.length());
Lines 1076-1082 Link Here
1076
		}
1076
		}
1077
	}
1077
	}
1078
	
1078
	
1079
	public AutoGUIObjectMineTreeStructure getObjectMineTreeStruct()
1079
	public AutoGUIMacroObjectDescriptorMineTreeStructure getObjectMineTreeStruct()
1080
	{
1080
	{
1081
		return objectMineTree;
1081
		return objectMineTree;
1082
	}
1082
	}
(-)src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUITestCaseTreeStructure.java (-649 / +649 lines)
Lines 1-649 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.editor;
11
package org.eclipse.tptp.test.auto.gui.internal.editor;
12
12
13
import java.io.ByteArrayInputStream;
13
import java.io.ByteArrayInputStream;
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.Hashtable;
15
import java.util.Hashtable;
16
16
17
import org.eclipse.core.runtime.IStatus;
17
import org.eclipse.core.runtime.IStatus;
18
import org.eclipse.emf.ecore.EStructuralFeature;
18
import org.eclipse.emf.ecore.EStructuralFeature;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
20
import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter;
20
import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter;
21
import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider;
21
import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider;
22
import org.eclipse.hyades.ui.editor.IEditorExtension;
22
import org.eclipse.hyades.ui.editor.IEditorExtension;
23
import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider;
23
import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider;
24
import org.eclipse.jface.viewers.IContentProvider;
24
import org.eclipse.jface.viewers.IContentProvider;
25
import org.eclipse.jface.viewers.ILabelProvider;
25
import org.eclipse.jface.viewers.ILabelProvider;
26
import org.eclipse.jface.viewers.ISelectionChangedListener;
26
import org.eclipse.jface.viewers.ISelectionChangedListener;
27
import org.eclipse.jface.viewers.IStructuredSelection;
27
import org.eclipse.jface.viewers.IStructuredSelection;
28
import org.eclipse.jface.viewers.SelectionChangedEvent;
28
import org.eclipse.jface.viewers.SelectionChangedEvent;
29
import org.eclipse.osgi.util.NLS;
29
import org.eclipse.osgi.util.NLS;
30
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.SWT;
31
import org.eclipse.swt.graphics.Image;
31
import org.eclipse.swt.graphics.Image;
32
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Composite;
33
import org.eclipse.swt.widgets.TreeItem;
33
import org.eclipse.swt.widgets.TreeItem;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
34
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
35
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
35
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
36
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
36
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
37
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
38
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler;
39
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
40
import org.w3c.dom.Node;
40
import org.w3c.dom.Node;
41
import org.w3c.dom.NodeList;
41
import org.w3c.dom.NodeList;
42
42
43
/**
43
/**
44
 * This class represents the test case tree
44
 * This class represents the test case tree
45
 * 
45
 * 
46
 * 
46
 * 
47
 * @author      Ali Mehregani
47
 * @author      Ali Mehregani
48
 * @author      Paul E. Slauenwhite
48
 * @author      Paul E. Slauenwhite
49
 * @version     March 5, 2008
49
 * @version     March 5, 2008
50
 * @since       March 17, 2006
50
 * @since       March 17, 2006
51
 */
51
 */
52
public class AutoGUITestCaseTreeStructure extends AutoGUIAbstractTreeStructure implements ISelectionChangedListener
52
public class AutoGUITestCaseTreeStructure extends AutoGUIAbstractTreeStructure implements ISelectionChangedListener
53
{
53
{
54
	/** Stores the cached parsed macro <br/>
54
	/** Stores the cached parsed macro <br/>
55
	 * Key = Test case id <br/>
55
	 * Key = Test case id <br/>
56
	 * Value = An array list containing the macro UI instructions that fall
56
	 * Value = An array list containing the macro UI instructions that fall
57
	 * under it. <br/>
57
	 * under it. <br/>
58
	 */
58
	 */
59
	private Hashtable cachedParsedMacro;
59
	private Hashtable cachedParsedMacro;
60
	
60
	
61
	
61
	
62
	/**
62
	/**
63
	 * Stores the line number and offset of a macro: <br/>
63
	 * Stores the line number and offset of a macro: <br/>
64
	 * Key = Test case object of type ITestCase <br/>
64
	 * Key = Test case object of type ITestCase <br/>
65
	 * Value = An array list with the following content:
65
	 * Value = An array list with the following content:
66
	 * 		   Index of the array list = line number in the macro
66
	 * 		   Index of the array list = line number in the macro
67
	 * 		   Value of the array list element = offset in the
67
	 * 		   Value of the array list element = offset in the
68
	 * 		   macro corresponding to the line number <br/>
68
	 * 		   macro corresponding to the line number <br/>
69
	 */
69
	 */
70
	private Hashtable cachedLineOffsetIndicator;
70
	private Hashtable cachedLineOffsetIndicator;
71
	
71
	
72
	/** Allows for the retrieval of test case properties */
72
	/** Allows for the retrieval of test case properties */
73
	private GUITestCaseProperties testCasePropertyManager;
73
	private GUITestCaseProperties testCasePropertyManager;
74
	
74
	
75
	/** The currently selected test case */
75
	/** The currently selected test case */
76
	private ITestCase selectedTestCase;
76
	private ITestCase selectedTestCase;
77
	
77
	
78
	
78
	
79
	/**
79
	/**
80
	 * Constructor 
80
	 * Constructor 
81
	 * @param editorPart The editor part
81
	 * @param editorPart The editor part
82
	 * @param eStructuralFeature The structural feature
82
	 * @param eStructuralFeature The structural feature
83
	 */
83
	 */
84
	public AutoGUITestCaseTreeStructure(IEditorExtension editorPart, EStructuralFeature eStructuralFeature)
84
	public AutoGUITestCaseTreeStructure(IEditorExtension editorPart, EStructuralFeature eStructuralFeature)
85
	{
85
	{
86
		super(editorPart, eStructuralFeature);
86
		super(editorPart, eStructuralFeature);
87
		cachedParsedMacro = new Hashtable();
87
		cachedParsedMacro = new Hashtable();
88
		cachedLineOffsetIndicator = new Hashtable();
88
		cachedLineOffsetIndicator = new Hashtable();
89
		testCasePropertyManager = new GUITestCaseProperties();
89
		testCasePropertyManager = new GUITestCaseProperties();
90
	}
90
	}
91
		
91
		
92
	/**
92
	/**
93
	 * Overwrite this method so that a custom content provider can be 
93
	 * Overwrite this method so that a custom content provider can be 
94
	 * registered with the tree
94
	 * registered with the tree
95
	 */
95
	 */
96
	protected IContentProvider createContentProvider()
96
	protected IContentProvider createContentProvider()
97
	{
97
	{
98
		getTreeViewer().addSelectionChangedListener(this);
98
		getTreeViewer().addSelectionChangedListener(this);
99
		return new TestCaseTreeContentProvider(editorPart, getEStructuralFeature());
99
		return new TestCaseTreeContentProvider(editorPart, getEStructuralFeature());
100
	}
100
	}
101
		
101
		
102
	
102
	
103
	/**
103
	/**
104
	 * Overwrite this method so that a custom label provider can be 
104
	 * Overwrite this method so that a custom label provider can be 
105
	 * registered with the tree
105
	 * registered with the tree
106
	 */
106
	 */
107
	protected ILabelProvider createLabelProvider()
107
	protected ILabelProvider createLabelProvider()
108
	{
108
	{
109
		return new TestCaseTreeLabelProvider(TestWorkbenchAdapter.class);
109
		return new TestCaseTreeLabelProvider(TestWorkbenchAdapter.class);
110
	}
110
	}
111
	
111
	
112
	
112
	
113
	/**
113
	/**
114
	 * Parses the test case and creates its associatreb
114
	 * Parses the test case and creates its associatreb
115
	 * 
115
	 * 
116
	 * @param testCase The test case to be parsed
116
	 * @param testCase The test case to be parsed
117
	 * @return An array list of the direct elements of test case  
117
	 * @return An array list of the direct elements of test case  
118
	 */
118
	 */
119
	private ArrayList parseMacro(ITestCase testCase) 
119
	private ArrayList parseMacro(ITestCase testCase) 
120
	{	
120
	{	
121
		testCasePropertyManager.setTestCase(testCase);
121
		testCasePropertyManager.setTestCase(testCase);
122
		String macro = testCasePropertyManager.getProperty(GUITestCaseProperties.MACRO_FRAGMENT);
122
		String macro = testCasePropertyManager.getProperty(GUITestCaseProperties.MACRO_FRAGMENT);
123
		
123
		
124
		try 
124
		try 
125
		{
125
		{
126
			XMLDefaultHandler handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(macro.getBytes("UTF-8")));
126
			XMLDefaultHandler handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(macro.getBytes("UTF-8")));
127
			ArrayList macroInstructions = new ArrayList();
127
			ArrayList macroInstructions = new ArrayList();
128
			findMacroInstructions (macroInstructions, handler.getDocumentElement(), handler.getLineTable(), 0, 0);
128
			findMacroInstructions (macroInstructions, handler.getDocumentElement(), handler.getLineTable(), 0, 0);
129
			cachedParsedMacro.put(testCase.getId(), macroInstructions);
129
			cachedParsedMacro.put(testCase.getId(), macroInstructions);
130
			return macroInstructions;
130
			return macroInstructions;
131
		} 
131
		} 
132
		catch (Throwable t)
132
		catch (Throwable t)
133
		{
133
		{
134
			/* There was an error parsing the XML.  Create an error element and return it */
134
			/* There was an error parsing the XML.  Create an error element and return it */
135
			MessageUIElement element = new MessageUIElement(IStatus.ERROR, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_MACRO_XML, t.getMessage()));
135
			MessageUIElement element = new MessageUIElement(IStatus.ERROR, NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_MACRO_XML, t.getMessage()));
136
			ArrayList error = new ArrayList();
136
			ArrayList error = new ArrayList();
137
			error.add(element);
137
			error.add(element);
138
			return error;
138
			return error;
139
		}		
139
		}		
140
	}
140
	}
141
	
141
	
142
	private void findMacroInstructions(ArrayList macroInstructions, Node node, Hashtable lineTable, int shellNumber, int commandNumber) 
142
	private void findMacroInstructions(ArrayList macroInstructions, Node node, Hashtable lineTable, int shellNumber, int commandNumber) 
143
	{
143
	{
144
		/* Traverse the node and create the tree items for each shell or command element */
144
		/* Traverse the node and create the tree items for each shell or command element */
145
		NodeList nodeList = node.getChildNodes();
145
		NodeList nodeList = node.getChildNodes();
146
		Node currentNode;
146
		Node currentNode;
147
		String currentNodeName;
147
		String currentNodeName;
148
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++)
148
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++)
149
		{
149
		{
150
			currentNode = nodeList.item(i);
150
			currentNode = nodeList.item(i);
151
			currentNodeName = currentNode.getNodeName();
151
			currentNodeName = currentNode.getNodeName();
152
			MacroUIInstruction uiInstruction = null;
152
			MacroUIInstruction uiInstruction = null;
153
			if (currentNodeName.equals(MacroConstants.SHELL_ELEMENT))
153
			if (currentNodeName.equals(MacroConstants.SHELL_ELEMENT))
154
			{
154
			{
155
				String textValue = getAttribute(currentNode, MacroConstants.DESCRIPTIVE_ATTRIBUTE, null);
155
				String textValue = getAttribute(currentNode, MacroConstants.DESCRIPTIVE_ATTRIBUTE, null);
156
				if (textValue == null)
156
				if (textValue == null)
157
					textValue = NLS.bind(AutoGUIMessages.TST_SUITE_AUTO_MACRO_SHELL, String.valueOf(shellNumber++)) +  getAttribute(currentNode, MacroConstants.ID_ATTRIBUTE, "");
157
					textValue = NLS.bind(AutoGUIMessages.TST_SUITE_AUTO_MACRO_SHELL, String.valueOf(shellNumber++)) +  getAttribute(currentNode, MacroConstants.ID_ATTRIBUTE, "");
158
				
158
				
159
				uiInstruction = new MacroUIInstruction(textValue, (Integer[])lineTable.get(currentNode));				
159
				uiInstruction = new MacroUIInstruction(textValue, (Integer[])lineTable.get(currentNode));				
160
				findMacroInstructions (uiInstruction.getSubInstructions(), currentNode, lineTable, shellNumber, 0);
160
				findMacroInstructions (uiInstruction.getSubInstructions(), currentNode, lineTable, shellNumber, 0);
161
			}
161
			}
162
			else if (currentNodeName.equals(MacroConstants.COMMAND_ELEMENT))
162
			else if (currentNodeName.equals(MacroConstants.COMMAND_ELEMENT))
163
			{
163
			{
164
				String textValue = getAttribute(currentNode, MacroConstants.TYPE_ATTRIBUTE, MacroConstants.COMMAND_ELEMENT);
164
				String textValue = getAttribute(currentNode, MacroConstants.TYPE_ATTRIBUTE, MacroConstants.COMMAND_ELEMENT);
165
				String descriptiveField = getAttribute(currentNode, MacroConstants.DESCRIPTIVE_ATTRIBUTE, null);
165
				String descriptiveField = getAttribute(currentNode, MacroConstants.DESCRIPTIVE_ATTRIBUTE, null);
166
				if (descriptiveField != null)
166
				if (descriptiveField != null)
167
					textValue += " \"" + descriptiveField + "\"";
167
					textValue += " \"" + descriptiveField + "\"";
168
				
168
				
169
				uiInstruction = new MacroUIInstruction(textValue, (Integer[])lineTable.get(currentNode));				
169
				uiInstruction = new MacroUIInstruction(textValue, (Integer[])lineTable.get(currentNode));				
170
			}			
170
			}			
171
			
171
			
172
			if (uiInstruction != null)
172
			if (uiInstruction != null)
173
				macroInstructions.add(uiInstruction);
173
				macroInstructions.add(uiInstruction);
174
		}
174
		}
175
	}
175
	}
176
	
176
	
177
	private String getAttribute(Node node, String attributeName, String defaultValue)
177
	private String getAttribute(Node node, String attributeName, String defaultValue)
178
	{
178
	{
179
		Node textNode = node.getAttributes().getNamedItem(attributeName);		
179
		Node textNode = node.getAttributes().getNamedItem(attributeName);		
180
		String text = (textNode == null ? defaultValue : textNode.getNodeValue());
180
		String text = (textNode == null ? defaultValue : textNode.getNodeValue());
181
		
181
		
182
		return text;
182
		return text;
183
	}
183
	}
184
	
184
	
185
	
185
	
186
	/**
186
	/**
187
	 * Returns an array list that indicates the line offset relation of a macro
187
	 * Returns an array list that indicates the line offset relation of a macro
188
	 * for a test case.
188
	 * for a test case.
189
	 * 
189
	 * 
190
	 * @param testCase The test case whose line-offest relation will be returned.
190
	 * @param testCase The test case whose line-offest relation will be returned.
191
	 * @return An array list (the index of the array list indicates the line number
191
	 * @return An array list (the index of the array list indicates the line number
192
	 * of the macro and the value of the array list indicates the offset value).
192
	 * of the macro and the value of the array list indicates the offset value).
193
	 */
193
	 */
194
	public ArrayList getLineOffsetRelation(ITestCase testCase)
194
	public ArrayList getLineOffsetRelation(ITestCase testCase)
195
	{
195
	{
196
		if (testCase == null)
196
		if (testCase == null)
197
			return null;
197
			return null;
198
		
198
		
199
		ArrayList lineOffsetIndicator = (ArrayList)cachedLineOffsetIndicator.get(testCase);
199
		ArrayList lineOffsetIndicator = (ArrayList)cachedLineOffsetIndicator.get(testCase);
200
		if (lineOffsetIndicator == null)
200
		if (lineOffsetIndicator == null)
201
		{
201
		{
202
			lineOffsetIndicator = findLineOffsetIndicator (testCase);
202
			lineOffsetIndicator = findLineOffsetIndicator (testCase);
203
			if (lineOffsetIndicator == null)
203
			if (lineOffsetIndicator == null)
204
				return null;
204
				return null;
205
			
205
			
206
			cachedLineOffsetIndicator.put(testCase, lineOffsetIndicator);
206
			cachedLineOffsetIndicator.put(testCase, lineOffsetIndicator);
207
		}
207
		}
208
		
208
		
209
		return lineOffsetIndicator;
209
		return lineOffsetIndicator;
210
	}
210
	}
211
	
211
	
212
	
212
	
213
	/**
213
	/**
214
	 * Looks up the current test case selected and returns its associated 
214
	 * Looks up the current test case selected and returns its associated 
215
	 * line-offset relation
215
	 * line-offset relation
216
	 *  
216
	 *  
217
	 * @return The line-offset relation.
217
	 * @return The line-offset relation.
218
	 */
218
	 */
219
	public ArrayList getLineOffsetRelation()
219
	public ArrayList getLineOffsetRelation()
220
	{
220
	{
221
		return getLineOffsetRelation(getSelectedTestCase());
221
		return getLineOffsetRelation(getSelectedTestCase());
222
	}
222
	}
223
	
223
	
224
	
224
	
225
	/**
225
	/**
226
	 * Find line-offset relation
226
	 * Find line-offset relation
227
	 * 
227
	 * 
228
	 * @param testCase The test case
228
	 * @param testCase The test case
229
	 * @return The line-offset relation for a test case macro.
229
	 * @return The line-offset relation for a test case macro.
230
	 */
230
	 */
231
	private ArrayList findLineOffsetIndicator(ITestCase testCase)
231
	private ArrayList findLineOffsetIndicator(ITestCase testCase)
232
	{
232
	{
233
		testCasePropertyManager.setTestCase(testCase);
233
		testCasePropertyManager.setTestCase(testCase);
234
		String macroStr = testCasePropertyManager.getProperty(GUITestCaseProperties.MACRO_FRAGMENT);
234
		String macroStr = testCasePropertyManager.getProperty(GUITestCaseProperties.MACRO_FRAGMENT);
235
		
235
		
236
		return super.findLineOffsetIndicator(macroStr);
236
		return super.findLineOffsetIndicator(macroStr);
237
	}
237
	}
238
238
239
	
239
	
240
	/**
240
	/**
241
	 * Detect the selection change and update the selection-dependent
241
	 * Detect the selection change and update the selection-dependent
242
	 * controls.
242
	 * controls.
243
	 * 
243
	 * 
244
	 * @param event The selection event
244
	 * @param event The selection event
245
	 */	 
245
	 */	 
246
	public void selectionChanged(SelectionChangedEvent event)
246
	public void selectionChanged(SelectionChangedEvent event)
247
	{
247
	{
248
		TreeItem[] treeItems = this.getTreeViewer().getTree().getSelection();
248
		TreeItem[] treeItems = this.getTreeViewer().getTree().getSelection();
249
		selectedTestCase = null;
249
		selectedTestCase = null;
250
		 
250
		 
251
		for (int i = 0; i < treeItems.length; i++)
251
		for (int i = 0; i < treeItems.length; i++)
252
		{
252
		{
253
			 ITestCase rootTestCase = findRootTestCase(treeItems[i]);
253
			 ITestCase rootTestCase = findRootTestCase(treeItems[i]);
254
			 if (selectedTestCase != null && selectedTestCase != rootTestCase)
254
			 if (selectedTestCase != null && selectedTestCase != rootTestCase)
255
			 {
255
			 {
256
				 selectedTestCase = null;
256
				 selectedTestCase = null;
257
				 return;
257
				 return;
258
			 }
258
			 }
259
			 selectedTestCase = rootTestCase;
259
			 selectedTestCase = rootTestCase;
260
		}
260
		}
261
	}
261
	}
262
262
263
263
264
	public ITestCase findRootTestCase(TreeItem item)
264
	public ITestCase findRootTestCase(TreeItem item)
265
	{
265
	{
266
		TreeItem parentItem = item.getParentItem();
266
		TreeItem parentItem = item.getParentItem();
267
		if (parentItem == null)
267
		if (parentItem == null)
268
		{
268
		{
269
			Object data = item.getData();
269
			Object data = item.getData();
270
			if (data instanceof ITestCase)
270
			if (data instanceof ITestCase)
271
				return (ITestCase)data;
271
				return (ITestCase)data;
272
			return null;
272
			return null;
273
		}
273
		}
274
		else 
274
		else 
275
			return findRootTestCase(parentItem);		
275
			return findRootTestCase(parentItem);		
276
	}
276
	}
277
277
278
	
278
	
279
	/**
279
	/**
280
	 * Return the currently selected test case.  It can be null in the
280
	 * Return the currently selected test case.  It can be null in the
281
	 * case of multiple selections or if no test case is selected
281
	 * case of multiple selections or if no test case is selected
282
	 * 
282
	 * 
283
	 * @return the currently selected test case
283
	 * @return the currently selected test case
284
	 */
284
	 */
285
	public ITestCase getSelectedTestCase ()
285
	public ITestCase getSelectedTestCase ()
286
	{
286
	{
287
		return selectedTestCase;
287
		return selectedTestCase;
288
	}
288
	}
289
	
289
	
290
	
290
	
291
	/**
291
	/**
292
	 * Need to overwrite this method since there are no buttons whose status need
292
	 * Need to overwrite this method since there are no buttons whose status need
293
	 * to be updated.
293
	 * to be updated.
294
	 */
294
	 */
295
	protected void updateActionsAndButtons(IStructuredSelection structuredSelection)
295
	protected void updateActionsAndButtons(IStructuredSelection structuredSelection)
296
	{
296
	{
297
		/* purposely left blank */
297
		/* purposely left blank */
298
	}
298
	}
299
	
299
	
300
	
300
	
301
	/**
301
	/**
302
	 * Need to overwrite this method since there are no buttons whose label
302
	 * Need to overwrite this method since there are no buttons whose label
303
	 * need to be set.
303
	 * need to be set.
304
	 */
304
	 */
305
	protected void adjustButtonLabels(String addLabel)
305
	protected void adjustButtonLabels(String addLabel)
306
	{
306
	{
307
		/* An empty set of button labels */
307
		/* An empty set of button labels */
308
		setButtonLabels (new String[]{});
308
		setButtonLabels (new String[]{});
309
	}
309
	}
310
	
310
	
311
311
312
	
312
	
313
	protected void adjustClient(Composite parent)
313
	protected void adjustClient(Composite parent)
314
	{
314
	{
315
		getTreeViewer().setContentProvider(createContentProvider());
315
		getTreeViewer().setContentProvider(createContentProvider());
316
		getTreeViewer().setLabelProvider(createLabelProvider());
316
		getTreeViewer().setLabelProvider(createLabelProvider());
317
		getTreeViewer().setAutoExpandLevel(0);
317
		getTreeViewer().setAutoExpandLevel(0);
318
	}
318
	}
319
	/**
319
	/**
320
	 * The content provider for the custom test case tree.
320
	 * The content provider for the custom test case tree.
321
	 * This content provider will be used to add commands under the test cases
321
	 * This content provider will be used to add commands under the test cases
322
	 * 
322
	 * 
323
	 * @author Ali Mehregani
323
	 * @author Ali Mehregani
324
	 */
324
	 */
325
	private class TestCaseTreeContentProvider extends EObjectTreeContentProvider
325
	private class TestCaseTreeContentProvider extends EObjectTreeContentProvider
326
	{
326
	{
327
327
328
		public TestCaseTreeContentProvider(IEditorExtension editorPart, EStructuralFeature eStructuralFeature)
328
		public TestCaseTreeContentProvider(IEditorExtension editorPart, EStructuralFeature eStructuralFeature)
329
		{
329
		{
330
			super(editorPart, eStructuralFeature);
330
			super(editorPart, eStructuralFeature);
331
		}		
331
		}		
332
		
332
		
333
		/**
333
		/**
334
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
334
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
335
		 */
335
		 */
336
		public Object[] getChildren(Object parentElement)
336
		public Object[] getChildren(Object parentElement)
337
		{
337
		{
338
			ArrayList children = new ArrayList();
338
			ArrayList children = new ArrayList();
339
			
339
			
340
			/* A test case */
340
			/* A test case */
341
			if (parentElement instanceof ITestCase)
341
			if (parentElement instanceof ITestCase)
342
			{
342
			{
343
				ITestCase testCase = (ITestCase)parentElement;
343
				ITestCase testCase = (ITestCase)parentElement;
344
				String testCaseId = testCase.getId();
344
				String testCaseId = testCase.getId();
345
				
345
				
346
				/* Is it in cache? */
346
				/* Is it in cache? */
347
				ArrayList testCaseCommands = (ArrayList) cachedParsedMacro.get(testCaseId);
347
				ArrayList testCaseCommands = (ArrayList) cachedParsedMacro.get(testCaseId);
348
				
348
				
349
				/* Didn't find it in the cache */
349
				/* Didn't find it in the cache */
350
				if (testCaseCommands == null)
350
				if (testCaseCommands == null)
351
					testCaseCommands = parseMacro(testCase);					
351
					testCaseCommands = parseMacro(testCase);					
352
								
352
								
353
				children.addAll(testCaseCommands);				
353
				children.addAll(testCaseCommands);				
354
			}
354
			}
355
			/* A macro UI instruction */
355
			/* A macro UI instruction */
356
			else if (parentElement instanceof MacroUIInstruction)
356
			else if (parentElement instanceof MacroUIInstruction)
357
			{
357
			{
358
				children.addAll(((MacroUIInstruction)parentElement).getSubInstructions());
358
				children.addAll(((MacroUIInstruction)parentElement).getSubInstructions());
359
			}
359
			}
360
			
360
			
361
			Object[] childrenArray = new Object[children.size()];
361
			Object[] childrenArray = new Object[children.size()];
362
			children.toArray(childrenArray);
362
			children.toArray(childrenArray);
363
			return childrenArray;
363
			return childrenArray;
364
		}
364
		}
365
		
365
		
366
		
366
		
367
		public boolean hasChildren(Object element)
367
		public boolean hasChildren(Object element)
368
		{
368
		{
369
			/* A test case */
369
			/* A test case */
370
			if (element instanceof ITestCase)
370
			if (element instanceof ITestCase)
371
			{
371
			{
372
				return true;
372
				return true;
373
			}
373
			}
374
			
374
			
375
			/* A macro UI instruction */
375
			/* A macro UI instruction */
376
			else if (element instanceof MacroUIInstruction)
376
			else if (element instanceof MacroUIInstruction)
377
			{
377
			{
378
				/* Does it have sub instrucitons */
378
				/* Does it have sub instrucitons */
379
				ArrayList subInstructions = ((MacroUIInstruction)element).getSubInstructions();
379
				ArrayList subInstructions = ((MacroUIInstruction)element).getSubInstructions();
380
				return subInstructions != null && subInstructions.size() > 0;
380
				return subInstructions != null && subInstructions.size() > 0;
381
			}
381
			}
382
			
382
			
383
			return false;
383
			return false;
384
		}
384
		}
385
	}
385
	}
386
	
386
	
387
	
387
	
388
	/**
388
	/**
389
	 * The label provider for the custom test case tree.
389
	 * The label provider for the custom test case tree.
390
	 * This label provider will be used to add the required images and labels of each
390
	 * This label provider will be used to add the required images and labels of each
391
	 * tree item.
391
	 * tree item.
392
	 * 
392
	 * 
393
	 * @author Ali Mehregani
393
	 * @author Ali Mehregani
394
	 */
394
	 */
395
	private static class TestCaseTreeLabelProvider extends WorkbenchAdapterLabelProvider
395
	private static class TestCaseTreeLabelProvider extends WorkbenchAdapterLabelProvider
396
	{
396
	{
397
397
398
		public TestCaseTreeLabelProvider(Class cl) throws IllegalArgumentException
398
		public TestCaseTreeLabelProvider(Class cl) throws IllegalArgumentException
399
		{
399
		{
400
			super(cl);
400
			super(cl);
401
		}
401
		}
402
		
402
		
403
	    public String getText(Object element)
403
	    public String getText(Object element)
404
	    {
404
	    {
405
	    	/* A test case */
405
	    	/* A test case */
406
	    	if (element instanceof ITestCase)
406
	    	if (element instanceof ITestCase)
407
	    	{
407
	    	{
408
	    		String testCaseName = ((ITestCase)element).getName();
408
	    		String testCaseName = ((ITestCase)element).getName();
409
	    		return testCaseName == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_TEST_CASE : ((ITestCase)element).getName();
409
	    		return testCaseName == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_TEST_CASE : ((ITestCase)element).getName();
410
	    	}
410
	    	}
411
	    	
411
	    	
412
	    	/* A macro instruction */
412
	    	/* A macro instruction */
413
	    	else if (element instanceof MacroUIInstruction)
413
	    	else if (element instanceof MacroUIInstruction)
414
	    	{	    		
414
	    	{	    		
415
	    		String instructionText = ((MacroUIInstruction)element).getText();
415
	    		String instructionText = ((MacroUIInstruction)element).getText();
416
	    		return instructionText == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_INSTRUCTION : instructionText;
416
	    		return instructionText == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_INSTRUCTION : instructionText;
417
	    	}
417
	    	}
418
	    	
418
	    	
419
	    	/* An error message */
419
	    	/* An error message */
420
	    	else if (element instanceof MessageUIElement)
420
	    	else if (element instanceof MessageUIElement)
421
	    	{
421
	    	{
422
	    		String message = ((MessageUIElement)element).getText();	    		
422
	    		String message = ((MessageUIElement)element).getText();	    		
423
	    		return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE : message; 
423
	    		return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE : message; 
424
	    	}
424
	    	}
425
	    	
425
	    	
426
	    	return "";	    	
426
	    	return "";	    	
427
	    }
427
	    }
428
		
428
		
429
	    public Image getImage(Object element)
429
	    public Image getImage(Object element)
430
	    {
430
	    {
431
	    	/* A test case */
431
	    	/* A test case */
432
	    	if (element instanceof ITestCase)
432
	    	if (element instanceof ITestCase)
433
	    		return AutoGUIImages.getInstance().getImage("e", AutoGUIImages.IMG_NEW_AUTO_GUI);
433
	    		return AutoGUIImages.getInstance().getImage("e", AutoGUIImages.IMG_NEW_AUTO_GUI);
434
	    	
434
	    	
435
	    	/* A macro instruction */
435
	    	/* A macro instruction */
436
	    	else if (element instanceof MacroUIInstruction)
436
	    	else if (element instanceof MacroUIInstruction)
437
	    	{
437
	    	{
438
	    		MacroUIInstruction uiInstruction = (MacroUIInstruction)element;
438
	    		MacroUIInstruction uiInstruction = (MacroUIInstruction)element;
439
	    		ArrayList subInstructions = uiInstruction.getSubInstructions();
439
	    		ArrayList subInstructions = uiInstruction.getSubInstructions();
440
	    		
440
	    		
441
	    		/* A shell */
441
	    		/* A shell */
442
	    		if (subInstructions != null && subInstructions.size() > 0)
442
	    		if (subInstructions != null && subInstructions.size() > 0)
443
	    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.SHELL);
443
	    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.SHELL);
444
	    		
444
	    		
445
	    		/* A command */
445
	    		/* A command */
446
	    		else 
446
	    		else 
447
	    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.COMMAND);
447
	    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.COMMAND);
448
	    	}
448
	    	}
449
	    	
449
	    	
450
	    	/* An error message */
450
	    	/* An error message */
451
	    	else if (element instanceof MessageUIElement)
451
	    	else if (element instanceof MessageUIElement)
452
	    	{
452
	    	{
453
	    		((MessageUIElement)element).getIcon();
453
	    		((MessageUIElement)element).getIcon();
454
	    	}
454
	    	}
455
	    	
455
	    	
456
	    	return null;
456
	    	return null;
457
	    }
457
	    }
458
	}
458
	}
459
	
459
	
460
	/**
460
	/**
461
	 * The UI representation of a macro instruction
461
	 * The UI representation of a macro instruction
462
	 * 
462
	 * 
463
	 * @author Ali Mehregani
463
	 * @author Ali Mehregani
464
	 */
464
	 */
465
	protected static class MacroUIInstruction
465
	protected static class MacroUIInstruction
466
	{
466
	{
467
		/** If a macro UI instruction is a shell, then it will have sub instructions */ 
467
		/** If a macro UI instruction is a shell, then it will have sub instructions */ 
468
		private ArrayList subInstructions;
468
		private ArrayList subInstructions;
469
		
469
		
470
		/** The text of the command */
470
		/** The text of the command */
471
		private String text;
471
		private String text;
472
		
472
		
473
		/** The line number.  This is expected to be of size 2 (indicating the start and
473
		/** The line number.  This is expected to be of size 2 (indicating the start and
474
		 * end line number for the command */
474
		 * end line number for the command */
475
		private Integer[] lineNumber;
475
		private Integer[] lineNumber;
476
				
476
				
477
		
477
		
478
		/**
478
		/**
479
		 * Constructor
479
		 * Constructor
480
		 * @param text The text of the UI element
480
		 * @param text The text of the UI element
481
		 * @param lineNumber The line number is epx
481
		 * @param lineNumber The line number is epx
482
		 */
482
		 */
483
		public MacroUIInstruction(String text, Integer[] lineNumber)
483
		public MacroUIInstruction(String text, Integer[] lineNumber)
484
		{
484
		{
485
			subInstructions = new ArrayList();
485
			subInstructions = new ArrayList();
486
			this.lineNumber = lineNumber;
486
			this.lineNumber = lineNumber;
487
			this.text = formatText(text);
487
			this.text = formatText(text);
488
		}
488
		}
489
489
490
490
491
		/**
491
		/**
492
		 * @return the lineNumber
492
		 * @return the lineNumber
493
		 */
493
		 */
494
		public Integer[] getLineNumber()
494
		public Integer[] getLineNumber()
495
		{
495
		{
496
			return lineNumber;
496
			return lineNumber;
497
		}
497
		}
498
498
499
499
500
		/**
500
		/**
501
		 * @param lineNumber the lineNumber to set
501
		 * @param lineNumber the lineNumber to set
502
		 */
502
		 */
503
		public void setLineNumber(Integer[] lineNumber)
503
		public void setLineNumber(Integer[] lineNumber)
504
		{
504
		{
505
			this.lineNumber = lineNumber;
505
			this.lineNumber = lineNumber;
506
		}
506
		}
507
507
508
508
509
		/**
509
		/**
510
		 * @return the subInstructions
510
		 * @return the subInstructions
511
		 */
511
		 */
512
		public ArrayList getSubInstructions()
512
		public ArrayList getSubInstructions()
513
		{
513
		{
514
			return subInstructions;
514
			return subInstructions;
515
		}
515
		}
516
516
517
517
518
		/**
518
		/**
519
		 * @param subInstructions the subInstructions to set
519
		 * @param subInstructions the subInstructions to set
520
		 */
520
		 */
521
		public void setSubInstructions(ArrayList subInstructions)
521
		public void setSubInstructions(ArrayList subInstructions)
522
		{
522
		{
523
			this.subInstructions = subInstructions;
523
			this.subInstructions = subInstructions;
524
		}
524
		}
525
525
526
		
526
		
527
		/**
527
		/**
528
		 * Returns a formatted version of the text
528
		 * Returns a formatted version of the text
529
		 * 
529
		 * 
530
		 * @param text The text to be formatted
530
		 * @param text The text to be formatted
531
		 * @return The formatted text.
531
		 * @return The formatted text.
532
		 */
532
		 */
533
		protected String formatText (String text)
533
		protected String formatText (String text)
534
		{
534
		{
535
			int start = lineNumber[0].intValue();
535
			int start = lineNumber[0].intValue();
536
			int end = lineNumber[1].intValue();
536
			int end = lineNumber[1].intValue();
537
			String lineNumber;
537
			String lineNumber;
538
			
538
			
539
			if (start == end)
539
			if (start == end)
540
				lineNumber = String.valueOf(start);
540
				lineNumber = String.valueOf(start);
541
			else
541
			else
542
				lineNumber = start + "-" + end;
542
				lineNumber = start + "-" + end;
543
			
543
			
544
			return text + " (" + AutoGUIMessages.TST_SUITE_AUTO_MACRO_LINE_NUM + " " + lineNumber + ")";
544
			return text + " (" + AutoGUIMessages.TST_SUITE_AUTO_MACRO_LINE_NUM + " " + lineNumber + ")";
545
		}
545
		}
546
546
547
		/**
547
		/**
548
		 * @return the text
548
		 * @return the text
549
		 */
549
		 */
550
		public String getText()
550
		public String getText()
551
		{
551
		{
552
			return text;
552
			return text;
553
		}
553
		}
554
554
555
555
556
		/**
556
		/**
557
		 * @param text the text to set
557
		 * @param text the text to set
558
		 */
558
		 */
559
		public void setText(String text)
559
		public void setText(String text)
560
		{
560
		{
561
			this.text = text;
561
			this.text = text;
562
		}
562
		}
563
		
563
		
564
		
564
		
565
	}
565
	}
566
	
566
	
567
	
567
	
568
	/**
568
	/**
569
	 * Represents an element that only displays an error/warning
569
	 * Represents an element that only displays an error/warning
570
	 * message.
570
	 * message.
571
	 * 
571
	 * 
572
	 * @author Ali Mehregani
572
	 * @author Ali Mehregani
573
	 *
573
	 *
574
	 */
574
	 */
575
	protected static class MessageUIElement
575
	protected static class MessageUIElement
576
	{
576
	{
577
		/** The severity of the message */
577
		/** The severity of the message */
578
		private int severity;
578
		private int severity;
579
		
579
		
580
		/** The actual message */
580
		/** The actual message */
581
		private String text;
581
		private String text;
582
		
582
		
583
		public MessageUIElement(int severity, String text)
583
		public MessageUIElement(int severity, String text)
584
		{
584
		{
585
			this.severity = severity;
585
			this.severity = severity;
586
			this.text = text;
586
			this.text = text;
587
		}
587
		}
588
588
589
		/**
589
		/**
590
		 * @return the severity
590
		 * @return the severity
591
		 */
591
		 */
592
		public int getSeverity()
592
		public int getSeverity()
593
		{
593
		{
594
			return severity;
594
			return severity;
595
		}
595
		}
596
596
597
		/**
597
		/**
598
		 * @param severity the severity to set
598
		 * @param severity the severity to set
599
		 */
599
		 */
600
		public void setSeverity(int severity)
600
		public void setSeverity(int severity)
601
		{
601
		{
602
			this.severity = severity;
602
			this.severity = severity;
603
		}
603
		}
604
604
605
		/**
605
		/**
606
		 * @return the text
606
		 * @return the text
607
		 */
607
		 */
608
		public String getText()
608
		public String getText()
609
		{
609
		{
610
			return text;
610
			return text;
611
		}
611
		}
612
612
613
		/**
613
		/**
614
		 * @param text the text to set
614
		 * @param text the text to set
615
		 */
615
		 */
616
		public void setText(String text)
616
		public void setText(String text)
617
		{
617
		{
618
			this.text = text;
618
			this.text = text;
619
		}		
619
		}		
620
		
620
		
621
		
621
		
622
		public Image getIcon()
622
		public Image getIcon()
623
		{    		    		
623
		{    		    		
624
    		/* An error */
624
    		/* An error */
625
    		if (severity == IStatus.ERROR)
625
    		if (severity == IStatus.ERROR)
626
    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.ERROR);
626
    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.ERROR);
627
    		/* A warning */
627
    		/* A warning */
628
    		else if (severity == IStatus.WARNING)
628
    		else if (severity == IStatus.WARNING)
629
    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.WARNING);
629
    			return AutoGUIImages.getInstance().getImage(AutoGUIImages.WARNING);
630
    		
630
    		
631
    		return null;
631
    		return null;
632
		}
632
		}
633
	}
633
	}
634
634
635
635
636
	public void refresh()
636
	public void refresh()
637
	{
637
	{
638
		cachedParsedMacro.clear();
638
		cachedParsedMacro.clear();
639
		cachedLineOffsetIndicator.clear();
639
		cachedLineOffsetIndicator.clear();
640
		selectedTestCase = null;
640
		selectedTestCase = null;
641
		getTreeViewer().setSelection(null);
641
		getTreeViewer().setSelection(null);
642
		getTreeViewer().refresh();
642
		getTreeViewer().refresh();
643
	}
643
	}
644
	
644
	
645
	public int getTreeStryle()
645
	public int getTreeStryle()
646
	{
646
	{
647
		return super.getTreeStryle() | SWT.BORDER;
647
		return super.getTreeStryle() | SWT.BORDER;
648
	}
648
	}
649
}
649
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIObjectMineTreeStructure.java (-537 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.editor;
12
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Iterator;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.emf.ecore.EStructuralFeature;
20
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
21
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
22
import org.eclipse.hyades.test.common.util.XMLUtil;
23
import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter;
24
import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider;
25
import org.eclipse.hyades.ui.editor.IEditorExtension;
26
import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider;
27
import org.eclipse.jface.action.Action;
28
import org.eclipse.jface.action.IMenuManager;
29
import org.eclipse.jface.dialogs.IDialogConstants;
30
import org.eclipse.jface.resource.ImageDescriptor;
31
import org.eclipse.jface.viewers.IContentProvider;
32
import org.eclipse.jface.viewers.ILabelProvider;
33
import org.eclipse.jface.viewers.IStructuredSelection;
34
import org.eclipse.jface.viewers.Viewer;
35
import org.eclipse.osgi.util.NLS;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.graphics.Image;
38
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
39
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
40
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
41
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
42
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
43
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
44
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
45
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestSuiteDialog;
46
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MessageUIElement;
47
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
48
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager;
49
50
/**
51
 * Represents the object mine tree that is displayed in the test
52
 * case page of the editor.
53
 * 
54
 * @author      Ali Mehregani
55
 * @author      Paul E. Slauenwhite
56
 * @version     March 7, 2008
57
 * @since       July 10, 2006
58
 */
59
public class AutoGUIObjectMineTreeStructure extends AutoGUIAbstractTreeStructure
60
{
61
	/** Represents the root element in the object mine tree */
62
	private static final RootUIObjectMineTreeNode ROOT_ELEMENT = new RootUIObjectMineTreeNode();
63
64
	/** The test case form */
65
	private AutoGUITestCasesForm testCaseForm;
66
67
	/** The content provider */
68
	private ObjectMineTreeContentProvider contentProvider;
69
	
70
	/** The label provider */
71
	private ObjectMineLabelProvider labelProvider;
72
	
73
	/** The line number and offset relation.  The index of the list represents the line
74
	 * number and the value is an object of type Integer[0] indicating the start
75
	 * and end offset */
76
	private List lineOffsetRelation;
77
	
78
	/** The include object mine menu item */
79
	private IncludeObjectMineAction includeObjectMineAction;
80
	
81
	/** Change output menu item */
82
	private ChangeOutputAction changeOutputAction;
83
			
84
	/** Keeps track of the test suite used as input */
85
	private ITestSuite testSuiteInput;
86
	
87
	/** Stores any error that occurred while loading the object mine */
88
	private Object[] error;
89
	
90
	public AutoGUIObjectMineTreeStructure(AutoGUITestCasesForm testCaseForm, IEditorExtension editorPart)
91
	{
92
		super(editorPart, null);
93
		this.testCaseForm = testCaseForm;
94
		lineOffsetRelation = new ArrayList();
95
		includeObjectMineAction = new IncludeObjectMineAction();
96
		changeOutputAction = new ChangeOutputAction();
97
	}
98
	
99
	/**
100
	 * Overwrite this method so that a custom content provider can be 
101
	 * registered with the tree
102
	 */
103
	protected IContentProvider createContentProvider()
104
	{
105
		if (contentProvider == null)
106
			contentProvider = new ObjectMineTreeContentProvider(editorPart, getEStructuralFeature());
107
		return contentProvider;
108
	}
109
		
110
	
111
	/**
112
	 * Overwrite this method so that a custom label provider can be 
113
	 * registered with the tree
114
	 * 
115
	 * @return The label provider for the object mine tree
116
	 */
117
	protected ILabelProvider createLabelProvider()
118
	{
119
		if (labelProvider == null)
120
			labelProvider = new ObjectMineLabelProvider(TestWorkbenchAdapter.class);
121
		return labelProvider;
122
	}
123
124
	
125
	
126
	/**
127
	 * Overwrite this method so that custom buttons can be added beside the 
128
	 * object mine tree.
129
	 */
130
	protected void adjustButtonLabels(String addLabel)
131
	{
132
		setButtonLabels (new String[0]);
133
	}
134
	
135
	
136
	/**
137
	 * Need to overwrite this method since there are no buttons whose status need
138
	 * to be updated.
139
	 */
140
	protected void updateActionsAndButtons(IStructuredSelection structuredSelection)
141
	{
142
		/* purposely left blank */
143
	}
144
	
145
	
146
	/**
147
	 * Refreshes the content of this tree by forcing the test suite to reload its
148
	 * object mine.
149
	 */
150
	public void refresh()
151
	{
152
		ObjectMineManager.getInstance().clearCache();
153
		loadObjectMine(testSuiteInput, false);
154
		getTreeViewer().refresh();
155
	}
156
	
157
	
158
	public List getLineOffsetRelation()
159
	{
160
		return lineOffsetRelation;
161
	}
162
	
163
	
164
	/**
165
	 * Needs to be overwritten to modify the default tree style 
166
	 */
167
	public int getTreeStryle()
168
	{
169
		return super.getTreeStryle() | SWT.BORDER;
170
	}
171
	
172
	
173
	private Object[] createErrorItem(String prefix, Exception e)
174
	{
175
		Throwable cause = AutoGUIUtil.findCause(e);
176
		prefix += prefix == null ? "": ": ";
177
		prefix += (cause.getMessage() == cause.getClass().getName() ? "" : " " + cause.getMessage());
178
		prefix += ": " + e.getStackTrace()[0].getClassName() + ":" + e.getStackTrace()[0].getLineNumber(); 
179
		return new Object[]{new MessageUIElement(IStatus.ERROR, prefix)};
180
	}
181
	
182
	
183
	/**
184
	 * Overwrite this method so that custom menu items can be added to the entries that are
185
	 * displayed in the object mine tree.
186
	 * 
187
	 * @param menuManager The menu manager
188
	 */
189
	protected void fillContextMenu(IMenuManager menuManager)
190
	{
191
		IStructuredSelection selection = getStructuredSelection();
192
		if (!selection.isEmpty() && selection.size() == 1 && selection.getFirstElement() instanceof RootUIObjectMineTreeNode)
193
		{
194
			menuManager.add(includeObjectMineAction);
195
			menuManager.add(changeOutputAction);
196
		}
197
	}
198
	
199
	
200
	private IObjectMine loadObjectMine(ITestSuite testSuite, boolean showError)
201
	{
202
		IObjectMine input = null;
203
		if (testSuite == null)
204
		{
205
			testSuiteInput = null;				
206
			return null;
207
		}
208
		
209
		try
210
		{				
211
			testSuiteInput =(ITestSuite)testSuite;
212
			input = ObjectMineManager.getInstance().loadObjectMine(testSuiteInput);
213
			String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteInput, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
214
			lineOffsetRelation = AutoGUIObjectMineTreeStructure.this.findLineOffsetIndicator(objectMineXML);
215
			error = null;
216
		}
217
		catch (Exception e)
218
		{	
219
			if (showError)
220
			{
221
				AutoGUIUtil.openErrorWithDetail(
222
						AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
223
						AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE + ": " + testSuite.getName(), 
224
						e);
225
			}
226
			else
227
			{
228
				error = createErrorItem(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, e);
229
			}
230
			
231
			input = null;
232
		}
233
		
234
		return input;
235
	}
236
	
237
	
238
	/**
239
	 * The content provider for the object mine tree.
240
	 * 
241
	 * @author Ali Mehregani
242
	 */
243
	private class ObjectMineTreeContentProvider extends EObjectTreeContentProvider
244
	{				
245
		public ObjectMineTreeContentProvider(IEditorExtension editorPart, EStructuralFeature eStructuralFeature)
246
		{
247
			super(editorPart, eStructuralFeature);
248
		}		
249
250
		public Object[] getElements(Object inputElement)
251
		{			
252
			return new Object[]{ROOT_ELEMENT};
253
		}
254
255
		
256
		/**
257
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
258
		 */
259
		public Object[] getChildren(Object parentElement)
260
		{	
261
			IObjectMine input = loadObjectMine(testSuiteInput, false);
262
			if (input == null)
263
			{	
264
				if (parentElement == ROOT_ELEMENT && error != null)
265
					return error;		
266
			}
267
			
268
			/* If the test suite doesn't have an object mine then return an empty list */
269
			String objectMineXML = null;
270
			if (testSuiteInput == null || (objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteInput, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE)) == null || objectMineXML.length() <= 0)
271
				return null;
272
273
274
			if (parentElement == ROOT_ELEMENT)
275
			{
276
				return input.getChildren();
277
			}
278
			else if (parentElement instanceof IUIObject)
279
			{
280
				return ((IUIObject)parentElement).getChildren();
281
			}
282
						
283
			return null;
284
		}
285
	
286
287
		public boolean hasChildren(Object parentElement)
288
		{
289
			IObjectMine input = loadObjectMine(testSuiteInput, false);
290
			if (parentElement == ROOT_ELEMENT)
291
			{
292
				return input == null ? error != null : input.getChildren().length > 0;
293
			}
294
			else if (parentElement instanceof IUIObject)
295
			{
296
				return ((IUIObject)parentElement).childCount() > 0;
297
			}
298
			
299
			return false;
300
		}
301
		
302
		/**
303
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
304
		 */
305
		public Object getParent(Object element)
306
		{
307
			if (element instanceof IUIObject)
308
			{
309
				IUIObject parent = ((IUIObject)element).getParent(); 
310
				return parent == null ? (Object)ROOT_ELEMENT : parent;
311
			}
312
			return null;
313
		}
314
		
315
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
316
		{
317
			if (!(newInput instanceof ITestSuite))
318
				return;
319
			
320
			loadObjectMine((ITestSuite)newInput, false);
321
322
		}
323
	}
324
	
325
	
326
	private class ObjectMineLabelProvider extends WorkbenchAdapterLabelProvider
327
	{
328
329
		public ObjectMineLabelProvider(Class cl) throws IllegalArgumentException
330
		{
331
			super(cl);
332
		}
333
		
334
	    public String getText(Object element)
335
	    {
336
	    	if (element == ROOT_ELEMENT)
337
	    	{
338
	    		return AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_MINE;
339
	    	}
340
	    	else if (element instanceof IUIObject)
341
	    	{
342
	    		String descriptiveField = ((IUIObject)element).getDescriptive();
343
	    		return descriptiveField == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_OBJECT : XMLUtil.removeXMLSymbols(descriptiveField);
344
	    	}
345
	    	else if (element instanceof MessageUIElement)
346
	    	{
347
	    		String message = ((MessageUIElement)element).getText();	    		
348
	    		return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE : message;
349
	    	}
350
	    	
351
	    	return MacroConstants.EMPTY_STRING;	    	
352
	    }
353
		
354
	    public Image getImage(Object element)
355
	    {	    	
356
	    	if (element == ROOT_ELEMENT)
357
	    	{
358
	    		return AutoGUIImages.getInstance().getImage(AutoGUIImages.OBJECT_MINE);
359
	    	}
360
	    	else if (element instanceof IUIObject)
361
	    	{
362
	    		IUIObject parent  = ((IUIObject)element).getParent();
363
	    		return parent == null ? AutoGUIImages.getInstance().getImage(AutoGUIImages.SHELL) : AutoGUIImages.getInstance().getImage(AutoGUIImages.WIDGET);
364
	    	}
365
	    	else if (element instanceof MessageUIElement)
366
	    	{
367
	    		return ((MessageUIElement)element).getIcon();
368
	    	}
369
	    	
370
	    	return null;
371
	    }
372
	}
373
	
374
	
375
	/**
376
	 * A dummy class that represents the root element in the object mine
377
	 * tree.
378
	 */
379
	private static class RootUIObjectMineTreeNode
380
	{	
381
	}
382
	
383
	
384
	/**
385
	 * The include object mine action.  The purpose of this action is to allow
386
	 * the user to include object mines under the test suite's object mine
387
	 * 
388
	 * @author Ali Mehregani
389
	 */
390
	private class IncludeObjectMineAction extends Action
391
	{
392
		/**
393
		 * Perform the action.
394
		 * 
395
		 */
396
		public void run() 
397
		{			
398
			/* Display the test suite list dialog */
399
			AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog(
400
					GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
401
					testSuiteInput, 
402
					AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, 
403
					false);
404
			
405
			if(autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID)
406
				return;
407
			
408
			
409
			/* Get the selected test suites and include them as part of this test suite's object mine */
410
			Collection tests = autoGUITestSuiteDialog.getTests();
411
			IObjectMine input = loadObjectMine(testSuiteInput, true);
412
			boolean markdirty = false;
413
			for (Iterator testIterator = tests.iterator(); testIterator.hasNext();)
414
			{
415
				Object currentTestSuite = testIterator.next();
416
				if (!(currentTestSuite instanceof ITestSuite))
417
					continue;
418
							
419
				ITestSuite testSuite = (ITestSuite)currentTestSuite;
420
				try
421
				{
422
					IObjectMine objectMine = ObjectMineManager.getInstance().loadObjectMine(testSuite);
423
					if (objectMine != null && !input.getIncludes().contains(objectMine))
424
					{
425
						markdirty = true;
426
						input.addInclude(objectMine);
427
					}						
428
				} 
429
				catch (Exception e)
430
				{
431
					/* Display an error */
432
					AutoGUIUtil.openErrorWithDetail(
433
							AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
434
							NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_DIALOG_TST_INCL, testSuite.getName()), 
435
							e);
436
				} 
437
			}
438
			
439
			if (markdirty)
440
			{
441
				testCaseForm.updateTestProperty(null, input.serializeToString(), true);
442
				getTreeViewer().setSelection(getTreeViewer().getSelection());
443
			}
444
		}
445
		
446
		
447
		public boolean isEnabled() 
448
		{
449
			return testSuiteInput != null;
450
		}
451
		
452
		public String getText() 
453
		{
454
			return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_INCL;
455
		}
456
		
457
		public ImageDescriptor getImageDescriptor() 
458
		{
459
			return AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.INCLUDE);
460
		}
461
	}
462
	
463
	
464
	/**
465
	 * This action changes the output of the object mine to another test suite.
466
	 * 
467
	 * @author Ali Mehregani
468
	 */
469
	private class ChangeOutputAction extends Action
470
	{
471
		/**
472
		 * Perform the action.
473
		 */
474
		public void run() 
475
		{			
476
			/* Display the test suite list dialog */
477
			AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog(
478
					GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
479
					testSuiteInput, 
480
					AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, 
481
					true);
482
			
483
			if(autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID)
484
				return;
485
			
486
			
487
			/* Get the selected test suites and include them as part of this test suite's object mine */
488
			Collection tests = autoGUITestSuiteDialog.getTests();			
489
			if (tests == null)
490
				return;
491
			
492
			Object[] selectedTestContainer = tests.toArray();
493
			if (selectedTestContainer.length != 1 || !(selectedTestContainer[0] instanceof ITestSuite))
494
				return;
495
			
496
			IObjectMine input = loadObjectMine(testSuiteInput, true);
497
			IObjectMine oldOutputObjectMine = input.getOutputSource();
498
			ITestSuite oldOutput = oldOutputObjectMine == null ? null : oldOutputObjectMine.getOwner();
499
			ITestSuite newOutput = (ITestSuite)selectedTestContainer[0];			
500
			if (oldOutput == null || (!oldOutput.getId().equals(newOutput.getId())))
501
			{
502
				IObjectMine objectMine = null;
503
				try
504
				{
505
					objectMine = ObjectMineManager.getInstance().loadObjectMine(newOutput);
506
					input.setOutputSource(objectMine);
507
					testCaseForm.updateTestProperty(null, input.serializeToString(), true);
508
					getTreeViewer().setSelection(getTreeViewer().getSelection());
509
				} 
510
				catch (Exception e)
511
				{
512
					input.setOutputSource(null);
513
					AutoGUIUtil.openErrorWithDetail(
514
							AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
515
							NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT, newOutput.getName()), 
516
							e);
517
				} 
518
			}						
519
		}
520
		
521
		
522
		public boolean isEnabled() 
523
		{
524
			return testSuiteInput != null;
525
		}
526
		
527
		public String getText() 
528
		{
529
			return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_OUPUT;
530
		}
531
		
532
		public ImageDescriptor getImageDescriptor() 
533
		{
534
			return AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.OUTPUT);
535
		}
536
	}
537
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIRecordAction.java (-520 / +516 lines)
Lines 1-520 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUIRecordAction.java,v 1.9 2008/03/05 18:27:00 paules Exp $
7
 * $Id: AutoGUIRecordAction.java,v 1.9 2008/03/05 18:27:00 paules Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.actions;
12
package org.eclipse.tptp.test.auto.gui.internal.actions;
13
13
14
import java.io.PrintWriter;
14
import java.io.PrintWriter;
15
import java.io.StringWriter;
15
import java.io.StringWriter;
16
16
17
import org.eclipse.core.runtime.NullProgressMonitor;
17
import org.eclipse.core.runtime.NullProgressMonitor;
18
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
18
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
20
import org.eclipse.hyades.test.tools.core.common.util.TestCommonUtil;
20
import org.eclipse.hyades.test.tools.core.common.util.TestCommonUtil;
21
import org.eclipse.hyades.test.tools.ui.common.internal.editor.action.AddTestCase;
21
import org.eclipse.hyades.test.tools.ui.common.internal.editor.action.AddTestCase;
22
import org.eclipse.hyades.test.tools.ui.common.internal.util.IITestSuiteProvider;
22
import org.eclipse.hyades.test.tools.ui.common.internal.util.IITestSuiteProvider;
23
import org.eclipse.jface.dialogs.MessageDialog;
23
import org.eclipse.jface.dialogs.MessageDialog;
24
import org.eclipse.osgi.util.NLS;
24
import org.eclipse.osgi.util.NLS;
25
import org.eclipse.swt.widgets.Shell;
25
import org.eclipse.swt.widgets.Shell;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
27
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
27
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
28
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
28
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
29
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
29
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
30
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
30
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
31
import org.eclipse.tptp.test.auto.gui.internal.codegen.AutoGUIGenerator;
31
import org.eclipse.tptp.test.auto.gui.internal.codegen.AutoGUIGenerator;
32
import org.eclipse.tptp.test.auto.gui.internal.codegen.CodeGeneratorHelper;
32
import org.eclipse.tptp.test.auto.gui.internal.codegen.CodeGeneratorHelper;
33
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
33
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
34
import org.eclipse.tptp.test.auto.gui.internal.core.VerificationMetaData;
34
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUIInputCollectorDialog;
35
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUIInputCollectorDialog;
35
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog;
36
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog;
36
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog.AutoGUIControllerListener;
37
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestControllerDialog.AutoGUIControllerListener;
37
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
38
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
38
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
39
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
39
import org.eclipse.tptp.test.auto.gui.internal.macro.Macro;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.Macro;
40
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
41
import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants;
42
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager;
42
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.GlobalStateListener;
43
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.GlobalStateListener;
43
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.VerificationHookListener;
44
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager.VerificationHookListener;
44
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
45
import org.eclipse.ui.IEditorPart;
45
import org.eclipse.ui.IWorkbench;
46
import org.eclipse.ui.IViewPart;
46
import org.eclipse.ui.IWorkbenchWindow;
47
import org.eclipse.ui.IWorkbench;
47
import org.eclipse.ui.WorkbenchException;
48
import org.eclipse.ui.IWorkbenchWindow;
48
49
import org.eclipse.ui.WorkbenchException;
49
/**
50
50
 * Handles the addition of auto gui test cases
51
/**
51
 * 
52
 * Handles the addition of auto gui test cases
52
 * 
53
 * 
53
 * @author      Ali Mehregani
54
 * 
54
 * @author      Paul E. Slauenwhite
55
 * @author      Ali Mehregani
55
 * @author      Alexander Nyssen
56
 * @author      Paul E. Slauenwhite
56
 * @version     March 5, 2008
57
 * @version     March 5, 2008
57
 * @since       March 17, 2006
58
 * @since       March 17, 2006
58
 */
59
 */
59
public class AutoGUIRecordAction extends AddTestCase implements AutoGUIControllerListener {
60
public class AutoGUIRecordAction extends AddTestCase implements AutoGUIControllerListener
60
61
{
61
	/* The test suite provider */
62
	
62
	private IITestSuiteProvider suiteProvider;
63
	/* The test suite provider */
63
64
	private IITestSuiteProvider suiteProvider;
64
	/* The perspective the user was in before adding a test case */
65
	
65
	private String perspectiveId;
66
	/* The perspective the user was in before adding a test case */
66
67
	private String perspectiveId;
67
	/* Control center dialog */
68
		
68
	private AutoGUITestControllerDialog controllerDialog;
69
	/* Control center dialog */
69
70
	private AutoGUITestControllerDialog controllerDialog;
70
	/* A global state listener */
71
	
71
	private CustomGlobalStateListener globalStateListener;
72
	/* A global state listener */
72
73
	private CustomGlobalStateListener globalStateListener;
73
	/* Start record dialog */
74
	
74
	private AutoGUIInputCollectorDialog inputCollectorDialog;
75
	/* Start record dialog */
75
76
	private AutoGUIInputCollectorDialog inputCollectorDialog;
76
	/* Stores the user input collected from the input dialog */
77
	
77
	private AutoGUIInputCollectorDialog.AutoGUIInputContainer userInput;
78
	/* Stores the user input collected from the input dialog */
78
79
	private AutoGUIInputCollectorDialog.AutoGUIInputContainer userInput;
79
	/* The test suite provider */
80
80
	private IITestSuiteProvider testSuiteProvider;
81
	/* The test suite provider */
81
82
	private IITestSuiteProvider testSuiteProvider;
82
	/**
83
		
83
	 * The constructor
84
	/**
84
	 * 
85
	 * The constructor
85
	 * @param testSuiteProvider
86
	 * 
86
	 *            The test suite provider used to get the test suite associated with this action
87
	 * @param testSuiteProvider The test suite provider used to get the test suite associated with this action
87
	 * @param baseName
88
	 * @param baseName The base name of the test case
88
	 *            The base name of the test case
89
	 */
89
	 */
90
	public AutoGUIRecordAction(IITestSuiteProvider testSuiteProvider, String baseName) 
90
	public AutoGUIRecordAction(IITestSuiteProvider testSuiteProvider, String baseName) {
91
	{
91
		super(testSuiteProvider,
92
		super(testSuiteProvider, GuiPlugin.getTestSuiteType(), baseName);		
92
			GuiPlugin.getTestSuiteType(),
93
		this.suiteProvider = testSuiteProvider;
93
			baseName);
94
		this.testSuiteProvider = testSuiteProvider;
94
		this.suiteProvider = testSuiteProvider;
95
		setToolTipText(AutoGUIMessages.TST_SUITE_AUTO_MACRO_RECORD);
95
		this.testSuiteProvider = testSuiteProvider;
96
		setImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("e", AutoGUIImages.RECORD));
96
		setToolTipText(AutoGUIMessages.TST_SUITE_AUTO_MACRO_RECORD);
97
		
97
		setImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("e",
98
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
98
			AutoGUIImages.RECORD));
99
		IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
99
100
		Shell activeShell = activeWorkbenchWindow.getShell();
100
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
101
		inputCollectorDialog = new AutoGUIInputCollectorDialog (activeShell);
101
		IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
102
	}
102
		Shell activeShell = activeWorkbenchWindow.getShell();
103
	
103
		inputCollectorDialog = new AutoGUIInputCollectorDialog(activeShell);
104
	
104
	}
105
	/**
105
106
	 * Invoked when this action is create
106
	/**
107
	 */
107
	 * Invoked when this action is create
108
	public void run()
108
	 */
109
	{ 
109
	public void run() {
110
		setActionPerformed(false);		
110
		setActionPerformed(false);
111
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
111
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
112
		IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
112
		IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
113
		Shell activeShell = activeWorkbenchWindow.getShell();
113
		Shell activeShell = activeWorkbenchWindow.getShell();
114
		userInput = inputCollectorDialog.openDialog();
114
		userInput = inputCollectorDialog.openDialog();
115
		
115
116
		
116
		/* We don't need to do anything if cancel is pressed */
117
		/* We don't need to do anything if cancel is pressed */
117
		if (userInput == null || !userInput.isOkPressed()) {
118
		if (userInput == null || !userInput.isOkPressed())
118
			setActionPerformed(true);
119
		{
119
			return;
120
			setActionPerformed (true);
120
		}
121
			return;
121
122
		}
122
		/*
123
		
123
		 * 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
124
		/* Otherwise, we'll need to add the test case.  Here are the phases:
124
		 * test case - Display the control center dialog box - Begin recording user actions
125
		 * 	- Switch to the perspective that corresponds to the starting point of the test case
125
		 */
126
		 *  - Display the control center dialog box
126
		userInput.setDescription(userInput.getDescription() == null
127
		 *  - Begin recording user actions */
127
			? ""
128
		userInput.setDescription(userInput.getDescription() == null ? "" : userInput.getDescription());
128
			: userInput.getDescription());
129
		
129
130
		/* Switch the perspecitve */			
130
		/* Switch the perspecitve */
131
		try
131
		try {
132
		{
132
			/* Store the perspective that we're in before switching it */
133
			/* Store the perspective that we're in before switching it */
133
			perspectiveId = activeWorkbenchWindow.getActivePage().getPerspective().getId();
134
			perspectiveId = activeWorkbenchWindow.getActivePage().getPerspective().getId();
134
			workbench.showPerspective(userInput.getStartingPoint(),
135
			workbench.showPerspective(userInput.getStartingPoint(), activeWorkbenchWindow);
135
				activeWorkbenchWindow);
136
		} catch (WorkbenchException e)
136
		}
137
		{
137
		catch (WorkbenchException e) {
138
			/* Something wrong happened while chaning the perspective.  Show an error */
138
			/* Something wrong happened while chaning the perspective. Show an error */
139
			String[] errorArgs = {userInput.getStartingPoint(), e.getMessage()};
139
			String[] errorArgs = {userInput.getStartingPoint(), e.getMessage()};
140
			AutoGUIUtil.openErrorWithDetail(
140
			AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE,
141
					AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE,
141
				NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH,
142
					NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, errorArgs),
142
					errorArgs),
143
					e);			
143
				e);
144
		}
144
		}
145
		
145
146
		/* Display the control center dialog box asynchronously */
146
		/* Display the control center dialog box asynchronously */
147
		controllerDialog = new AutoGUITestControllerDialog(activeShell);
147
		controllerDialog = new AutoGUITestControllerDialog(activeShell);
148
		controllerDialog.registerListener(this);
148
		controllerDialog.registerListener(this);
149
		controllerDialog.openDialog();		
149
		controllerDialog.openDialog();
150
		
150
151
		MacroManager macroManagerInstance = MacroManager.getInstance();
151
		MacroManager macroManagerInstance = MacroManager.getInstance();
152
		globalStateListener = new CustomGlobalStateListener(false);
152
		globalStateListener = new CustomGlobalStateListener(false);
153
		macroManagerInstance.registerGlobalStateListener(globalStateListener);
153
		macroManagerInstance.registerGlobalStateListener(globalStateListener);
154
		macroManagerInstance.setGlobalState(MacroManager.RECORDING_MODE);
154
		macroManagerInstance.setGlobalState(ModeConstants.RECORDING_MODE);
155
		controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
155
		controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
156
156
157
		startRecording(userInput.isObjectMineOn());
157
		startRecording(userInput.isObjectMineOn());
158
		setActionPerformed(true);
158
		setActionPerformed(true);
159
	}
159
	}
160
	
160
161
	
161
	private void startRecording(boolean isObjectMineOn) {
162
	private void startRecording(boolean isObjectMineOn)
162
		/* The control center is now open. Start recording the user's actions */
163
	{
163
		try {
164
		/* The control center is now open.  Start recording the user's actions */
164
			MacroManager.getInstance().startRecording(suiteProvider.getTestSuite(),
165
		try
165
				isObjectMineOn);
166
		{
166
		}
167
			MacroManager.getInstance().startRecording(suiteProvider.getTestSuite(), isObjectMineOn);
167
		catch (Exception e) {
168
		} 
168
			MacroManager.getInstance().setObjectMine(null);
169
		catch (Exception e)
169
			;
170
		{			
170
			if (controllerDialog != null) {
171
			MacroManager.getInstance().setObjectMine(null);;			
171
				controllerDialog.terminate();
172
			if (controllerDialog != null)
172
			}
173
			{
173
174
				controllerDialog.terminate();
174
			AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC_TITLE,
175
			}
175
				AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC,
176
			
176
				e);
177
			AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC_TITLE, AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, e);
177
		}
178
		} 
178
	}
179
	}
179
180
	
180
	protected void adjusTestCase(ITestCase testCase) {
181
	
181
	}
182
	protected void adjusTestCase(ITestCase testCase)
182
183
	{
183
	public void handleEvent(byte event, Object value) {
184
	}
184
		MacroManager macroManager = MacroManager.getInstance();
185
185
186
186
		switch (event) {
187
	public void handleEvent(byte event, Object value)
187
			/*
188
	{
188
			 * 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
189
		MacroManager macroManager = MacroManager.getInstance();
189
			 * what it was
190
		
190
			 */
191
		switch (event)
191
			case AutoGUITestControllerDialog.TERMINATE:
192
		{
192
				try {
193
			/* When user terminates, we have to take the macro and transfer it to the test suite.
193
					/* Stop the macro */
194
			 * We'll also need to reset the perspective back to what it was */
194
					Macro macro = macroManager.stopRecording(false);
195
			case AutoGUITestControllerDialog.TERMINATE:				
195
196
				try
196
					/* Something went wrong in the macro manager */
197
				{
197
					if (macro == null) {
198
					/* Stop the macro */
198
						/* Display error message and switch to the original perspective of the user */
199
					Macro macro = macroManager.stopRecording(false);
199
						IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
200
					
200
						MessageDialog.openError(workbench.getActiveWorkbenchWindow().getShell(),
201
					/* Something went wrong in the macro manager */
201
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE_T,
202
					if (macro == null)
202
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE);
203
					{
203
204
						/* Display error message and switch to the original perspective of the user */
204
						try {
205
						IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();												
205
							workbench.showPerspective(perspectiveId,
206
						MessageDialog.openError(workbench.getActiveWorkbenchWindow().getShell(),
206
								workbench.getActiveWorkbenchWindow());
207
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE_T,
207
						}
208
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_GENERATE);						
208
						catch (WorkbenchException e) {
209
					
209
							/* Not a huge deal if we can't restore the perspective */
210
						try
210
						}
211
						{
211
212
							workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow());
212
						return;
213
						} 
213
					}
214
						catch (WorkbenchException e)
214
215
						{
215
					StringWriter swriter = null;
216
							/* Not a huge deal if we can't restore the perspective */					
216
					try {
217
						}
217
						swriter = new StringWriter();
218
														
218
						PrintWriter pwriter = new PrintWriter(swriter);
219
						return;					
219
						macro.write(0,
220
					}
220
							pwriter);
221
					
221
						pwriter.close();
222
					
222
						swriter.close();
223
					StringWriter swriter = null;
223
					}
224
					try 
224
					catch (Exception e) {
225
					{
225
						String messageWithOrigin = AutoGUIUtil.getOriginOfException(e);
226
						swriter = new StringWriter();
226
						String cause = messageWithOrigin + "\n" + AutoGUIUtil.getExceptionStackTrace(e);
227
						PrintWriter pwriter = new PrintWriter(swriter);
227
						AutoGUIUtil.openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
228
						macro.write(0, pwriter);
228
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP_TITLE,
229
						pwriter.close();
229
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP,
230
						swriter.close();
230
							cause);
231
					}
231
232
					catch (Exception e) 
232
						return;
233
					{
233
					}
234
						String messageWithOrigin = AutoGUIUtil.getOriginOfException(e);
234
235
						String cause = messageWithOrigin + "\n" + AutoGUIUtil.getExceptionStackTrace(e);
235
					/* Create the test case and add the required properties */
236
						AutoGUIUtil.openErrorWithDetail(
236
					ITestSuite testSuite = getTestSuite();
237
								GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
237
					boolean isExternalBehavior = testSuite.getImplementor().isExternalImplementor();
238
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP_TITLE, 
238
					ITestCase testcase = TestCommonUtil.createTestCase(testSuite,
239
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_STOP, 
239
						getType(),
240
								cause);												
240
						isExternalBehavior,
241
						
241
						userInput.getName());
242
						return;
242
					testcase.setDescription(userInput.getDescription());
243
					}
243
244
					
244
					/* Add the starting point */
245
					/* Create the test case and add the required properties */
245
					((AutoGUITestCasesForm) suiteProvider).addProperty(testcase,
246
					ITestSuite testSuite = getTestSuite();
246
						GUITestCaseProperties.STARTING_PT,
247
					boolean isExternalBehavior = testSuite.getImplementor().isExternalImplementor();
247
						userInput.getStartingPoint());
248
					ITestCase testcase = TestCommonUtil.createTestCase(testSuite, getType(), isExternalBehavior, userInput.getName());		
248
249
					testcase.setDescription(userInput.getDescription());
249
					/* Add the macro */
250
					
250
					String contents = swriter.toString();
251
					/* Add the starting point */
251
252
					((AutoGUITestCasesForm)suiteProvider).addProperty(testcase, GUITestCaseProperties.STARTING_PT, userInput.getStartingPoint());
252
					/* Get rid of the last line break */
253
					
253
					int lastLineBreak = contents.lastIndexOf(GlobalConstants.LINE_SEPARATOR);
254
					/* Add the macro */
254
					if (lastLineBreak != -1 && contents.substring(lastLineBreak).trim().length() <= 0)
255
					String contents = swriter.toString();
255
						contents = contents.substring(0,
256
					
256
							lastLineBreak);
257
					/* Get rid of the last line break */
257
258
					int lastLineBreak = contents.lastIndexOf(GlobalConstants.LINE_SEPARATOR);
258
					((AutoGUITestCasesForm) suiteProvider).addProperty(testcase,
259
					if (lastLineBreak != -1 && contents.substring(lastLineBreak).trim().length() <= 0)
259
						GUITestCaseProperties.MACRO_FRAGMENT,
260
						contents = contents.substring(0, lastLineBreak);
260
						contents);
261
					
261
262
					((AutoGUITestCasesForm)suiteProvider).addProperty(testcase, GUITestCaseProperties.MACRO_FRAGMENT, contents);					
262
					/* Switch the perspective to where we were before */
263
				
263
					try {
264
					/* Switch the perspective to where we were before */
264
						IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
265
					try
265
						workbench.showPerspective(perspectiveId,
266
					{
266
							workbench.getActiveWorkbenchWindow());
267
						IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
267
					}
268
						workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow());
268
					catch (WorkbenchException e) {
269
					} 
269
						/* Not a huge deal if we can't restore the perspective */
270
					catch (WorkbenchException e)
270
					}
271
					{
271
272
						/* Not a huge deal if we can't restore the perspective */					
272
					adjusTestCase(testcase);
273
					}
273
274
					
274
					/* Cause a selection event */
275
					adjusTestCase(testcase);
275
					if (testSuiteProvider instanceof AutoGUITestCasesForm) {
276
					
276
						AutoGUITestCasesForm testCaseForm = (AutoGUITestCasesForm) testSuiteProvider;
277
					/* Cause a selection event */
277
						testCaseForm.getLogicalRepresentationListener().selectionChanged(null);
278
					if (testSuiteProvider instanceof AutoGUITestCasesForm)
278
						testCaseForm.getLogicalTreeRepresentaion().selectionChanged(null);
279
					{
279
						testCaseForm.getObjectMineTreeStruct().refresh();
280
						AutoGUITestCasesForm testCaseForm = (AutoGUITestCasesForm)testSuiteProvider;
280
					}
281
						testCaseForm.getLogicalRepresentationListener().selectionChanged(null);
281
				}
282
						testCaseForm.getLogicalTreeRepresentaion().selectionChanged(null);
282
				catch (Throwable t) {
283
						testCaseForm.getObjectMineTreeStruct().refresh();
283
					t.printStackTrace();
284
					}
284
				}
285
				}
285
286
				catch (Throwable t)
286
				break;
287
				{
287
288
					t.printStackTrace();
288
			/* A verificaiton point is inserted */
289
				}
289
			case AutoGUITestControllerDialog.VERIFICATION_HOOK_INSERT:
290
				
290
291
				break;
291
				/* Make sure the verification hook name conforms to the standard defined */
292
				
292
				String hookName = (String) value;
293
			/* A verificaiton point is inserted */
293
				boolean validName = hookName != null && !hookName.equals("") && hookName.length() < 100 && !containSpecialChars(hookName);
294
			case AutoGUITestControllerDialog.VERIFICATION_HOOK_INSERT:		
294
				if (!validName) {
295
				
295
					/* display an error */
296
				/* Make sure the verification hook name conforms to the standard defined */
296
					macroManager.setGlobalState(ModeConstants.SUSPEND_MODE);
297
				String hookName = (String) value;
297
298
				boolean validName = hookName != null && !hookName.equals("") && hookName.length() < 100 && !containSpecialChars (hookName);
298
					AutoGUIUtil.openErrorWithDetail(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
299
				if (!validName)
299
						AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM_T,
300
				{
300
						AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM,
301
					/* display an error */
301
						(String) null);
302
					macroManager.setGlobalState(MacroManager.SUSPEND_MODE);
302
303
					
303
					macroManager.setGlobalState(ModeConstants.RECORDING_MODE);
304
					AutoGUIUtil.openErrorWithDetail(
304
					return;
305
							GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
305
				}
306
							AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM_T, 
306
307
							AutoGUIMessages.AUTO_GUI_ERROR_VER_INVALID_NM, 
307
				macroManager.setGlobalState(ModeConstants.SUSPEND_MODE);
308
							(String)null
308
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_GEN);
309
							);
309
310
					
310
				AutoGUIGenerator generator =
311
					macroManager.setGlobalState(MacroManager.RECORDING_MODE);
311
					new AutoGUIGenerator(((AutoGUITestCasesForm) suiteProvider).getTestSuite(), CodeGeneratorHelper.AUTO_GUI_VERIFICATION_HOOK_CLASS);
312
					return;
312
				try {
313
				}
313
					generator.createChange(new NullProgressMonitor()).perform(new NullProgressMonitor());
314
				
314
				}
315
315
				catch (Exception e) {
316
				macroManager.setGlobalState(MacroManager.SUSPEND_MODE);
316
					/* There was an error in generating the source code */
317
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_GEN);
317
					AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC_T,
318
				
318
						AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC,
319
				AutoGUIGenerator generator = new AutoGUIGenerator (((AutoGUITestCasesForm)suiteProvider).getTestSuite(), CodeGeneratorHelper.AUTO_GUI_VERIFICATION_HOOK_CLASS);
319
						e);
320
				try
320
321
				{
321
					return;
322
					generator.createChange(new NullProgressMonitor()).perform(new NullProgressMonitor());
322
				}
323
				} 
323
324
				catch (Exception e)
324
				macroManager.setGlobalState(ModeConstants.RECORDING_MODE);
325
				{
325
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
326
					/* There was an error in generating the source code */
326
327
					AutoGUIUtil.openErrorWithDetail(
327
				/* Allow the user to select an editor or a view */
328
							AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC_T, 
328
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_VER);
329
							AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_SRC, 
329
				macroManager.setVerListener(new CustomVerHookListener(generator, hookName, controllerDialog.isVerficationScopeExtended()));
330
							e);
330
				macroManager.setGlobalState(ModeConstants.VERIFICATION_MODE);
331
331
332
					return;
332
				if (globalStateListener != null)
333
				}
333
					globalStateListener.turnOn(true);
334
				
334
335
				macroManager.setGlobalState(MacroManager.RECORDING_MODE);
335
				break;
336
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
336
337
337
			/* The restart button is pressed */
338
				
338
			case AutoGUITestControllerDialog.RESTART:
339
				/* Allow the user to select an editor or a view */
339
				/* Restart recording */
340
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_VER);
340
				macroManager.stopRecording(true);
341
				macroManager.setVerListener(new CustomVerHookListener(generator, hookName));
341
				MacroObjectDescriptorMineManager.getInstance().clearCache();
342
				macroManager.setGlobalState(MacroManager.VERIFICATION_MODE);
342
				AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG_T,
343
				
343
					AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG,
344
				if (globalStateListener != null)
344
					MessageDialog.INFORMATION);
345
					globalStateListener.turnOn(true);
345
				startRecording(MacroManager.getInstance().isObjectMineOn());
346
				
346
347
				break;
347
				if (!controllerDialog.isPositionBasedOn())
348
				
348
					break;
349
			/* The restart button is pressed */
349
350
			case AutoGUITestControllerDialog.RESTART:	
350
				/* The position based recording option is turned on/off */
351
				/* Restart recording */
351
			case AutoGUITestControllerDialog.POSITION_BASED:
352
				macroManager.stopRecording(true);
352
				boolean success = MacroManager.getInstance().togglePositionBasedRec(controllerDialog.isPositionBasedOn());
353
				ObjectMineManager.getInstance().clearCache();
353
354
				AutoGUIUtil.showMessage(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG_T, 
354
				if (success) {
355
						AutoGUIMessages.AUTO_GUI_CONTROL_RESTART_MSG,
355
					if (controllerDialog.isPositionBasedOn())
356
						MessageDialog.INFORMATION);
356
						controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_POS);
357
				startRecording(MacroManager.getInstance().isObjectMineOn());
357
					else
358
				
358
						controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
359
				if (!controllerDialog.isPositionBasedOn())
359
				}
360
					break;
360
361
			
361
				break;
362
			/* The position based recording option is turned on/off */
362
363
			case AutoGUITestControllerDialog.POSITION_BASED:
363
			/* Wait time recording is turned on/off */
364
				boolean success = MacroManager.getInstance().togglePositionBasedRec(controllerDialog.isPositionBasedOn());
364
			case AutoGUITestControllerDialog.WAIT_TIME:
365
365
				MacroManager.getInstance().setArtificialWaitOn(controllerDialog.isWaitTimeOn());
366
				if (success)
366
367
				{
367
		}
368
					if (controllerDialog.isPositionBasedOn())
368
369
						controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_POS);
369
	}
370
					else
370
371
						controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
371
	private boolean containSpecialChars(String hookName) {
372
				}
372
		boolean condition = false;
373
				
373
374
				break;
374
		char currentChar = hookName.charAt(0);
375
			
375
		condition = (currentChar < 65 || currentChar > 90) && (currentChar < 97 || currentChar > 122);
376
			/* Wait time recording is turned on/off */
376
377
			case AutoGUITestControllerDialog.WAIT_TIME:
377
		if (condition)
378
				MacroManager.getInstance().setArtificialWaitOn(controllerDialog.isWaitTimeOn()); 
378
			return condition;
379
			
379
380
		}
380
		for (int i = 1; i < hookName.length(); i++) {
381
		
381
			currentChar = hookName.charAt(i);
382
	}
382
			condition =
383
	
383
				(currentChar < 65 || currentChar > 90)
384
	
384
					&& (currentChar < 97 || currentChar > 122)
385
	private boolean containSpecialChars(String hookName)
385
					&& (currentChar < 48 || currentChar > 57)
386
	{
386
					&& currentChar != 36
387
		boolean condition = false;
387
					&& currentChar != 95;
388
		
388
			if (condition)
389
		char currentChar = hookName.charAt(0);
389
				return condition;
390
		condition = (currentChar < 65 || currentChar > 90) && (currentChar < 97 || currentChar > 122);
390
		}
391
		
391
		return false;
392
		if (condition)
392
	}
393
			return condition;
393
394
		
394
	public class CustomVerHookListener implements VerificationHookListener {
395
		for (int i = 1; i < hookName.length(); i++)
395
396
		{
396
		private String verHook;
397
			currentChar = hookName.charAt(i);
397
		private boolean extendedScope;
398
			condition = (currentChar < 65 || currentChar > 90) && (currentChar < 97 || currentChar > 122) &&
398
		private AutoGUIGenerator generator;
399
						(currentChar < 48 || currentChar > 57) && currentChar != 36 && currentChar != 95;
399
		private boolean instanceReady;
400
			if (condition)
400
401
				return condition;
401
		public CustomVerHookListener(AutoGUIGenerator generator, String verificationHook, boolean extendedScope) {
402
		}
402
			this.verHook = verificationHook;
403
		return false;
403
			this.extendedScope = extendedScope;
404
	}
404
			this.generator = generator;
405
405
			this.instanceReady = false;
406
406
		}
407
	public class CustomVerHookListener implements VerificationHookListener
407
408
	{
408
		public synchronized void error(String error) {
409
		private String verHook;
409
			if (!instanceReady)
410
		private AutoGUIGenerator generator; 
410
				controllerDialog.setStatus(error);
411
		private boolean instanceReady;
411
			else
412
		
412
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
413
		public CustomVerHookListener(AutoGUIGenerator generator, String verificationHook)
413
		}
414
		{
414
415
			this.verHook = verificationHook;
415
		public synchronized void instanceReady(VerificationCommand verificationCommand) {
416
			this.generator = generator;
416
			instanceReady = true;
417
			this.instanceReady = false;
417
			/* We no longer need this class after being notified of the instance construciton */
418
		}
418
			MacroManager.getInstance().removeVerListener();
419
		
419
420
		
420
			controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_INS);
421
		public synchronized void error(String error)
421
422
		{
422
			/* Insert a method in the source file corresponding to the name of the verification hook */
423
			if (!instanceReady)
423
			try {
424
				controllerDialog.setStatus(error);		
424
				/*
425
			else
425
				 * We got the instance that we were looking for. Time to generate the method in the source code that is associated with this test
426
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
426
				 * suite
427
		}
427
				 */
428
428
				String contextArgument = "Q";
429
		public synchronized void instanceReady(VerificationCommand verificationCommand)
429
				contextArgument += verificationCommand.getContextClass().getName();
430
		{
430
				contextArgument += ";";
431
			instanceReady = true;
431
432
			/* We no longer need this class after being notified of the instance construciton */
432
				String[] args;
433
			MacroManager.getInstance().removeVerListener();
433
				if (!extendedScope) {
434
			
434
					args = new String[] {contextArgument};
435
			controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_INS);
435
				}
436
			
436
				else {
437
			/* We got the instance that we were looking for.  Time to generate the method in the source code that
437
					// construct a second argument for the UI object being selected
438
			 * is associated with this test suite */					
438
					String widgetArgument = "Q";
439
			String argument = "Q";
439
					widgetArgument += verificationCommand.getWidgetClass().getName();
440
			byte verificationContextType = verificationCommand.getMetaData().getFocusType();
440
					widgetArgument += ";";
441
			switch (verificationContextType)
441
					
442
			{
442
					String objectArgument = null;
443
				case VerificationMetaData.EDITOR:
443
					if(verificationCommand.getObjectClass() != null){
444
					argument += IEditorPart.class.getName();
444
						objectArgument = "Q";
445
					break;
445
						objectArgument += verificationCommand.getObjectClass().getName();
446
				case VerificationMetaData.VIEW:
446
						objectArgument += ";";						
447
					argument += IViewPart.class.getName();
447
					}
448
					break;
448
449
				case VerificationMetaData.SHELL:
449
					args = objectArgument == null ? new String[2] : new String[3];
450
					argument += Shell.class.getName();
450
					args[0] = contextArgument;
451
					break;
451
					args[1] = widgetArgument;
452
			}
452
					if(objectArgument != null){
453
			argument = argument + ";";
453
						args[2] = objectArgument;
454
			
454
					}
455
			/* Insert a method in the source file corresponding to the name of the verification hook */
455
				}
456
			try
456
457
			{
457
				/* This should never happen */
458
				/* This should never happen */
458
				if (contextArgument.length() <= 2)
459
				if (argument.length() <= 2)
459
					throw new Exception(AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON);
460
					throw new Exception (AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON);
460
461
					
461
				/* Complete the verification command's meta data */
462
				/* Complete the verification command's meta data */
462
				ITestSuite testSuite = ((AutoGUITestCasesForm) suiteProvider).getTestSuite();
463
				ITestSuite testSuite = ((AutoGUITestCasesForm)suiteProvider).getTestSuite();
463
				verificationCommand.setLocation(testSuite.getImplementor().getLocation());
464
				VerificationMetaData metaData = verificationCommand.getMetaData();
464
				verificationCommand.setResource(testSuite.getImplementor().getResource());
465
				metaData.setLocation(testSuite.getImplementor().getLocation());
465
				verificationCommand.setHook(verHook + ":" + (args.length > 1 ? (args.length > 2 ? args[0] + args[1] + args[2] : args[0] + args[1]) : args[0]));
466
				metaData.setResource(testSuite.getImplementor().getResource());
466
				verificationCommand.setExtendedScope(extendedScope);
467
				metaData.setHook(verHook + ":" + argument);
467
468
				
468
				generator.setInput(userInput.getName(),
469
				generator.setInput(userInput.getName(), userInput.getDescription());
469
					userInput.getDescription());
470
				generator.createMethod (verHook, argument);
470
				generator.createMethod(verHook,
471
			} catch (Exception e)
471
					args);
472
			{
472
			}
473
				MessageDialog.openWarning(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
473
			catch (Exception e) {
474
										AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD_T,
474
				MessageDialog.openWarning(GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),
475
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD, e.getLocalizedMessage()));				
475
					AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD_T,
476
			}
476
					NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_GEN_METHOD,
477
			
477
						e.getLocalizedMessage()));
478
			/* Change the state of the macro manager to recording */
478
			}
479
			if (globalStateListener != null)
479
480
				globalStateListener.turnOn(false);
480
			/* Change the state of the macro manager to recording */
481
			MacroManager.getInstance().setGlobalState(MacroManager.RECORDING_MODE);
481
			if (globalStateListener != null)
482
			controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);	
482
				globalStateListener.turnOn(false);
483
		
483
			MacroManager.getInstance().setGlobalState(ModeConstants.RECORDING_MODE);
484
		}
484
			controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
485
	
485
486
	}
486
		}
487
487
488
	
488
	}
489
	public class CustomGlobalStateListener implements GlobalStateListener
489
490
	{
490
	public class CustomGlobalStateListener implements GlobalStateListener {
491
491
492
		private boolean isOn;
492
		private boolean isOn;
493
		
493
494
		public CustomGlobalStateListener(boolean isOn)
494
		public CustomGlobalStateListener(boolean isOn) {
495
		{
495
			this.isOn = isOn;
496
			this.isOn = isOn;
496
		}
497
		}
497
498
		
498
		public void turnOn(boolean isOn) {
499
		public void turnOn (boolean isOn)
499
			this.isOn = isOn;
500
		{
500
		}
501
			this.isOn = isOn;
501
502
		}
502
		public boolean isListenerOn() {
503
		
503
			return isOn;
504
		public boolean isListenerOn()
504
		}
505
		{
505
506
			return isOn;
506
		public void globalStateChange(byte oldState, byte newState) {
507
		}
507
			/*
508
508
			 * We're only interested when we're in verification mode and we get interrupted
509
		public void globalStateChange(byte oldState, byte newState)
509
			 */
510
		{
510
			if (oldState == ModeConstants.VERIFICATION_MODE && newState == ModeConstants.SUSPEND_MODE) {
511
			/* We're only interested when we're in verification mode and we 
511
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);
512
			 * get interrupted */
512
			}
513
			if (oldState == MacroManager.VERIFICATION_MODE && newState == MacroManager.SUSPEND_MODE)
513
		}
514
			{
514
515
				controllerDialog.setStatus(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_REC);	
515
	}
516
			}
516
}
517
		}
518
		
519
	}
520
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIUpdateTestCaseAction.java (-310 / +500 lines)
Lines 1-310 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2007 IBM Corporation and others.
2
 * Copyright (c) 2006 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.actions;
11
package org.eclipse.tptp.test.auto.gui.internal.actions;
12
12
13
import java.io.ByteArrayInputStream;
13
import java.io.ByteArrayInputStream;
14
import java.lang.reflect.Method;
14
import java.lang.reflect.Method;
15
import java.util.Hashtable;
15
import java.util.Hashtable;
16
import java.util.Map;
16
import java.util.Map;
17
17
18
import org.eclipse.jface.dialogs.MessageDialog;
18
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.jface.resource.ImageDescriptor;
19
import org.eclipse.core.runtime.Path;
20
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
20
import org.eclipse.jface.dialogs.MessageDialog;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
21
import org.eclipse.jface.resource.ImageDescriptor;
22
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
22
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
23
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
23
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
24
import org.eclipse.tptp.test.auto.gui.internal.core.IObjectMine;
24
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
25
import org.eclipse.tptp.test.auto.gui.internal.core.IUIObject;
25
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
26
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
26
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
27
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
27
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
31
import org.eclipse.tptp.test.auto.gui.internal.macro.ObjectMineManager;
31
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
32
import org.eclipse.tptp.test.auto.gui.internal.macro.UIObject;
32
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
33
import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler;
33
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
34
import org.w3c.dom.NamedNodeMap;
34
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
35
import org.w3c.dom.Node;
35
import org.w3c.dom.NamedNodeMap;
36
import org.w3c.dom.NodeList;
36
import org.w3c.dom.Node;
37
37
import org.w3c.dom.NodeList;
38
/**
38
39
 * This action will update the macro of the selected test cases to use the 
39
/**
40
 * latest syntax of the macro.
40
 * This action will update the macro of the selected test cases to use the
41
 * 
41
 * latest syntax of the macro.
42
 * @author Ali Mehregani
42
 * 
43
 */
43
 * @author Ali Mehregani
44
public class AutoGUIUpdateTestCaseAction extends AutoGUITestCaseAction
44
 * @author Alexander Nyssen
45
{
45
 */
46
	/** Versions */
46
public class AutoGUIUpdateTestCaseAction extends AutoGUITestCaseAction
47
	private static final String VERSION_1_0 = "1.0";
47
{
48
	
48
	/** Versions */
49
	/** The updater table contains the method name that can update a particular version of a macro 
49
	private static final String VERSION_1_0 = "1.0";
50
	 * KEY = The macro version that can be updated
50
	private static final String VERSION_1_1 = "1.1";
51
	 * VALUE = The method name that will do the update
51
52
	 */
52
	/**
53
	private Map updaterTable;
53
	 * The updater table contains the method name that can update a particular
54
	
54
	 * version of a macro KEY = The macro version that can be updated VALUE =
55
	/** The object mine that belongs to the test suite of this action */
55
	 * The method name that will do the update
56
	private IObjectMine objectMine;
56
	 */
57
	
57
	private Map updaterTable;
58
	
58
59
	public AutoGUIUpdateTestCaseAction(AutoGUITestCasesForm testCaseForm, String text, ImageDescriptor imageDescriptor)
59
	/** The object mine that belongs to the test suite of this action */
60
	{
60
	private MacroObjectDescriptorMine objectMine;
61
		super(testCaseForm, text, imageDescriptor);
61
62
		setEnabled(false);
62
	public AutoGUIUpdateTestCaseAction(AutoGUITestCasesForm testCaseForm,
63
		
63
			String text, ImageDescriptor imageDescriptor) {
64
		/* Initialize the updater table */
64
		super(testCaseForm, text, imageDescriptor);
65
		updaterTable = new Hashtable();					
65
		setEnabled(false);
66
		final String VERSION_01 = "0.1";
66
67
		final String UPDATER_01 = "updater01";
67
		/* Initialize the updater table */
68
		
68
		updaterTable = new Hashtable();
69
		updaterTable.put(VERSION_01, UPDATER_01);		
69
		final String VERSION_0_1 = "0.1";
70
	}
70
		final String UPDATER__0_1__1_0 = "Update_0_1_to_1_0";
71
	
71
		final String UPDATER__1_0__1_1 = "Update_1_0_to_1_1";
72
	
72
		updaterTable.put(VERSION_0_1, UPDATER__0_1__1_0);
73
	/**
73
		updaterTable.put(VERSION_1_0, UPDATER__1_0__1_1);
74
	 * Invoked when the action is executed.  Walk through each of the selected test cases 
74
	}
75
	 * and update their corresponding macro.  
75
76
	 */
76
	/**
77
	public void run() 
77
	 * Invoked when the action is executed. Walk through each of the selected
78
	{		
78
	 * test cases and update their corresponding macro.
79
		if (!MessageDialog.openQuestion(
79
	 */
80
				GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
80
	public void run() {
81
				AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE_TITLE, 
81
		if (!MessageDialog.openQuestion(GuiPlugin.getDefault().getWorkbench()
82
				AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE))
82
				.getActiveWorkbenchWindow().getShell(),
83
		{
83
				AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE_TITLE,
84
			return;
84
				AutoGUIMessages.AUTO_GUI_TST_CASE_UPDATE)) {
85
		}
85
			return;
86
		
86
		}
87
		try
87
88
		{
88
		try {
89
			objectMine = ObjectMineManager.getInstance().loadObjectMine(testCaseForm.getTestSuite());
89
			objectMine = MacroObjectDescriptorMineManager.getInstance()
90
		} 
90
					.loadObjectMine(testCaseForm.getTestSuite());
91
		catch (Exception e)
91
		} catch (Exception e) {
92
		{
92
			AutoGUIUtil.openErrorWithDetail(
93
			AutoGUIUtil.openErrorWithDetail(
93
					AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
94
					AutoGUIMessages.AUTO_GUI_COMMON_ERROR, 
94
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, e);
95
					AutoGUIMessages.AUTO_GUI_ERROR_MACRO_REC, 
95
			return;
96
					e);
96
		}
97
			return;
97
98
		}
98
		/* For each selected test case */
99
		
99
		boolean updated = false;
100
		/* For each selected test case */
100
		for (int i = 0; i < selectedTestCases.length; i++) {
101
		boolean updated = false;
101
			/* Parse the macro of the selected test case */
102
		for (int i = 0; i < selectedTestCases.length; i++)
102
			String testCaseMacro = testCaseForm.getProperty(
103
		{
103
					selectedTestCases[i], GUITestCaseProperties.MACRO_FRAGMENT);
104
			/* Parse the macro of the selected test case */
104
			if (testCaseMacro == null || testCaseMacro.length() <= 0)
105
			String testCaseMacro = testCaseForm.getProperty(selectedTestCases[i], GUITestCaseProperties.MACRO_FRAGMENT);
105
				continue;
106
			if (testCaseMacro == null || testCaseMacro.length() <= 0)
106
107
				continue;
107
			XMLDefaultHandler handler = null;
108
			
108
			Node rootElement = null;
109
			XMLDefaultHandler handler = null;
109
			try {
110
			Node rootElement = null;
110
				handler = MacroManager.getInstance().createMacroDocument(
111
			try
111
						new ByteArrayInputStream(testCaseMacro
112
			{
112
								.getBytes("UTF-8")));
113
				handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(testCaseMacro.getBytes("UTF-8")));
113
				rootElement = handler.getDocumentElement();
114
				rootElement = handler.getDocumentElement();
114
			} catch (Exception e) {
115
			}
115
				/* Handled by the next line */
116
			catch (Exception e)
116
			}
117
			{
117
118
				/* Handled by the next line */
118
			if (rootElement == null
119
			}
119
					&& !MacroConstants.MACRO_ELEMENT.equals(rootElement
120
			
120
							.getNodeName()))
121
			if (rootElement != null && !MacroConstants.MACRO_ELEMENT.equals(rootElement.getNodeName()))
121
				continue;
122
				continue;
122
123
			
123
			/*
124
			
124
			 * Look up the current version of the macro and call its
125
			/* Look up the current version of the macro and call its corresponding update method */
125
			 * corresponding update method
126
			Node macroVersion = rootElement.getAttributes().getNamedItem(MacroConstants.VERSION_ATTRIBUTE);					
126
			 */
127
			String currentVersion;
127
			Node macroVersion = rootElement.getAttributes().getNamedItem(
128
			if (macroVersion == null || (currentVersion = macroVersion.getNodeValue()) == null)
128
					MacroConstants.VERSION_ATTRIBUTE);
129
				continue;
129
			String currentVersion;
130
									
130
			if (macroVersion == null
131
			/* For every sequential update required */
131
					|| (currentVersion = macroVersion.getNodeValue()) == null)
132
			String updater = null;
132
				continue;
133
			boolean updateTestCaseMacro = false;
133
134
			while ((updater = (String)updaterTable.get(currentVersion)) != null)
134
			/* For every sequential update required */
135
			{
135
			String updater = null;
136
				try
136
			boolean updateTestCaseMacro = false;
137
				{
137
			while ((updater = (String) updaterTable.get(currentVersion)) != null) {
138
					Method method = this.getClass().getMethod(updater, new Class[] {XMLDefaultHandler.class, IUIObject.class, Node.class});
138
				try {
139
					if (method != null)
139
					Method method = this.getClass().getMethod(
140
					{
140
							updater,
141
						currentVersion = (String)(method.invoke(this, new Object[]{handler, null, rootElement}));
141
							new Class[] { XMLDefaultHandler.class,
142
						updateTestCaseMacro = true;
142
									MacroObjectDescriptor.class, Node.class });
143
					}
143
					if (method != null) {
144
					else
144
						currentVersion = (String) (method.invoke(this,
145
					{
145
								new Object[] { handler, null, rootElement }));
146
						break;
146
						updateTestCaseMacro = true;
147
					}												
147
					} else {
148
				} 
148
						break;
149
				catch (Exception e)
149
					}
150
				{
150
				} catch (Exception e) {
151
					/* Should not happen */
151
					/* Should not happen */
152
					e.printStackTrace();
152
					e.printStackTrace();
153
					break;
153
					break;
154
				}
154
				}
155
			}
155
			}
156
			
156
157
			/* Update the test case macro and the object mine */
157
			/* Update the test case macro and the object mine */
158
			if (updateTestCaseMacro)
158
			if (updateTestCaseMacro) {
159
			{
159
				updated = true;
160
				updated = true;
160
				StringBuffer buffer = new StringBuffer();
161
				StringBuffer buffer = new StringBuffer();
161
				serializeXMLToString(buffer, rootElement, 0);
162
				serializeXMLToString(buffer, rootElement, 0);
162
				testCaseForm.updateTestProperty(null, buffer.toString(), false);
163
				testCaseForm.updateTestProperty (null, buffer.toString(), false);		
163
164
				
164
				MacroObjectDescriptorMineManager.getInstance().writeObjectMine(
165
				ObjectMineManager.getInstance().writeObjectMine(objectMine);
165
						objectMine);
166
				testCaseForm.refresh();
166
				testCaseForm.refresh();
167
			}			
167
			}
168
		}	
168
		}
169
		
169
170
		if (!updated)
170
		if (!updated) {
171
		{
171
			MessageDialog.openInformation(GuiPlugin.getDefault().getWorkbench()
172
			MessageDialog.openInformation(
172
					.getActiveWorkbenchWindow().getShell(),
173
					GuiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(), 
173
					AutoGUIMessages.AUTO_GUI_COMMON_INFORMATION,
174
					AutoGUIMessages.AUTO_GUI_COMMON_INFORMATION, 
174
					AutoGUIMessages.AUTO_GUI_TST_CASE_NO_UPDATE);
175
					AutoGUIMessages.AUTO_GUI_TST_CASE_NO_UPDATE);
175
		}
176
		}
176
	}
177
	}
177
178
	
178
	private void serializeXMLToString(StringBuffer buffer, Node node, int indent) {
179
	private void serializeXMLToString(StringBuffer buffer, Node node, int indent)
179
		/* Write the current element */
180
	{		
180
		boolean hasChildren = node.hasChildNodes();
181
		/* Write the current element */
181
		boolean hasAttributes = node.hasAttributes();
182
		boolean hasChildren = node.hasChildNodes();
182
		String nodeName = node.getNodeName();
183
		boolean hasAttributes = node.hasAttributes();
183
		final String TEXT_NODE_NAME = "#text";
184
		String nodeName = node.getNodeName();
184
185
		final String TEXT_NODE_NAME = "#text";
185
		if (TEXT_NODE_NAME.equals(nodeName)) {
186
		
186
			String textContent = node.getNodeValue().trim();
187
		if (TEXT_NODE_NAME.equals(nodeName))
187
			boolean isContentEmpty = textContent == null
188
		{
188
					|| MacroConstants.EMPTY_STRING.equals(textContent);
189
			String textContent = node.getNodeValue().trim();
189
			;
190
			boolean isContentEmpty = textContent == null || MacroConstants.EMPTY_STRING.equals(textContent);; 
190
			if (!isContentEmpty) {
191
			if (!isContentEmpty)
191
				MacroUtil.addIndent(buffer, indent);
192
			{
192
				buffer.append(textContent);
193
				MacroUtil.addIndent(buffer, indent);
193
				buffer.append(GlobalConstants.LINE_SEPARATOR);
194
				buffer.append(textContent);
194
			}
195
				buffer.append(GlobalConstants.LINE_SEPARATOR);
195
196
			}
196
			return;
197
			
197
		}
198
			return;
198
199
		}
199
		MacroUtil.addElement(buffer, indent, nodeName, !hasChildren
200
			
200
				&& !hasAttributes, !hasAttributes);
201
		
201
202
		MacroUtil.addElement(buffer, indent, nodeName, !hasChildren && !hasAttributes, !hasAttributes);
202
		/* Get the attributes */
203
		
203
		if (hasAttributes) {
204
		/* Get the attributes */
204
			NamedNodeMap attributes = node.getAttributes();
205
		if (hasAttributes)
205
			int attCount = attributes.getLength();
206
		{
206
			String[] attributeNames = new String[attCount];
207
			NamedNodeMap attributes = node.getAttributes();
207
			String[] attributeValues = new String[attCount];
208
			int attCount = attributes.getLength();
208
			for (int i = 0; i < attCount; i++) {
209
			String[] attributeNames = new String[attCount];
209
				Node currentAttribute = attributes.item(i);
210
			String[] attributeValues = new String[attCount];
210
				attributeNames[i] = currentAttribute.getNodeName();
211
			for (int i = 0; i < attCount; i++)
211
				attributeValues[i] = currentAttribute.getNodeValue();
212
			{
212
			}
213
				Node currentAttribute = attributes.item(i);
213
			MacroUtil.addAttribute(buffer, attributeNames, attributeValues,
214
				attributeNames[i] = currentAttribute.getNodeName();
214
					!hasChildren, true);
215
				attributeValues[i] = currentAttribute.getNodeValue();			
215
		}
216
			}
216
217
			MacroUtil.addAttribute(buffer, attributeNames, attributeValues, !hasChildren, true);
217
		/* For each child */
218
		}
218
		NodeList nodeList = node.getChildNodes();
219
		
219
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) {
220
		/* For each child */
220
			serializeXMLToString(buffer, nodeList.item(i), indent + 1);
221
		NodeList nodeList = node.getChildNodes();
221
		}
222
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++)
222
223
		{			
223
		/* Close the XML node */
224
			serializeXMLToString (buffer, nodeList.item(i), indent + 1);
224
		if (hasChildren) {
225
		}
225
			MacroUtil.addElement(buffer, indent, nodeName, true, true);
226
		
226
		}
227
		/* Close the XML node */
227
228
		if (hasChildren)
228
	}
229
		{
229
230
			MacroUtil.addElement(buffer, indent, nodeName, true, true);
230
	/**
231
		}
231
	 * Converts a prior 1.1 context id to the new 1.1. format (using separators
232
		
232
	 * instead of PATH.SEPARATOR)
233
	}
233
	 * 
234
234
	 * @param oldContextId
235
235
	 * @return
236
	public String updater01 (XMLDefaultHandler handler, IUIObject parent, Node rootNode)
236
	 */
237
	{
237
	private String convertSerializedContextId(String oldContextId) {
238
		NodeList nodeList = rootNode.getChildNodes();
238
		if (oldContextId != null
239
		Node currentNode;
239
				&& (oldContextId.startsWith(MacroConstants.LOCAL_TOOLBAR_VALUE)
240
				
240
						|| oldContextId.startsWith(MacroConstants.POPUP_VALUE) || oldContextId
241
		/* Update the version of the macro */
241
						.startsWith(MacroConstants.TAB_VALUE))
242
		if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName()))
242
				&& oldContextId
243
		{
243
						.indexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR) < 0) {
244
			NamedNodeMap rootAttributes = rootNode.getAttributes();
244
			// may be old format (or the context id does not use a
245
			Node versionAttribute = null;
245
			// nested serealized macro object id), have to convert
246
			if (rootAttributes != null && (versionAttribute = rootAttributes.getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null)
246
			IPath wpath = new Path(oldContextId);
247
			{
247
			String widgetId = wpath.lastSegment();
248
				versionAttribute.setNodeValue(VERSION_1_0);
248
			wpath = wpath.removeLastSegments(1);
249
			}
249
			while (widgetId.startsWith("}}")) {
250
		}
250
				widgetId = wpath.lastSegment() + IPath.SEPARATOR + widgetId;
251
		
251
				wpath = wpath.removeLastSegments(1);
252
		/* For each child */
252
			}
253
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++)
253
			String contextId = wpath.toString()
254
		{			
254
					+ MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR + widgetId;
255
			currentNode = nodeList.item(i);
255
			return contextId;
256
			NamedNodeMap attributes = currentNode.getAttributes();
256
		}
257
			if (attributes == null)
257
		return oldContextId;
258
				continue;
258
	}
259
			
259
260
			Node contextIdNode = attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
260
	/*
261
			boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode.getNodeName());
261
	 * Convert widget id where the object id was stored as suffix into distinct
262
			boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode.getNodeName()) || MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode.getNodeName());
262
	 * widget and object ids
263
			String idAttributeName =  isShell ? MacroConstants.ID_ATTRIBUTE : isItem ? MacroConstants.PATH_ATTRIBUTE : MacroConstants.WIDGET_ID_ATTRIBUTE;
263
	 */
264
			Node objectIdNode = attributes.getNamedItem(idAttributeName);
264
	private String[] convertConcatWidgetId(String oldWidgetId) {
265
					
265
		if (oldWidgetId != null
266
			String contextId = contextIdNode == null ? null : contextIdNode.getNodeValue();
266
				&& oldWidgetId
267
			String objectId = objectIdNode == null ? null : objectIdNode.getNodeValue();
267
						.indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) >= 0) {
268
			
268
			String[] uiObjectId = new String[2];
269
			IUIObject uiObject = null;
269
			uiObjectId[0] = oldWidgetId.substring(0, oldWidgetId
270
			if (objectId != null)		
270
					.indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR));
271
			{
271
			uiObjectId[1] = oldWidgetId.substring(oldWidgetId
272
				uiObject = objectMine.lookupUIObject(isShell ? null : parent, contextId, objectId);
272
					.indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) + 3);
273
				if (uiObject == null)
273
			return uiObjectId;
274
				{
274
		}
275
					try
275
		return new String[] { oldWidgetId };
276
					{
276
	}
277
						uiObject = new UIObject(parent);
277
278
						uiObject.setContextId(contextId);
278
	public String Update_1_0_to_1_1(XMLDefaultHandler handler,
279
						uiObject.setDescriptive(attributes.getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE) == null ? MacroConstants.OBJECT_ELEMENT : attributes.getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE).getNodeValue());
279
			MacroObjectDescriptor parent, Node rootNode) {
280
						uiObject.setObjectId(objectId);
280
		NodeList nodeList = rootNode.getChildNodes();
281
						uiObject.setParent(isShell ? null : parent);
281
		Node currentNode;
282
						uiObject.setReferenceId(objectMine.getUniqueReferenceId());
282
283
						
283
		/* Update the version of the macro */
284
						objectMine.registerObject(uiObject);
284
		if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName())) {
285
					} 
285
			NamedNodeMap rootAttributes = rootNode.getAttributes();
286
					catch (Exception e)
286
			Node versionAttribute = null;
287
					{
287
			if (rootAttributes != null
288
						/* Shouldn't happen */
288
					&& (versionAttribute = rootAttributes
289
						e.printStackTrace();
289
							.getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null) {
290
					}
290
				versionAttribute.setNodeValue(VERSION_1_1);
291
				}
291
			}
292
				
292
		}
293
				if (uiObject != null)
293
294
				{
294
		/* For each child */
295
					if (contextId != null)
295
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) {
296
						attributes.removeNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
296
			currentNode = nodeList.item(i);
297
					attributes.removeNamedItem(idAttributeName);
297
			NamedNodeMap attributes = currentNode.getAttributes();
298
					Node refIdAttribute = handler.getDocument().createAttribute(MacroConstants.REFERENCE_ID_ATTRIBUTE);
298
			if (attributes == null)
299
					refIdAttribute.setNodeValue(uiObject.getReferenceId());					
299
				continue;
300
					attributes.setNamedItem(refIdAttribute);
300
301
				}
301
			// Fix old context identifiers (serialized widget identifiers)
302
			}
302
			if (attributes.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE) != null) {
303
			
303
				Node contextIdAttributeNode = attributes
304
			if (currentNode.hasChildNodes())
304
						.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
305
				updater01(handler, uiObject == null ? parent : uiObject, currentNode);
305
				String oldContextId = contextIdAttributeNode.getNodeValue();
306
		}
306
				String newContextId = convertSerializedContextId(oldContextId);
307
		
307
				if (!oldContextId.equals(newContextId)) {
308
		return VERSION_1_0;
308
					contextIdAttributeNode.setNodeValue(newContextId);
309
	}
309
				}
310
}
310
			}
311
312
			// Replace old ID attribute of shell with WIDGET_ID (now used
313
			// globally)
314
			if (attributes.getNamedItem(MacroConstants.ID_ATTRIBUTE) != null) {
315
				Node idAttributeNode = attributes
316
						.getNamedItem(MacroConstants.ID_ATTRIBUTE);
317
				String widgetId = idAttributeNode.getNodeValue();
318
				attributes.removeNamedItem(MacroConstants.ID_ATTRIBUTE);
319
				Node widgetIdAttribute = handler.getDocument().createAttribute(
320
						MacroConstants.WIDGET_ID_ATTRIBUTE);
321
				widgetIdAttribute.setNodeValue(widgetId);
322
				attributes.setNamedItem(widgetIdAttribute);
323
			}
324
325
			// Fix old widget identifiers (that have the object id as suffix)
326
			if (attributes.getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE) != null) {
327
				Node widgetIdAttributeNode = attributes
328
						.getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE);
329
				String oldWidgetId = widgetIdAttributeNode.getNodeValue();
330
				String[] uiObjectId = convertConcatWidgetId(oldWidgetId);
331
				if (!oldWidgetId.equals(uiObjectId[0])) {
332
					widgetIdAttributeNode.setNodeValue(uiObjectId[0]);
333
					// we have an object id, add an object id
334
					if (uiObjectId.length > 1) {
335
						Node objectIdAttribute = handler.getDocument()
336
								.createAttribute(
337
										MacroConstants.OBJECT_ID_ATTRIBUTE);
338
						objectIdAttribute.setNodeValue(uiObjectId[1]);
339
						attributes.setNamedItem(objectIdAttribute);
340
					}
341
				}
342
			}
343
344
			// Replace old PATH attribute of item -> now also WIDGET_ID
345
			boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode
346
					.getNodeName())
347
					|| MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode
348
							.getNodeName());
349
			if (isItem
350
					&& attributes.getNamedItem(MacroConstants.PATH_ATTRIBUTE) != null) {
351
				Node idAttributeNode = attributes
352
						.getNamedItem(MacroConstants.PATH_ATTRIBUTE);
353
				String widgetId = idAttributeNode.getNodeValue();
354
				attributes.removeNamedItem(MacroConstants.PATH_ATTRIBUTE);
355
				Node widgetIdAttribute = handler.getDocument().createAttribute(
356
						MacroConstants.WIDGET_ID_ATTRIBUTE);
357
				widgetIdAttribute.setNodeValue(widgetId);
358
				attributes.setNamedItem(widgetIdAttribute);
359
			}
360
361
			// // replace the old CHOICE_ID attribute -> now the more general
362
			// OBJECT_ID can be used
363
			// if (attributes.getNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE)
364
			// != null) {
365
			// Node idAttributeNode = attributes
366
			// .getNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE);
367
			// String objectId = idAttributeNode.getNodeValue();
368
			// attributes.removeNamedItem(MacroConstants.CHOICE_ID_ATTRIBUTE);
369
			// Node objectIdAttribute = handler.getDocument().createAttribute(
370
			// MacroConstants.OBJECT_ID_ATTRIBUTE);
371
			// objectIdAttribute.setNodeValue(objectId);
372
			// attributes.setNamedItem(objectIdAttribute);
373
			// }
374
375
			// if the object is stored in the object mine, make sure the old
376
			// context id is converted
377
			Node refIdNode = attributes
378
					.getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE);
379
			String refId = refIdNode == null ? null : refIdNode.getNodeValue();
380
			boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode
381
					.getNodeName());
382
383
			MacroObjectDescriptor descriptor = null;
384
			if (refId != null) {
385
				descriptor = objectMine.lookupMacroObjectDescriptor(
386
						isShell ? null : parent, refId);
387
				// fix the context id
388
				if (descriptor != null) {
389
					descriptor
390
							.setContextId(convertSerializedContextId(descriptor
391
									.getContextId()));
392
				}
393
394
				// NOTE: the object id was not stored as suffix of the widget id up to now (due to a bug),
395
				// so we do not have to convert it here.
396
				
397
				// the ID -> WIDGET_ID conversion is done implicitly for the
398
				// stored descriptors when saving the object mine
399
			}
400
401
			if (currentNode.hasChildNodes())
402
				Update_1_0_to_1_1(handler, descriptor == null ? parent
403
						: descriptor, currentNode);
404
405
		}
406
		return VERSION_1_1;
407
	}
408
409
	public String Update_0_1_to_1_0(XMLDefaultHandler handler,
410
			MacroObjectDescriptor parent, Node rootNode) {
411
		NodeList nodeList = rootNode.getChildNodes();
412
		Node currentNode;
413
414
		/* Update the version of the macro */
415
		if (MacroConstants.MACRO_ELEMENT.equals(rootNode.getNodeName())) {
416
			NamedNodeMap rootAttributes = rootNode.getAttributes();
417
			Node versionAttribute = null;
418
			if (rootAttributes != null
419
					&& (versionAttribute = rootAttributes
420
							.getNamedItem(MacroConstants.VERSION_ATTRIBUTE)) != null) {
421
				versionAttribute.setNodeValue(VERSION_1_0);
422
			}
423
		}
424
425
		/* For each child */
426
		for (int i = 0, nodeListCount = nodeList.getLength(); i < nodeListCount; i++) {
427
			currentNode = nodeList.item(i);
428
			NamedNodeMap attributes = currentNode.getAttributes();
429
			if (attributes == null)
430
				continue;
431
432
			Node contextIdNode = attributes
433
					.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
434
			boolean isShell = MacroConstants.SHELL_ELEMENT.equals(currentNode
435
					.getNodeName());
436
			boolean isItem = MacroConstants.ITEM_ELEMENT.equals(currentNode
437
					.getNodeName())
438
					|| MacroConstants.SELECT_ITEM_ELEMENT.equals(currentNode
439
							.getNodeName());
440
			String idAttributeName = isShell ? MacroConstants.ID_ATTRIBUTE
441
					: isItem ? MacroConstants.PATH_ATTRIBUTE
442
							: MacroConstants.WIDGET_ID_ATTRIBUTE;
443
			Node widgetIdNode = attributes.getNamedItem(idAttributeName);
444
445
			String contextId = contextIdNode == null ? null : contextIdNode
446
					.getNodeValue();
447
			String widgetId = widgetIdNode == null ? null : widgetIdNode
448
					.getNodeValue();
449
450
			MacroObjectDescriptor uiObject = null;
451
			if (widgetId != null) {
452
				uiObject = objectMine.lookupMacroObjectDescriptor(
453
						isShell ? null : parent, contextId, widgetId, null);
454
				if (uiObject == null) {
455
					try {
456
						uiObject = new MacroObjectDescriptor(parent);
457
						((MacroObjectDescriptor) uiObject)
458
								.setContextId(contextId);
459
						((MacroObjectDescriptor) uiObject)
460
								.setDescriptive(attributes
461
										.getNamedItem(MacroConstants.DESCRIPTIVE_ATTRIBUTE) == null ? MacroConstants.OBJECT_ELEMENT
462
										: attributes
463
												.getNamedItem(
464
														MacroConstants.DESCRIPTIVE_ATTRIBUTE)
465
												.getNodeValue());
466
						((MacroObjectDescriptor) uiObject)
467
								.setWidgetId(widgetId);
468
						((MacroObjectDescriptor) uiObject).setObjectId(null);
469
						((MacroObjectDescriptor) uiObject)
470
								.setParent(isShell ? null : parent);
471
						objectMine
472
								.registerObject((MacroObjectDescriptor) uiObject);
473
					} catch (Exception e) {
474
						/* Shouldn't happen */
475
						e.printStackTrace();
476
					}
477
				}
478
479
				if (uiObject != null) {
480
					if (contextId != null)
481
						attributes
482
								.removeNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
483
					attributes.removeNamedItem(idAttributeName);
484
					Node refIdAttribute = handler.getDocument()
485
							.createAttribute(
486
									MacroConstants.REFERENCE_ID_ATTRIBUTE);
487
					refIdAttribute.setNodeValue(uiObject.getReferenceId());
488
					attributes.setNamedItem(refIdAttribute);
489
				}
490
			}
491
492
			if (currentNode.hasChildNodes())
493
				Update_0_1_to_1_0(handler,
494
						uiObject == null ? parent : uiObject, currentNode);
495
		}
496
497
		return VERSION_1_0;
498
	}
499
500
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/actions/AutoGUIPlayAction.java (-116 / +118 lines)
Lines 1-116 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
2
 * Copyright (c) 2006, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
7
 * 
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.actions;
11
package org.eclipse.tptp.test.auto.gui.internal.actions;
12
12
13
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
13
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase;
14
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
14
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
15
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
15
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
16
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
16
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
17
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
17
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm;
18
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
18
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
20
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner;
20
import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants;
21
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser;
21
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner;
22
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner.ITestRunnerDelegator;
22
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser;
23
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestCase;
23
import org.eclipse.tptp.test.auto.gui.internal.runner.AutoGUIRunner.ITestRunnerDelegator;
24
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestSuite;
24
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestCase;
25
import org.eclipse.ui.IWorkbench;
25
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestSuite;
26
import org.eclipse.ui.WorkbenchException;
26
import org.eclipse.ui.IWorkbench;
27
27
import org.eclipse.ui.WorkbenchException;
28
/**
28
29
 * Represents the play action
29
/**
30
 *
30
 * Represents the play action
31
 * 
31
 *
32
 * @author      Ali Mehregani
32
 * 
33
 * @author      Paul E. Slauenwhite
33
 * @author      Ali Mehregani
34
 * @version     March 5, 2008
34
 * @author      Paul E. Slauenwhite
35
 * @since       March 17, 2006
35
 * @author      Alexander Nyssen
36
 */
36
 * @version     March 5, 2008
37
public class AutoGUIPlayAction extends AutoGUITestCaseAction implements ITestRunnerDelegator
37
 * @since       March 17, 2006
38
{
38
 */
39
	/** The perspective id */
39
public class AutoGUIPlayAction extends AutoGUITestCaseAction implements ITestRunnerDelegator
40
	private String perspectiveId;
40
{
41
	
41
	/** The perspective id */
42
	/**
42
	private String perspectiveId;
43
	 * Constructor
43
	
44
	 */
44
	/**
45
	public AutoGUIPlayAction(AutoGUITestCasesForm testCaseForm)
45
	 * Constructor
46
	{
46
	 */
47
		super(testCaseForm, AutoGUIMessages.AUTO_GUI_EDT_QUICK_RUN_TOOL_TIP, AutoGUIImages.getInstance().getImageDescriptor("c", AutoGUIImages.PLAY));
47
	public AutoGUIPlayAction(AutoGUITestCasesForm testCaseForm)
48
		setDisabledImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("d", AutoGUIImages.PLAY));
48
	{
49
		setEnabled(false);
49
		super(testCaseForm, AutoGUIMessages.AUTO_GUI_EDT_QUICK_RUN_TOOL_TIP, AutoGUIImages.getInstance().getImageDescriptor("c", AutoGUIImages.PLAY));
50
	}
50
		setDisabledImageDescriptor(AutoGUIImages.getInstance().getImageDescriptor("d", AutoGUIImages.PLAY));
51
51
		setEnabled(false);
52
	
52
	}
53
	/**
53
54
	 * The quick launch button is been invoked
54
	
55
	 */
55
	/**
56
	public void run()
56
	 * The quick launch button is been invoked
57
	{	
57
	 */
58
		/* Change the state of the macro manager */
58
	public void run()
59
		MacroManager.getInstance().setGlobalState(MacroManager.QUICK_RUN_MODE);
59
	{	
60
		
60
		/* Change the state of the macro manager */
61
		/* This handler attempts to closely simulate the environment set before the 
61
		MacroManager.getInstance().setGlobalState(ModeConstants.QUICK_RUN_MODE);
62
		 * auto gui runner is executed.  This is important in order to make the quick
62
		
63
		 * launch mode closely similar to a launch of a test suite when a proper launch
63
		/* This handler attempts to closely simulate the environment set before the 
64
		 * configuration is used. */				
64
		 * auto gui runner is executed.  This is important in order to make the quick
65
		if (selectedTestCases == null || selectedTestCases.length <= 0)
65
		 * launch mode closely similar to a launch of a test suite when a proper launch
66
			return;
66
		 * configuration is used. */				
67
		
67
		if (selectedTestCases == null || selectedTestCases.length <= 0)
68
		/* Walk through each selected test case and create the appropriate environment */
68
			return;
69
		ExtendedScriptParser parser = new ExtendedScriptParser();
69
		
70
		ExtendedTestSuite root = parser.new ExtendedTestSuite();
70
		/* Walk through each selected test case and create the appropriate environment */
71
		for (int i = 0; i < selectedTestCases.length; i++)
71
		ExtendedScriptParser parser = new ExtendedScriptParser();
72
		{	
72
		ExtendedTestSuite root = parser.new ExtendedTestSuite();
73
			ITestCase testCaseEObject = selectedTestCases[i];
73
		for (int i = 0; i < selectedTestCases.length; i++)
74
			ExtendedTestCase testCase = parser.new ExtendedTestCase();
74
		{	
75
			
75
			ITestCase testCaseEObject = selectedTestCases[i];
76
			/* Set the id, name, description, starting point, and macro fragment of the test case */
76
			ExtendedTestCase testCase = parser.new ExtendedTestCase();
77
			testCase.setId(testCaseEObject.getId());
77
			
78
			testCase.setName(testCaseEObject.getName());
78
			/* Set the id, name, description, starting point, and macro fragment of the test case */
79
			testCase.setDescription(testCaseEObject.getDescription());
79
			testCase.setId(testCaseEObject.getId());
80
			
80
			testCase.setName(testCaseEObject.getName());
81
			testCase.addProperty(String.valueOf(GUITestCaseProperties.STARTING_PT), testCaseForm.getProperty(testCaseEObject, GUITestCaseProperties.STARTING_PT));
81
			testCase.setDescription(testCaseEObject.getDescription());
82
			testCase.addProperty(String.valueOf(GUITestCaseProperties.MACRO_FRAGMENT), testCaseForm.getProperty(testCaseEObject, GUITestCaseProperties.MACRO_FRAGMENT));
82
			
83
			testCase.setTestSuite(root);
83
			testCase.addProperty(String.valueOf(GUITestCaseProperties.STARTING_PT), testCaseForm.getProperty(testCaseEObject, GUITestCaseProperties.STARTING_PT));
84
		}
84
			testCase.addProperty(String.valueOf(GUITestCaseProperties.MACRO_FRAGMENT), testCaseForm.getProperty(testCaseEObject, GUITestCaseProperties.MACRO_FRAGMENT));
85
		
85
			testCase.setTestSuite(root);
86
		/* Store the perspective that we're in before switching it */
86
		}
87
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
87
		
88
		perspectiveId = workbench.getActiveWorkbenchWindow().getActivePage().getPerspective().getId();
88
		/* Store the perspective that we're in before switching it */
89
		
89
		IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
90
		AutoGUIRunner artificialRunner = new AutoGUIRunner();
90
		perspectiveId = workbench.getActiveWorkbenchWindow().getActivePage().getPerspective().getId();
91
		artificialRunner.runTestInCurrentContext(testCaseForm.getTestSuite(), root, this);					
91
		
92
	}
92
		AutoGUIRunner artificialRunner = new AutoGUIRunner();
93
93
		artificialRunner.runTestInCurrentContext(testCaseForm.getTestSuite(), root, this);					
94
94
	}
95
	public void finishedTestRun() 
95
96
	{				
96
97
		GuiPlugin.getDefault().getWorkbench().getDisplay().syncExec(new Runnable(){
97
	public void finishedTestRun() 
98
			public void run() 
98
	{				
99
			{			
99
		GuiPlugin.getDefault().getWorkbench().getDisplay().syncExec(new Runnable(){
100
				/* Change the state back to idle */
100
			public void run() 
101
				MacroManager.getInstance().setGlobalState(MacroManager.IDLE_MODE);
101
			{			
102
				
102
				/* Change the state back to idle */
103
				/* Re-store perspective */
103
				MacroManager.getInstance().setGlobalState(ModeConstants.IDLE_MODE);
104
				try
104
				
105
				{
105
				/* Re-store perspective */
106
					IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
106
				try
107
					workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow());
107
				{
108
				}
108
					IWorkbench workbench = GuiPlugin.getDefault().getWorkbench();
109
				catch (WorkbenchException e)
109
					workbench.showPerspective (perspectiveId, workbench.getActiveWorkbenchWindow());
110
				{
110
				}
111
					/* Not a big deal if we can't re-store the perspective */
111
				catch (WorkbenchException e)
112
				}						
112
				{
113
			}
113
					/* Not a big deal if we can't re-store the perspective */
114
		});
114
				}						
115
	}
115
			}
116
}
116
		});
117
	}
118
}
(-)META-INF/MANIFEST.MF (-2 / +10 lines)
Lines 2-8 Link Here
2
Bundle-ManifestVersion: 2
2
Bundle-ManifestVersion: 2
3
Bundle-Name: %pluginName
3
Bundle-Name: %pluginName
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui; singleton:=true
4
Bundle-SymbolicName: org.eclipse.tptp.test.auto.gui; singleton:=true
5
Bundle-Version: 4.4.0.qualifier
5
Bundle-Version: 4.5.0.qualifier
6
Bundle-ClassPath: autogui.jar
6
Bundle-ClassPath: autogui.jar
7
Bundle-Activator: org.eclipse.tptp.test.auto.gui.internal.GuiPlugin
7
Bundle-Activator: org.eclipse.tptp.test.auto.gui.internal.GuiPlugin
8
Bundle-Vendor: %providerName
8
Bundle-Vendor: %providerName
Lines 11-22 Link Here
11
 org.eclipse.tptp.test.auto.gui.internal.actions,
11
 org.eclipse.tptp.test.auto.gui.internal.actions,
12
 org.eclipse.tptp.test.auto.gui.internal.codegen,
12
 org.eclipse.tptp.test.auto.gui.internal.codegen,
13
 org.eclipse.tptp.test.auto.gui.internal.commands,
13
 org.eclipse.tptp.test.auto.gui.internal.commands,
14
 org.eclipse.tptp.test.auto.gui.internal.commands.factory,
14
 org.eclipse.tptp.test.auto.gui.internal.core,
15
 org.eclipse.tptp.test.auto.gui.internal.core,
15
 org.eclipse.tptp.test.auto.gui.internal.dialogs,
16
 org.eclipse.tptp.test.auto.gui.internal.dialogs,
16
 org.eclipse.tptp.test.auto.gui.internal.editor,
17
 org.eclipse.tptp.test.auto.gui.internal.editor,
17
 org.eclipse.tptp.test.auto.gui.internal.macro,
18
 org.eclipse.tptp.test.auto.gui.internal.macro,
18
 org.eclipse.tptp.test.auto.gui.internal.resolvers,
19
 org.eclipse.tptp.test.auto.gui.internal.macroobject,
20
 org.eclipse.tptp.test.auto.gui.internal.macroobject.mine,
21
 org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver,
19
 org.eclipse.tptp.test.auto.gui.internal.runner,
22
 org.eclipse.tptp.test.auto.gui.internal.runner,
23
 org.eclipse.tptp.test.auto.gui.internal.uiobject,
24
 org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver,
25
 org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate,
26
 org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport,
27
 org.eclipse.tptp.test.auto.gui.internal.util,
20
 org.eclipse.tptp.test.auto.gui.internal.wizard
28
 org.eclipse.tptp.test.auto.gui.internal.wizard
21
Require-Bundle: org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
29
Require-Bundle: org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
22
 org.junit;bundle-version="[3.2.0,4.0.0)",
30
 org.junit;bundle-version="[3.2.0,4.0.0)",
(-)src/org/eclipse/tptp/test/auto/gui/internal/dialogs/AutoGUITestControllerDialog.java (-883 / +926 lines)
Lines 1-883 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUITestControllerDialog.java,v 1.7 2008/04/18 14:51:21 dmorris Exp $
7
 * $Id: AutoGUITestControllerDialog.java,v 1.7 2008/04/18 14:51:21 dmorris Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.dialogs;
12
package org.eclipse.tptp.test.auto.gui.internal.dialogs;
13
13
14
import java.util.Vector;
14
import java.util.Vector;
15
15
16
import org.eclipse.hyades.ui.internal.util.GridDataUtil;
16
import org.eclipse.hyades.ui.internal.util.GridDataUtil;
17
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.events.DisposeEvent;
18
import org.eclipse.swt.events.DisposeEvent;
19
import org.eclipse.swt.events.DisposeListener;
19
import org.eclipse.swt.events.DisposeListener;
20
import org.eclipse.swt.events.KeyEvent;
20
import org.eclipse.swt.events.KeyEvent;
21
import org.eclipse.swt.events.KeyListener;
21
import org.eclipse.swt.events.KeyListener;
22
import org.eclipse.swt.events.MouseEvent;
22
import org.eclipse.swt.events.MouseEvent;
23
import org.eclipse.swt.events.MouseListener;
23
import org.eclipse.swt.events.MouseListener;
24
import org.eclipse.swt.events.MouseMoveListener;
24
import org.eclipse.swt.events.MouseMoveListener;
25
import org.eclipse.swt.events.SelectionEvent;
25
import org.eclipse.swt.events.SelectionEvent;
26
import org.eclipse.swt.events.SelectionListener;
26
import org.eclipse.swt.events.SelectionListener;
27
import org.eclipse.swt.graphics.Point;
27
import org.eclipse.swt.graphics.Point;
28
import org.eclipse.swt.layout.GridData;
28
import org.eclipse.swt.layout.GridData;
29
import org.eclipse.swt.layout.GridLayout;
29
import org.eclipse.swt.layout.GridLayout;
30
import org.eclipse.swt.widgets.Button;
30
import org.eclipse.swt.widgets.Button;
31
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.Control;
33
import org.eclipse.swt.widgets.Dialog;
33
import org.eclipse.swt.widgets.Dialog;
34
import org.eclipse.swt.widgets.Display;
34
import org.eclipse.swt.widgets.Display;
35
import org.eclipse.swt.widgets.Event;
35
import org.eclipse.swt.widgets.Event;
36
import org.eclipse.swt.widgets.Group;
36
import org.eclipse.swt.widgets.Group;
37
import org.eclipse.swt.widgets.Label;
37
import org.eclipse.swt.widgets.Label;
38
import org.eclipse.swt.widgets.List;
38
import org.eclipse.swt.widgets.List;
39
import org.eclipse.swt.widgets.Listener;
39
import org.eclipse.swt.widgets.Listener;
40
import org.eclipse.swt.widgets.Shell;
40
import org.eclipse.swt.widgets.Shell;
41
import org.eclipse.swt.widgets.Text;
41
import org.eclipse.swt.widgets.Text;
42
import org.eclipse.swt.widgets.ToolBar;
42
import org.eclipse.swt.widgets.ToolBar;
43
import org.eclipse.swt.widgets.ToolItem;
43
import org.eclipse.swt.widgets.ToolItem;
44
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
44
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
45
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
45
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
46
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
46
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
47
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
47
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
48
48
49
49
/**
50
/**
50
 * This dialog is displayed while the user is recording their macro. It is used
51
 * This dialog is displayed while the user is recording their macro.
51
 * to control the test case that is being recorded.
52
 * It is used to control the test case that is being recorded.
52
 * 
53
 * 
53
 * @author      Ali Mehregani
54
 * @author      Ali Mehregani
54
 * @author      Paul E. Slauenwhite
55
 * @author      Paul E. Slauenwhite
55
 * @author      Alexander Nyssen
56
 * @version     March 5, 2008
56
 * @version     March 5, 2008
57
 * @since       July 10, 2006
57
 * @since       July 10, 2006
58
 */
58
 */
59
public class AutoGUITestControllerDialog extends Dialog 
59
public class AutoGUITestControllerDialog extends Dialog implements
60
implements SelectionListener, MouseListener, MouseMoveListener, KeyListener, DisposeListener
60
		SelectionListener, MouseListener, MouseMoveListener, KeyListener,
61
{
61
		DisposeListener {
62
62
63
	private Shell sShell;  //  @jve:decl-index=0:visual-constraint="10,10"
63
	private Shell sShell; // @jve:decl-index=0:visual-constraint="10,10"
64
	private Composite toolbarComposite;
64
	private Composite toolbarComposite;
65
	private Group verificationGrp;
65
	private Group verificationGrp;
66
	private Group controlGrp;
66
	private Group controlGrp;
67
	private ToolBar toolBar;
67
	private ToolBar toolBar;
68
	private Text verificationName;
68
69
	private Button insertButton;
69
	/* verification group */
70
	private Label nameLbl;
70
	private Label verficationHookNameLabel;
71
	private ToolItem terminate;
71
	private Text verificationHookNameText;
72
	private ToolItem restart;
72
	private ToolBar verificationScopExtensionToolBar;
73
	private ToolItem positionBasedRecording;
73
	private ToolItem verificationScopeExtensionToolItem;
74
	private ToolItem recordWaitTime;
74
	private Button verificationHookInsertionButton;
75
	
75
76
	private Composite statusComposite;
76
	private ToolItem terminate;
77
	private Label statuslbl;
77
	private ToolItem restart;
78
	
78
	private ToolItem positionBasedRecording;
79
	/* Listener container */
79
	private ToolItem recordWaitTime;
80
	private Vector listenerBucket;
80
81
	
81
	private Composite statusComposite;
82
	/* Global coordinates of the shell - everything else is defined relative to this */
82
	private Label statuslbl;
83
	private Point shellBounds;
83
84
	
84
	/* Listener container */
85
	/* Indicates that the mouse button is pushed on the shell */ 
85
	private Vector listenerBucket;
86
	private boolean isMouseDown;
86
87
	
87
	/*
88
	/* The dialog is moved relative to this position */
88
	 * Global coordinates of the shell - everything else is defined relative to
89
	private Point originalPosition;
89
	 * this
90
	
90
	 */
91
	/* Indicates whether the control center shell is disposed or not */	
91
	private Point shellBounds;
92
	private boolean isShellDisposed;
92
93
	
93
	/* Indicates that the mouse button is pushed on the shell */
94
	/* The real parent that the dialog is suppose to have.  This may not necessarily be the actual parent
94
	private boolean isMouseDown;
95
	 * of the shell if it is forced to go to the background */
95
96
	private Shell realParent;
96
	/* The dialog is moved relative to this position */
97
	
97
	private Point originalPosition;
98
	/* The actual parent of the dialog.  This should always return the same result as getParent() */
98
99
	private Shell actualParent;
99
	/* Indicates whether the control center shell is disposed or not */
100
100
	private boolean isShellDisposed;
101
	/* The first control center dialog will have this set and the successive ones will not */
101
102
	private boolean isRoot;
102
	/*
103
	
103
	 * The real parent that the dialog is suppose to have. This may not
104
	/* The control root (set only if isRoot is false) */
104
	 * necessarily be the actual parent of the shell if it is forced to go to
105
	private AutoGUITestControllerDialog rootControl;
105
	 * the background
106
	
106
	 */
107
	/* The control delegator (maybe set only if isRoot is true) */
107
	private Shell realParent;
108
	private AutoGUITestControllerDialog delegator;
108
109
	
109
	/*
110
	/* The display listener that will be listening in for new active shells (set only if isRoot is true) */
110
	 * The actual parent of the dialog. This should always return the same
111
	private DisplayListener displayListener; 
111
	 * result as getParent()
112
	
112
	 */
113
	/* The last status of the control center dialog */
113
	private Shell actualParent;
114
	private String lastStatus;
114
115
	
115
	/*
116
	/* The last location of the control dialog box */
116
	 * The first control center dialog will have this set and the successive
117
	private Point lastLocation;
117
	 * ones will not
118
	
118
	 */
119
	/* Indicates whether position based should be on (should be set before shell is created)*/
119
	private boolean isRoot;
120
	private boolean positionBasedOn;
120
121
	
121
	/* The control root (set only if isRoot is false) */
122
	/* Indicates whether wait times should be recorded */
122
	private AutoGUITestControllerDialog rootControl;
123
	private boolean waitTimeOn;
123
124
	
124
	/* The control delegator (maybe set only if isRoot is true) */
125
	/* Stores the root's parent.  At any time this dialog will either have its parent set to 
125
	private AutoGUITestControllerDialog delegator;
126
	 * the root's parent or the active shell */
126
127
	private static Shell rootParent;
127
	/*
128
	
128
	 * The display listener that will be listening in for new active shells (set
129
	/* Indicates whether this dialog has purposely been sent to back */
129
	 * only if isRoot is true)
130
	private boolean forceToBack;
130
	 */
131
	
131
	private DisplayListener displayListener;
132
	/* Indicates whether the dialog is activated or not */
132
133
	private static boolean activated;
133
	/* The last status of the control center dialog */
134
	
134
	private String lastStatus;
135
	/* Event types */
135
136
	public final static byte TERMINATE 						= 0x01;
136
	/* The last location of the control dialog box */
137
	public final static byte VERIFICATION_HOOK_INSERT		= 0x02;
137
	private Point lastLocation;
138
	public final static byte RESTART						= 0x03;
138
139
	public final static byte POSITION_BASED					= 0x04;
139
	/*
140
	public final static byte WAIT_TIME						= 0x05;
140
	 * Indicates whether position based should be on (should be set before shell
141
	
141
	 * is created)
142
	private final static int DO_NOT_DISPOSE = 1020;
142
	 */
143
	
143
	private boolean positionBasedOn;
144
	/* At all times, there should only be one active dialog displayed to the user */
144
145
	private static AutoGUITestControllerDialog activeControlDialog;
145
	/* Indicates whether wait times should be recorded */
146
	
146
	private boolean waitTimeOn;
147
	/**
147
148
	 * This constructor is used to create dialogs that are opened when the active shell changes.
148
	/*
149
	 * 
149
	 * Indicates wether the generated verification hook method should contain a
150
	 * @param parentShell The parent shell
150
	 * second parameter for the UI object that was selected inside the context
151
	 * @param rootControl The control center that all the tasks will be delegated to.
151
	 */
152
	 */
152
	private boolean verificationScopeExtended;
153
	public AutoGUITestControllerDialog(Shell parentShell, AutoGUITestControllerDialog rootControl)
153
154
	{
154
	/*
155
		super(parentShell);
155
	 * Stores the root's parent. At any time this dialog will either have its
156
		isShellDisposed = false;
156
	 * parent set to the root's parent or the active shell
157
		realParent = parentShell;
157
	 */
158
		actualParent = parentShell;
158
	private static Shell rootParent;
159
		isRoot = false;
159
160
		this.rootControl = rootControl;
160
	/* Indicates whether this dialog has purposely been sent to back */
161
		this.positionBasedOn = false;
161
	private boolean forceToBack;
162
		
162
163
	}
163
	/* Indicates whether the dialog is activated or not */
164
	
164
	private static boolean activated;
165
	
165
166
	public AutoGUITestControllerDialog(Shell parent)
166
	/* Event types */
167
	{
167
	public final static byte TERMINATE = 0x01;
168
		super(parent);
168
	public final static byte RESTART = 0x02;
169
		isShellDisposed = false;
169
	public final static byte POSITION_BASED = 0x03;
170
		realParent = parent;
170
	public final static byte WAIT_TIME = 0x04;
171
		actualParent = parent;
171
	public final static byte VERIFICATION_HOOK_INSERT = 0x05;
172
		isRoot = true;
172
173
		activated = true;
173
	private final static int DO_NOT_DISPOSE = 1020;
174
	}
174
175
	
175
	/*
176
	
176
	 * At all times, there should only be one active dialog displayed to the
177
	public void openDialog()
177
	 * user
178
	{
178
	 */
179
		openDialog(null);
179
	private static AutoGUITestControllerDialog activeControlDialog;
180
	}
180
181
	
181
	/**
182
	/**
182
	 * This constructor is used to create dialogs that are opened when the
183
	 * Equivalent to openDialog (true)
183
	 * active shell changes.
184
	 */
184
	 * 
185
	public void openDialog(final Shell activeShell)
185
	 * @param parentShell
186
	{
186
	 *            The parent shell
187
		shellBounds = new Point (317, 105);
187
	 * @param rootControl
188
		originalPosition = new Point(0, 0);
188
	 *            The control center that all the tasks will be delegated to.
189
		sShell = new Shell(getParent(), SWT.MODELESS); 
189
	 */
190
		sShell.setText(AutoGUIMessages.AUTO_GUI_CONTROL_DIALOG_TITLE);
190
	public AutoGUITestControllerDialog(Shell parentShell,
191
		sShell.setLayout(new GridLayout());
191
			AutoGUITestControllerDialog rootControl) {
192
		sShell.setSize(shellBounds);
192
		super(parentShell);
193
		if (lastLocation != null)
193
		isShellDisposed = false;
194
			sShell.setLocation(lastLocation);
194
		realParent = parentShell;
195
		sShell.addMouseListener(this);
195
		actualParent = parentShell;
196
		sShell.addMouseMoveListener(this);
196
		isRoot = false;
197
		sShell.addDisposeListener(this);
197
		this.rootControl = rootControl;
198
		
198
		this.positionBasedOn = false;
199
		/* We would like the macro recorder to ignore this shell */
199
200
		sShell.setData(MacroManager.IGNORE, Boolean.TRUE);
200
	}
201
		
201
202
		sShell.setFocus();		
202
	public AutoGUITestControllerDialog(Shell parent) {
203
		createToolbarComposite();
203
		super(parent);
204
		createStatusComposite();
204
		isShellDisposed = false;
205
				
205
		realParent = parent;
206
		ActivationListener activationListener = null;
206
		actualParent = parent;
207
		/* We need to always stay on top of every shell */
207
		isRoot = true;
208
		if (isRoot)
208
		activated = true;
209
		{
209
	}
210
			rootParent = getParent();
210
211
			displayListener = new DisplayListener();
211
	public void openDialog() {
212
			Display.getCurrent().addFilter(SWT.Activate, displayListener);
212
		openDialog(null);
213
		}
213
	}
214
		
214
215
		else
215
	/**
216
		{
216
	 * Equivalent to openDialog (true)
217
			/* Defect #113543: Under the RedHat linux environment, if a modeless dialog is opened with an application modal dialog as its
217
	 */
218
			 * parent, the modality of the opened dialog will be restricted to application modal (blocking the parent dialog).  We'll
218
	public void openDialog(final Shell activeShell) {
219
			 * need to dispose and open the control center dialog based on activation and deactivation events.  This is very expensive and
219
		shellBounds = new Point(317, 105);
220
			 * it is only performed on non-windows environments.
220
		originalPosition = new Point(0, 0);
221
			 */ 
221
		sShell = new Shell(getParent(), SWT.MODELESS);
222
			final String WINDOWS_OS = "windows";
222
		sShell.setText(AutoGUIMessages.AUTO_GUI_CONTROL_DIALOG_TITLE);
223
			String platformOS = System.getProperty("os.name");
223
		sShell.setLayout(new GridLayout());
224
			 
224
		sShell.setSize(shellBounds);
225
			if (platformOS == null || platformOS.toLowerCase().indexOf(WINDOWS_OS) == -1)
225
		if (lastLocation != null)
226
			{
226
			sShell.setLocation(lastLocation);
227
				activationListener = new ActivationListener(false);
227
		sShell.addMouseListener(this);
228
			}
228
		sShell.addMouseMoveListener(this);
229
		}
229
		sShell.addDisposeListener(this);
230
		
230
231
		/* Open the dialog */
231
		/* We would like the macro recorder to ignore this shell */
232
		activeControlDialog = this;
232
		sShell.setData(MacroManager.IGNORE, Boolean.TRUE);
233
 		sShell.open(); 		
233
234
 		
234
		sShell.setFocus();
235
 		if (activationListener != null)
235
		createToolbarComposite();
236
 		{
236
		createStatusComposite();
237
 			sShell.addListener(SWT.Activate, activationListener);
237
238
 			sShell.addListener(SWT.Deactivate, activationListener); 			
238
		ActivationListener activationListener = null;
239
 			
239
		/* We need to always stay on top of every shell */
240
 			final ActivationListener finalActivationListener = activationListener;
240
		if (isRoot) {
241
 			GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(100, new Runnable(){
241
			rootParent = getParent();
242
242
			displayListener = new DisplayListener();
243
				public void run() {
243
			Display.getCurrent().addFilter(SWT.Activate, displayListener);
244
					if (activeShell != null && !activeShell.isDisposed())
244
		}
245
						activeShell.setActive();
245
246
						
246
		else {
247
					finalActivationListener.setEnable(true);
247
			/*
248
					
248
			 * Defect #113543: Under the RedHat linux environment, if a modeless
249
				}});
249
			 * dialog is opened with an application modal dialog as its parent,
250
 		}
250
			 * the modality of the opened dialog will be restricted to
251
 		
251
			 * application modal (blocking the parent dialog). We'll need to
252
 		
252
			 * dispose and open the control center dialog based on activation
253
253
			 * and deactivation events. This is very expensive and it is only
254
	}
254
			 * performed on non-windows environments.
255
	
255
			 */
256
	
256
			final String WINDOWS_OS = "windows";
257
	/**
257
			String platformOS = System.getProperty("os.name");
258
	 * This method initializes toolbarComposite	
258
259
	 *
259
			if (platformOS == null
260
	 */    
260
					|| platformOS.toLowerCase().indexOf(WINDOWS_OS) == -1) {
261
	private void createToolbarComposite() {
261
				activationListener = new ActivationListener(false);
262
		GridLayout gridLayout = new GridLayout();
262
			}
263
		gridLayout.numColumns = 2;
263
		}
264
		toolbarComposite = new Composite(sShell, SWT.NONE);		   
264
265
		createControlGrp();
265
		/* Open the dialog */
266
		createVerificationGrp();
266
		activeControlDialog = this;
267
		toolbarComposite.setLayoutData(GridDataUtil.createHorizontalFill());
267
		sShell.open();
268
		toolbarComposite.addMouseListener(this);
268
269
		toolbarComposite.addMouseMoveListener(this);
269
		if (activationListener != null) {
270
		toolbarComposite.setLayout(gridLayout);		
270
			sShell.addListener(SWT.Activate, activationListener);
271
	}
271
			sShell.addListener(SWT.Deactivate, activationListener);
272
	
272
273
	private void createStatusComposite()
273
			final ActivationListener finalActivationListener = activationListener;
274
	{
274
			GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(100,
275
		GridData gd = new GridData();
275
					new Runnable() {
276
		gd.horizontalAlignment = SWT.CENTER;
276
277
		
277
						public void run() {
278
		GridLayout gridLayout = new GridLayout();
278
							if (activeShell != null
279
		statusComposite = new Composite (sShell, SWT.NONE);		   
279
									&& !activeShell.isDisposed())
280
		statusComposite.setLayout(gridLayout);
280
								activeShell.setActive();
281
		statusComposite.setLayoutData(gd);
281
282
		statusComposite.addMouseListener(this);
282
							finalActivationListener.setEnable(true);
283
		statusComposite.addMouseMoveListener(this);
283
284
		
284
						}
285
		GridData gd2 = new GridData();
285
					});
286
		gd2.horizontalAlignment = SWT.CENTER;
286
		}
287
		gd2.grabExcessHorizontalSpace = true;
287
288
		gd2.widthHint = (int)(shellBounds.x * 0.8);
288
	}
289
		statuslbl = new Label (statusComposite, SWT.NONE);
289
290
		statuslbl.setAlignment(SWT.CENTER);
290
	/**
291
		statuslbl.setLayoutData(gd2);
291
	 * This method initializes toolbarComposite
292
		statuslbl.addMouseListener(this);
292
	 * 
293
		statuslbl.addMouseMoveListener(this);
293
	 */
294
	}
294
	private void createToolbarComposite() {
295
	
295
		GridLayout gridLayout = new GridLayout();
296
	
296
		gridLayout.numColumns = 2;
297
	/**
297
		toolbarComposite = new Composite(sShell, SWT.NONE);
298
	 * This method initializes verificationGrp	
298
		createControlGrp();
299
	 *
299
		createVerificationGrp();
300
	 */    
300
		toolbarComposite.setLayoutData(GridDataUtil.createHorizontalFill());
301
	private void createVerificationGrp() {
301
		toolbarComposite.addMouseListener(this);
302
		GridLayout gridLayout1 = new GridLayout();
302
		toolbarComposite.addMouseMoveListener(this);
303
		gridLayout1.numColumns = 3;
303
		toolbarComposite.setLayout(gridLayout);
304
		verificationGrp = new Group(toolbarComposite, SWT.NONE);		   
304
	}
305
		verificationGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_HOOK);
305
306
		verificationGrp.setLayout(gridLayout1);
306
	private void createStatusComposite() {
307
		verificationGrp.setLayoutData (GridDataUtil.createHorizontalFill());
307
		GridData gd = new GridData();
308
		verificationGrp.addMouseListener(this);
308
		gd.horizontalAlignment = SWT.CENTER;
309
		verificationGrp.addMouseMoveListener(this);
309
310
		nameLbl = new Label(verificationGrp, SWT.NONE);
310
		GridLayout gridLayout = new GridLayout();
311
		nameLbl.setText(AutoGUIMessages.AUTO_GUI_NEW_DIALOG_NAME);
311
		statusComposite = new Composite(sShell, SWT.NONE);
312
		nameLbl.addMouseListener(this);
312
		statusComposite.setLayout(gridLayout);
313
		nameLbl.addMouseMoveListener(this);
313
		statusComposite.setLayoutData(gd);
314
		verificationName = new Text(verificationGrp, SWT.BORDER);
314
		statusComposite.addMouseListener(this);
315
		verificationName.setLayoutData (GridDataUtil.createHorizontalFill());
315
		statusComposite.addMouseMoveListener(this);
316
		verificationName.addKeyListener(this);
316
317
		insertButton = new Button(verificationGrp, SWT.NONE);
317
		GridData gd2 = new GridData();
318
		insertButton.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INSERT);
318
		gd2.horizontalAlignment = SWT.CENTER;
319
		insertButton.addSelectionListener(this);
319
		gd2.grabExcessHorizontalSpace = true;
320
		insertButton.setEnabled(false);
320
		gd2.widthHint = (int) (shellBounds.x * 0.8);
321
		sShell.setDefaultButton(insertButton);
321
		statuslbl = new Label(statusComposite, SWT.NONE);
322
	}
322
		statuslbl.setAlignment(SWT.CENTER);
323
	/**
323
		statuslbl.setLayoutData(gd2);
324
	 * This method initializes controlGrp	
324
		statuslbl.addMouseListener(this);
325
	 *
325
		statuslbl.addMouseMoveListener(this);
326
	 */    
326
	}
327
	private void createControlGrp() {
327
328
		controlGrp = new Group(toolbarComposite, SWT.NONE);		   
328
	/**
329
		controlGrp.setLayout(new GridLayout());
329
	 * This method initializes verificationGrp
330
		controlGrp.addMouseListener(this);
330
	 * 
331
		controlGrp.addMouseMoveListener(this);
331
	 */
332
		createToolBar();
332
	private void createVerificationGrp() {
333
		controlGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_CONT);
333
		GridLayout gridLayout1 = new GridLayout();
334
	}
334
		gridLayout1.numColumns = 4;
335
	/**
335
		verificationGrp = new Group(toolbarComposite, SWT.NONE);
336
	 * This method initializes toolBar	
336
		verificationGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_HOOK);
337
	 *
337
		verificationGrp.setLayout(gridLayout1);
338
	 */    
338
		verificationGrp.setLayoutData(GridDataUtil.createHorizontalFill());
339
	private void createToolBar() {
339
		verificationGrp.addMouseListener(this);
340
		GridData gridData = new GridData();
340
		verificationGrp.addMouseMoveListener(this);
341
		gridData.horizontalAlignment = SWT.CENTER;
341
342
		gridData.grabExcessHorizontalSpace = true;
342
		verficationHookNameLabel = new Label(verificationGrp, SWT.NONE);
343
		toolBar = new ToolBar(controlGrp, SWT.NONE);		   
343
		verficationHookNameLabel
344
		
344
				.setText(AutoGUIMessages.AUTO_GUI_NEW_DIALOG_NAME);
345
		/* The terminate button */
345
		verficationHookNameLabel.addMouseListener(this);
346
		terminate = new ToolItem(toolBar, SWT.PUSH);
346
		verficationHookNameLabel.addMouseMoveListener(this);
347
		terminate.setImage(AutoGUIImages.getInstance().getImage("e", AutoGUIImages.TERMINATE));
347
348
		terminate.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_TERMINATE);
348
		verificationHookNameText = new Text(verificationGrp, SWT.BORDER);
349
		terminate.addSelectionListener(this);
349
		verificationHookNameText.setLayoutData(GridDataUtil
350
		
350
				.createHorizontalFill());
351
		/* The restart button */
351
		verificationHookNameText.addKeyListener(this);
352
		restart = new ToolItem(toolBar, SWT.PUSH);
352
353
		restart.setImage(AutoGUIImages.getInstance().getImage(AutoGUIImages.RESTART));
353
		verificationScopExtensionToolBar = new ToolBar(verificationGrp,
354
		restart.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART);
354
				SWT.NONE);
355
		restart.addSelectionListener(this);
355
		verificationScopeExtensionToolItem = new ToolItem(
356
		
356
				verificationScopExtensionToolBar, SWT.CHECK);
357
		/* A separator */
357
		verificationScopeExtensionToolItem.setImage(AutoGUIImages.getInstance()
358
		ToolItem sep = new ToolItem(toolBar, SWT.SEPARATOR);
358
				.getImage("e", AutoGUIImages.VERIFICATION_HOOK));
359
		sep.setText("");
359
		verificationScopeExtensionToolItem
360
		
360
				.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INCLUDE_UI_OBJECT);
361
		/* The position-based recording button */
361
		verificationScopeExtensionToolItem
362
		positionBasedRecording = new ToolItem (toolBar, SWT.CHECK);
362
				.setSelection(verificationScopeExtended);
363
		positionBasedRecording.setImage(AutoGUIImages.getInstance().getImage("e", AutoGUIImages.POSITION_BASED));
363
		verificationScopeExtensionToolItem.addSelectionListener(this);
364
		positionBasedRecording.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_POSITION_BASED);
364
		verificationScopeExtensionToolItem.setEnabled(false);
365
		positionBasedRecording.setSelection(positionBasedOn);
365
366
		positionBasedRecording.addSelectionListener(this);
366
		verificationHookInsertionButton = new Button(verificationGrp, SWT.NONE);
367
				
367
		verificationHookInsertionButton
368
		/* The wait time toggle buttong */		
368
				.setText(AutoGUIMessages.AUTO_GUI_CONTROL_VER_INSERT);
369
		recordWaitTime = new ToolItem (toolBar, SWT.CHECK);
369
		verificationHookInsertionButton.addSelectionListener(this);
370
		recordWaitTime .setImage(AutoGUIImages.getInstance().getImage(AutoGUIImages.WAIT_TIME));
370
		verificationHookInsertionButton.setEnabled(false);
371
		recordWaitTime.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_WAIT_TIME);
371
		sShell.setDefaultButton(verificationHookInsertionButton);
372
		recordWaitTime.setSelection(waitTimeOn);
372
	}
373
		recordWaitTime.addSelectionListener(this);
373
374
		
374
	/**
375
		
375
	 * This method initializes controlGrp
376
		toolBar.setLayoutData(gridData);
376
	 * 
377
	}
377
	 */
378
	
378
	private void createControlGrp() {
379
	
379
		controlGrp = new Group(toolbarComposite, SWT.NONE);
380
	/**
380
		controlGrp.setLayout(new GridLayout());
381
	 * Used to register listeners with the control dialog box
381
		controlGrp.addMouseListener(this);
382
	 * See event types for the type of events that the listener
382
		controlGrp.addMouseMoveListener(this);
383
	 * will be invoked with.
383
		createToolBar();
384
	 */
384
		controlGrp.setText(AutoGUIMessages.AUTO_GUI_CONTROL_CONT);
385
	public void registerListener (AutoGUIControllerListener listener)
385
	}
386
	{
386
387
		if (listenerBucket == null)
387
	/**
388
			listenerBucket = new Vector();
388
	 * This method initializes toolBar
389
		if (listener != null && !listenerBucket.contains(listener))
389
	 * 
390
			listenerBucket.add(listener);
390
	 */
391
	}
391
	private void createToolBar() {
392
	
392
		GridData gridData = new GridData();
393
	public void terminate()
393
		gridData.horizontalAlignment = SWT.CENTER;
394
	{
394
		gridData.grabExcessHorizontalSpace = true;
395
		if (rootControl != null)
395
		toolBar = new ToolBar(controlGrp, SWT.NONE);
396
		{
396
397
			rootControl.terminate();
397
		/* The terminate button */
398
		}
398
		terminate = new ToolItem(toolBar, SWT.PUSH);
399
		else if (isRoot)
399
		terminate.setImage(AutoGUIImages.getInstance().getImage("e",
400
		{
400
				AutoGUIImages.TERMINATE));
401
			Display.getCurrent().removeFilter(SWT.Activate, displayListener);
401
		terminate.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_TERMINATE);
402
			activeControlDialog.dispose();
402
		terminate.addSelectionListener(this);
403
			notifyListeners (TERMINATE, null);
403
404
		}
404
		/* The restart button */
405
405
		restart = new ToolItem(toolBar, SWT.PUSH);
406
	}
406
		restart
407
407
				.setImage(AutoGUIImages.getInstance()
408
	public void widgetSelected(SelectionEvent e)
408
						.getImage(AutoGUIImages.RESTART));
409
	{
409
		restart.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_RESTART);
410
		byte eventType = 0;
410
		restart.addSelectionListener(this);
411
		
411
412
		/* Determine the type of event */
412
		/* A separator */
413
		if (e.widget == terminate)
413
		ToolItem sep = new ToolItem(toolBar, SWT.SEPARATOR);
414
		{
414
		sep.setText("");
415
			eventType = TERMINATE;
415
416
			notifyListeners (eventType, null);			
416
		/* The position-based recording button */
417
			
417
		positionBasedRecording = new ToolItem(toolBar, SWT.CHECK);
418
			if (e.detail != DO_NOT_DISPOSE)
418
		positionBasedRecording.setImage(AutoGUIImages.getInstance().getImage("e",
419
				dispose();
419
				AutoGUIImages.POSITION_BASED));
420
			
420
		positionBasedRecording
421
			return;
421
				.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_POSITION_BASED);
422
		}
422
		positionBasedRecording.setSelection(positionBasedOn);
423
		/* This is the verification insertion event */
423
		positionBasedRecording.addSelectionListener(this);
424
		else if (e.widget == insertButton)
424
425
			eventType = VERIFICATION_HOOK_INSERT;
425
		/* The wait time toggle buttong */
426
		else if (e.widget == restart)
426
		recordWaitTime = new ToolItem(toolBar, SWT.CHECK);
427
			eventType = RESTART;
427
		recordWaitTime.setImage(AutoGUIImages.getInstance()
428
		else if (e.widget == positionBasedRecording)
428
				.getImage(AutoGUIImages.WAIT_TIME));
429
		{
429
		recordWaitTime
430
			positionBasedOn = ((ToolItem)e.widget).getSelection();
430
				.setToolTipText(AutoGUIMessages.AUTO_GUI_CONTROL_WAIT_TIME);
431
			eventType = POSITION_BASED;
431
		recordWaitTime.setSelection(waitTimeOn);
432
		}
432
		recordWaitTime.addSelectionListener(this);
433
		else if (e.widget == recordWaitTime)
433
434
		{
434
		toolBar.setLayoutData(gridData);
435
			waitTimeOn = ((ToolItem)e.widget).getSelection();
435
	}
436
			eventType = WAIT_TIME;
436
437
		}
437
	/**
438
		
438
	 * Used to register listeners with the control dialog box See event types
439
		if (eventType != 0)
439
	 * for the type of events that the listener will be invoked with.
440
			notifyListeners (eventType, verificationName.getText());
440
	 */
441
	}
441
	public void registerListener(AutoGUIControllerListener listener) {
442
	
442
		if (listenerBucket == null)
443
	
443
			listenerBucket = new Vector();
444
	public void widgetDisposed(DisposeEvent e) 
444
		if (listener != null && !listenerBucket.contains(listener))
445
	{
445
			listenerBucket.add(listener);
446
		if (!isShellDisposed && isRoot)
446
	}
447
		{
447
448
			isShellDisposed = true;
448
	public void terminate() {
449
			
449
		if (rootControl != null) {
450
			/* The shell is been disposed.  Simulate a termination */
450
			rootControl.terminate();
451
			Event event = new Event();
451
		} else if (isRoot) {
452
			event.widget = terminate;
452
			Display.getCurrent().removeFilter(SWT.Activate, displayListener);
453
			event.detail = DO_NOT_DISPOSE;
453
			activeControlDialog.dispose();
454
			widgetSelected(new SelectionEvent(event));			
454
			notifyListeners(TERMINATE, null);
455
		}
455
		}
456
		
456
457
	}	
457
	}
458
	
458
459
	/**
459
	public void widgetSelected(SelectionEvent e) {
460
	 * A helper method used to notify the registered listeners
460
		byte eventType = 0;
461
	 * 
461
462
	 * @param eventType The type of event that caused this invokation
462
		/* Determine the type of event */
463
	 */
463
		if (e.widget == terminate) {
464
	protected void notifyListeners (byte eventType, Object value)
464
			eventType = TERMINATE;
465
	{
465
			notifyListeners(eventType, null);
466
		
466
467
		/* If we're not the root control center, then we're expected to delegate the tasks */
467
			if (e.detail != DO_NOT_DISPOSE)
468
		if (!isRoot)
468
				dispose();
469
		{
469
470
			rootControl.notifyListeners(eventType, value);			
470
			return;
471
		}
471
		}
472
		else
472
		/* This is the verification insertion event */
473
		{
473
		else if (e.widget == verificationHookInsertionButton)
474
			/* Remove the listener if we were terminated */
474
			eventType = VERIFICATION_HOOK_INSERT;
475
			if (eventType == TERMINATE)
475
		else if (e.widget == verificationScopeExtensionToolItem) {
476
				Display.getCurrent().removeFilter(SWT.Activate, displayListener);
476
			verificationScopeExtended = ((ToolItem) e.widget).getSelection();
477
			
477
		} else if (e.widget == restart)
478
			/* Update appropriate fields if delegator updated the position-based or wait-time-recording options */
478
			eventType = RESTART;
479
			if (delegator != null)
479
		else if (e.widget == positionBasedRecording) {
480
			{
480
			positionBasedOn = ((ToolItem) e.widget).getSelection();
481
				if (eventType == POSITION_BASED)
481
			eventType = POSITION_BASED;
482
					positionBasedOn = delegator.isPositionBasedOn();
482
		} else if (e.widget == recordWaitTime) {
483
				else if (eventType == WAIT_TIME)
483
			waitTimeOn = ((ToolItem) e.widget).getSelection();
484
					waitTimeOn = delegator.isWaitTimeOn();
484
			eventType = WAIT_TIME;
485
			}
485
		}
486
			
486
487
			/* Start notifying the listeners */
487
		if (eventType != 0)
488
			int size = listenerBucket.size();
488
			notifyListeners(eventType, verificationHookNameText.getText());
489
			for (int i = 0; i < size; i++)
489
	}
490
			{
490
491
				((AutoGUIControllerListener)listenerBucket.get(i)).handleEvent(eventType, value);
491
	public void widgetDisposed(DisposeEvent e) {
492
			}
492
		if (!isShellDisposed && isRoot) {
493
		}
493
			isShellDisposed = true;
494
	}
494
495
495
			/* The shell is been disposed. Simulate a termination */
496
496
			Event event = new Event();
497
	public void widgetDefaultSelected(SelectionEvent e)
497
			event.widget = terminate;
498
	{
498
			event.detail = DO_NOT_DISPOSE;
499
		/* Doesn't need to be implemented */		
499
			widgetSelected(new SelectionEvent(event));
500
	}
500
		}
501
	
501
502
	
502
	}
503
	/**
503
504
	 * A chance to clean up after our self 
504
	/**
505
	 */
505
	 * A helper method used to notify the registered listeners
506
	public void dispose()
506
	 * 
507
	{		
507
	 * @param eventType
508
		isShellDisposed = true;		
508
	 *            The type of event that caused this invokation
509
		if (sShell != null && !sShell.isDisposed())
509
	 */
510
		{
510
	protected void notifyListeners(byte eventType, Object value) {
511
			sShell.close();
511
512
			toolBar.dispose();
512
		/*
513
			verificationName.dispose();
513
		 * If we're not the root control center, then we're expected to delegate
514
			insertButton.dispose();
514
		 * the tasks
515
			nameLbl.dispose();
515
		 */
516
			terminate.dispose();
516
		if (!isRoot) {
517
			restart.dispose();
517
			rootControl.notifyListeners(eventType, value);
518
			positionBasedRecording.dispose();
518
		} else {
519
			verificationGrp.dispose();
519
			/* Remove the listener if we were terminated */
520
			controlGrp.dispose();
520
			if (eventType == TERMINATE)
521
			toolbarComposite.dispose();
521
				Display.getCurrent()
522
			sShell.dispose();  //  @jve:decl-index=0:visual-constraint="10,10"
522
						.removeFilter(SWT.Activate, displayListener);
523
		}
523
524
		
524
			/*
525
		toolBar = null;
525
			 * Update appropriate fields if delegator updated the position-based
526
		verificationName = null;
526
			 * or wait-time-recording options
527
		insertButton = null;
527
			 */
528
		nameLbl = null;
528
			if (delegator != null) {
529
		terminate = null; 
529
				if (eventType == POSITION_BASED)
530
		verificationGrp = null;
530
					positionBasedOn = delegator.isPositionBasedOn();
531
		controlGrp = null;
531
				else if (eventType == WAIT_TIME)
532
		toolbarComposite = null;
532
					waitTimeOn = delegator.isWaitTimeOn();
533
		sShell = null;  //  @jve:decl-index=0:visual-constraint="10,10"
533
			}
534
		
534
535
		shellBounds = null;
535
			/* Start notifying the listeners */
536
		originalPosition = null;
536
			int size = listenerBucket.size();
537
	}
537
			for (int i = 0; i < size; i++) {
538
	
538
				((AutoGUIControllerListener) listenerBucket.get(i))
539
	public void mouseDoubleClick(MouseEvent e)
539
						.handleEvent(eventType, value);
540
	{
540
			}
541
		/* Doesn't need to be implemented */
541
		}
542
	}
542
	}
543
	
543
544
	public void mouseDown(MouseEvent e)
544
	public void widgetDefaultSelected(SelectionEvent e) {
545
	{
545
		/* Doesn't need to be implemented */
546
		isMouseDown = true;
546
	}
547
		originalPosition.x = e.x;
547
548
		originalPosition.y = e.y;
548
	/**
549
	}
549
	 * A chance to clean up after our self
550
550
	 */
551
551
	public void dispose() {
552
	public void mouseUp(MouseEvent e)
552
		isShellDisposed = true;
553
	{
553
		if (sShell != null && !sShell.isDisposed()) {
554
		isMouseDown = false;
554
			sShell.close();
555
	}
555
			toolBar.dispose();
556
556
			verificationHookNameText.dispose();
557
557
			verificationScopeExtensionToolItem.dispose();
558
	/**
558
			verificationHookInsertionButton.dispose();
559
	 * Move the dialog box when the user clicks on the shell and moves the cursor
559
			verficationHookNameLabel.dispose();
560
	 */
560
			terminate.dispose();
561
	public void mouseMove(MouseEvent e)
561
			restart.dispose();
562
	{
562
			positionBasedRecording.dispose();
563
		if (isMouseDown)
563
			verificationGrp.dispose();
564
		{
564
			controlGrp.dispose();
565
			int xMove = e.x - originalPosition.x;
565
			toolbarComposite.dispose();
566
			int yMove = e.y - originalPosition.y;
566
			sShell.dispose(); // @jve:decl-index=0:visual-constraint="10,10"
567
			
567
		}
568
			Point currentLocation = sShell.getLocation();
568
569
			sShell.setLocation(currentLocation.x + xMove, currentLocation.y + yMove);
569
		toolBar = null;
570
			lastLocation = sShell.getLocation();
570
		verificationHookNameText = null;
571
		}		
571
		verificationScopeExtensionToolItem = null;
572
	}
572
		verificationHookInsertionButton = null;
573
573
		verficationHookNameLabel = null;
574
	/**
574
		terminate = null;
575
	 * Updates the status of the control dialog center
575
		verificationGrp = null;
576
	 * 
576
		controlGrp = null;
577
	 * @param status The status to be printed
577
		toolbarComposite = null;
578
	 */
578
		sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
579
	public void setStatus (String status)
579
580
	{	
580
		shellBounds = null;
581
		
581
		originalPosition = null;
582
		/* The delegator has to handle this (if one exists) */
582
	}
583
		if (isRoot && delegator != null && !delegator.isShellDisposed)
583
584
		{
584
	public void mouseDoubleClick(MouseEvent e) {
585
			delegator.setStatus(status);
585
		/* Doesn't need to be implemented */
586
			return;
586
	}
587
		}
587
588
		//added for defect 173451 to ensure that in case where the widget is disposed
588
	public void mouseDown(MouseEvent e) {
589
		// we switch to the correct reference (for Linux platform)
589
		isMouseDown = true;
590
		// Liz Dancy
590
		originalPosition.x = e.x;
591
		else if (statuslbl.isDisposed() && delegator.isShellDisposed){
591
		originalPosition.y = e.y;
592
			
592
	}
593
			this.updateDelegator(this.realParent, this.realParent);
593
594
			statuslbl = this.delegator.statuslbl;
594
	public void mouseUp(MouseEvent e) {
595
		}	
595
		isMouseDown = false;
596
		if (status == null)
596
	}
597
			return;
597
598
		
598
	/**
599
		lastStatus = status;
599
	 * Move the dialog box when the user clicks on the shell and moves the
600
		String finalStatus = AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BASE + status;
600
	 * cursor
601
		boolean toolong = false;
601
	 */
602
		if (finalStatus.length() > 30)
602
	public void mouseMove(MouseEvent e) {
603
			toolong = true;
603
		if (isMouseDown) {
604
		
604
			int xMove = e.x - originalPosition.x;
605
	
605
			int yMove = e.y - originalPosition.y;
606
		statuslbl.setToolTipText(finalStatus);
606
607
		if (toolong)
607
			Point currentLocation = sShell.getLocation();
608
			finalStatus = finalStatus.substring (0, 30) + "...";
608
			sShell.setLocation(currentLocation.x + xMove, currentLocation.y
609
			
609
					+ yMove);
610
		statuslbl.setText (finalStatus);
610
			lastLocation = sShell.getLocation();
611
	}
611
		}
612
	
612
	}
613
	public String getLastStatus()
613
614
	{
614
	/**
615
		if (isRoot && delegator != null)
615
	 * Updates the status of the control dialog center
616
			return delegator.getLastStatus();
616
	 * 
617
		return lastStatus;
617
	 * @param status
618
	}
618
	 *            The status to be printed
619
	
619
	 */
620
	
620
	public void setStatus(String status) {
621
	/**
621
622
	 * A primitive listener class
622
		/* The delegator has to handle this (if one exists) */
623
	 */
623
		if (isRoot && delegator != null && !delegator.isShellDisposed) {
624
	public interface AutoGUIControllerListener
624
			delegator.setStatus(status);
625
	{
625
			return;
626
		/**
626
		}
627
		 * Invoked when there is an event caused by the user interacting with the control center.
627
		// added for defect 173451 to ensure that in case where the widget is
628
		 * 
628
		// disposed
629
		 * @param event The event type
629
		// we switch to the correct reference (for Linux platform)
630
		 * @param value The value associated with the event.  It can be null if no value is associated with
630
		// Liz Dancy
631
		 * the event type. 
631
		else if (statuslbl.isDisposed() && delegator.isShellDisposed) {
632
		 */
632
633
		public void handleEvent (byte event, Object value);
633
			this.updateDelegator(this.realParent, this.realParent);
634
	}
634
			statuslbl = this.delegator.statuslbl;
635
635
		}
636
636
		if (status == null)
637
	public void keyPressed(KeyEvent e)
637
			return;
638
	{
638
639
		keyReleased (null);
639
		lastStatus = status;
640
	}
640
		String finalStatus = AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BASE
641
641
				+ status;
642
642
		boolean toolong = false;
643
	public void keyReleased(KeyEvent e)
643
		if (finalStatus.length() > 30)
644
	{		
644
			toolong = true;
645
		if (verificationName.getText().trim().equals(""))
645
646
		{
646
		statuslbl.setToolTipText(finalStatus);
647
			insertButton.setEnabled(false);
647
		if (toolong)
648
			return;
648
			finalStatus = finalStatus.substring(0, 30) + "...";
649
		}
649
650
		insertButton.setEnabled(true);		
650
		statuslbl.setText(finalStatus);
651
	}
651
	}
652
	
652
653
	public Point getLastLocation ()
653
	public String getLastStatus() {
654
	{
654
		if (isRoot && delegator != null)
655
		if (isRoot && delegator != null)
655
			return delegator.getLastStatus();
656
			return delegator.getLastLocation();
656
		return lastStatus;
657
		if (sShell != null && !sShell.isDisposed())
657
	}
658
			return sShell.getLocation();
658
659
		
659
	/**
660
		return lastLocation;
660
	 * A primitive listener class
661
	}
661
	 */
662
	
662
	public interface AutoGUIControllerListener {
663
	public void setLocation (Point location)
663
		/**
664
	{
664
		 * Invoked when there is an event caused by the user interacting with
665
		lastLocation = location;
665
		 * the control center.
666
	}
666
		 * 
667
	
667
		 * @param event
668
	
668
		 *            The event type
669
	public void setPositionBasedOn(boolean isPositionBasedOn) {
669
		 * @param value
670
		this.positionBasedOn = isPositionBasedOn;
670
		 *            The value associated with the event. It can be null if no
671
	}
671
		 *            value is associated with the event type.
672
672
		 */
673
673
		public void handleEvent(byte event, Object value);
674
	public boolean isPositionBasedOn() {
674
	}
675
		return positionBasedOn;
675
676
	}
676
	public void keyPressed(KeyEvent e) {
677
677
		keyReleased(null);
678
678
	}
679
	public boolean isWaitTimeOn() {
679
680
		return waitTimeOn;
680
	public void keyReleased(KeyEvent e) {
681
	}
681
		if (verificationHookNameText.getText().trim().equals("")) {
682
682
			verificationHookInsertionButton.setEnabled(false);
683
683
			verificationScopeExtensionToolItem.setEnabled(false);
684
	public void setWaitTimeOn(boolean waitTimeOn) {
684
			return;
685
		this.waitTimeOn = waitTimeOn;
685
		}
686
	}
686
		verificationHookInsertionButton.setEnabled(true);
687
	
687
		verificationScopeExtensionToolItem.setEnabled(true);
688
	
688
	}
689
	public synchronized void updateDelegator (Shell guardian, Shell realParent)
689
690
	{
690
	public Point getLastLocation() {
691
		updateDelegator (guardian, realParent, null);
691
		if (isRoot && delegator != null)
692
	}	
692
			return delegator.getLastLocation();
693
	
693
		if (sShell != null && !sShell.isDisposed())
694
	public void updateDelegator (Shell guardian, Shell realParent, Shell activeShell)
694
			return sShell.getLocation();
695
	{
695
696
		if (guardian.isDisposed())
696
		return lastLocation;
697
			return;
697
	}
698
		
698
699
		Point location = getLastLocation();	
699
	public void setLocation(Point location) {
700
		String lastStatus = getLastStatus();
700
		lastLocation = location;
701
		
701
	}
702
		AutoGUITestControllerDialog rootControl = null;
702
703
		if (isRoot)
703
	public void setPositionBasedOn(boolean isPositionBasedOn) {
704
			rootControl = this;
704
		this.positionBasedOn = isPositionBasedOn;
705
		
705
	}
706
		else
706
707
			rootControl = this.rootControl;
707
	public boolean isPositionBasedOn() {
708
		
708
		return positionBasedOn;
709
		AutoGUITestControllerDialog delegator = rootControl.getDelegator();
709
	}
710
		/* Get rid of the last delegator */					
710
711
		if (activeControlDialog != null ){
711
	public boolean isVerficationScopeExtended() {
712
			activeControlDialog.dispose();
712
		return verificationScopeExtended;
713
			
713
	}
714
		}
714
715
		
715
	public boolean isWaitTimeOn() {
716
		delegator = new AutoGUITestControllerDialog(guardian, AutoGUITestControllerDialog.this);																
716
		return waitTimeOn;
717
		delegator.setLocation(location);
717
	}
718
		delegator.setPositionBasedOn(isPositionBasedOn());
718
719
		delegator.setWaitTimeOn(isWaitTimeOn());
719
	public void setWaitTimeOn(boolean waitTimeOn) {
720
		delegator.openDialog(activeShell);
720
		this.waitTimeOn = waitTimeOn;
721
		delegator.setStatus(lastStatus);	
721
	}
722
		delegator.actualParent = guardian;
722
723
		delegator.realParent = realParent;
723
	public synchronized void updateDelegator(Shell guardian, Shell realParent) {
724
		
724
		updateDelegator(guardian, realParent, null);
725
		rootControl.setDelegator(delegator);
725
	}
726
	}
726
727
	
727
	public void updateDelegator(Shell guardian, Shell realParent,
728
	public AutoGUITestControllerDialog getDelegator()
728
			Shell activeShell) {
729
	{
729
		if (guardian.isDisposed())
730
		return delegator;
730
			return;
731
	}
731
732
	
732
		Point location = getLastLocation();
733
	public void setDelegator(AutoGUITestControllerDialog delegator)
733
		String lastStatus = getLastStatus();
734
	{
734
735
		this.delegator = delegator;
735
		AutoGUITestControllerDialog rootControl = null;
736
	}
736
		if (isRoot)
737
	
737
			rootControl = this;
738
	
738
739
	private class DisplayListener implements Listener
739
		else
740
	{
740
			rootControl = this.rootControl;
741
		public void handleEvent(final Event event) 
741
742
		{				
742
		AutoGUITestControllerDialog delegator = rootControl.getDelegator();
743
				
743
		/* Get rid of the last delegator */
744
			class ChangeDialogParentOp implements Runnable
744
		if (activeControlDialog != null) {
745
			{
745
			activeControlDialog.dispose();
746
				private DisplayListener listener;
746
747
				public ChangeDialogParentOp(DisplayListener listener)
747
		}
748
				{
748
749
					this.listener = listener;
749
		delegator = new AutoGUITestControllerDialog(guardian,
750
				}
750
				AutoGUITestControllerDialog.this);
751
				
751
		delegator.setLocation(location);
752
				public void run() 
752
		delegator.setPositionBasedOn(isPositionBasedOn());
753
				{
753
		delegator.setWaitTimeOn(isWaitTimeOn());
754
					try
754
		delegator.openDialog(activeShell);
755
					{
755
		delegator.setStatus(lastStatus);
756
						if (forceToBack)
756
		delegator.actualParent = guardian;
757
							return;
757
		delegator.realParent = realParent;
758
						
758
759
						boolean isNewShellPresent = event.widget instanceof Shell && 										/* The widget is a shell */
759
		rootControl.setDelegator(delegator);
760
													!event.widget.isDisposed() && 											/* It hasn't been disposed */
760
	}
761
													event.widget.getData(MacroManager.IGNORE) == null &&  					/* It shouldn't be ignored */
761
762
													(realParent.isDisposed() || !event.widget.equals(realParent)) &&		/* It's not the current shell that we have as our parent */
762
	public AutoGUITestControllerDialog getDelegator() {
763
													!isComboBox(actualParent = (Shell)event.widget);						/* It's not a combo box */
763
		return delegator;
764
						if (!isNewShellPresent)
764
	}
765
							return;
765
766
766
	public void setDelegator(AutoGUITestControllerDialog delegator) {
767
						updateDelegator (actualParent, actualParent, actualParent);
767
		this.delegator = delegator;
768
						
768
	}
769
						if (actualParent != rootParent)
769
770
							activated = true;
770
	private class DisplayListener implements Listener {
771
						AutoGUITestControllerDialog.this.realParent = actualParent;
771
		public void handleEvent(final Event event) {
772
					}
772
773
773
			class ChangeDialogParentOp implements Runnable {
774
					catch (Throwable t)
774
				private DisplayListener listener;
775
					{
775
776
						/* If at any point an error occurs, then de-register this listener */
776
				public ChangeDialogParentOp(DisplayListener listener) {
777
						Display.getCurrent().removeFilter(SWT.Activate, listener);
777
					this.listener = listener;
778
					}
778
				}
779
				
779
780
				}
780
				public void run() {
781
781
					try {
782
				private boolean isComboBox(Shell shell) 
782
						if (forceToBack)
783
				{
783
							return;
784
					Control[] children = shell.getChildren();
784
785
					return children.length == 1 && children[0] instanceof List;
785
						boolean isNewShellPresent = event.widget instanceof Shell
786
				}
786
								&& /* The widget is a shell */
787
			};
787
								!event.widget.isDisposed()
788
		
788
								&& /* It hasn't been disposed */
789
			/* We need to run this as a timer operation because it may otherwise cause a widget disposed exeception.  The exception
789
								event.widget.getData(MacroManager.IGNORE) == null
790
			 * is caused in cases where we get an activation event on shells that are activated only for short periods of time.  Running
790
								&& /* It shouldn't be ignored */
791
			 * this operation as a timer operation will guarantee that an activated shell is present and not disposed after 50 milliseconds.  
791
								(realParent.isDisposed() || !event.widget
792
			 * This ultimately avoids processing activated shells that have a very short life span. */
792
										.equals(realParent))
793
			GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(50, new ChangeDialogParentOp(this));
793
								&& /*
794
		}		
794
									 * It's not the current shell that we have
795
	}
795
									 * as our parent
796
796
									 */
797
797
								!isComboBox(actualParent = (Shell) event.widget); /*
798
	public class ActivationListener implements Listener
798
																					 * It's
799
	{
799
																					 * not
800
		private boolean enable;
800
																					 * a
801
		
801
																					 * combo
802
		public ActivationListener(boolean enable)
802
																					 * box
803
		{
803
																					 */
804
			this.enable = enable;
804
						if (!isNewShellPresent)
805
		}
805
							return;
806
		
806
						// need to check for activated
807
		
807
						// bugzilla_184767
808
		public void handleEvent(Event event)
808
						// Liz Dancy
809
		{
809
						if (activated)
810
			if (!enable)
810
							updateDelegator(actualParent, actualParent,
811
				return;
811
									actualParent);
812
			
812
813
			
813
						if (actualParent != rootParent)
814
			switch (event.type)
814
							activated = true;
815
			{
815
						AutoGUITestControllerDialog.this.realParent = actualParent;
816
				case SWT.Activate:
816
					}
817
					controlCenterDialogActivated();
817
818
					break;
818
					catch (Throwable t) {
819
				case SWT.Deactivate:
819
						/*
820
					controlCenterDialogDeactivated();
820
						 * If at any point an error occurs, then de-register
821
					break;				
821
						 * this listener
822
			}
822
						 */
823
			
823
						Display.getCurrent().removeFilter(SWT.Activate,
824
		}
824
								listener);
825
825
					}
826
		private void controlCenterDialogActivated() 
826
827
		{								
827
				}
828
			/* If the parent of the control center dialog is a modal dialog but it was sent back, then we'll need to 
828
829
			 * bring the control center dialog to the front */			
829
				private boolean isComboBox(Shell shell) {
830
			if (isModalParent() && actualParent == rootParent && !activated)
830
					Control[] children = shell.getChildren();
831
			{	
831
					return children.length == 1 && children[0] instanceof List;
832
				activated = true;
832
				}
833
				forceToBack = false;
833
			}
834
				enable = false;
834
			;
835
				updateDelegator (realParent, realParent);
835
836
				enable = true;
836
			/*
837
				
837
			 * We need to run this as a timer operation because it may otherwise
838
			}
838
			 * cause a widget disposed exeception. The exception is caused in
839
			
839
			 * cases where we get an activation event on shells that are
840
		}
840
			 * activated only for short periods of time. Running this operation
841
		
841
			 * as a timer operation will guarantee that an activated shell is
842
		private void controlCenterDialogDeactivated() 
842
			 * present and not disposed after 50 milliseconds. This ultimately
843
		{	
843
			 * avoids processing activated shells that have a very short life
844
			/* If the parent of the control center dialog is modal, then we need to send it back */			
844
			 * span.
845
			if (isModalParent() && actualParent == realParent && activated)
845
			 */
846
			{
846
			GuiPlugin.getDefault().getWorkbench().getDisplay().timerExec(50,
847
				activated = false;
847
					new ChangeDialogParentOp(this));
848
				forceToBack = true;
848
		}
849
				enable = false;		
849
	}
850
				
850
851
				Shell realParent = null;
851
	public class ActivationListener implements Listener {
852
				if (delegator != null){
852
		private boolean enable;
853
					realParent = delegator.realParent;
853
854
				}
854
		public ActivationListener(boolean enable) {
855
				else 
855
			this.enable = enable;
856
					realParent = AutoGUITestControllerDialog.this.realParent;
856
		}
857
					
857
858
				updateDelegator(rootParent, realParent, realParent);
858
		public void handleEvent(Event event) {
859
				
859
			if (!enable)
860
				
860
				return;
861
				enable = true;
861
862
			}
862
			switch (event.type) {
863
		}
863
			case SWT.Activate:
864
864
				controlCenterDialogActivated();
865
865
				break;
866
		private boolean isModalParent()
866
			case SWT.Deactivate:
867
		{
867
				controlCenterDialogDeactivated();
868
			if (realParent == null || realParent.isDisposed())
868
				break;
869
				return false;
869
			}
870
			
870
871
			int parentStyle = realParent.getStyle();
871
		}
872
			return 	(parentStyle & SWT.SYSTEM_MODAL) != 0 ||
872
873
					(parentStyle & SWT.PRIMARY_MODAL) != 0 || 
873
		private void controlCenterDialogActivated() {
874
					(parentStyle & SWT.APPLICATION_MODAL) != 0;
874
			/*
875
		}
875
			 * If the parent of the control center dialog is a modal dialog but
876
		
876
			 * it was sent back, then we'll need to bring the control center
877
		private void setEnable (boolean enable)
877
			 * dialog to the front
878
		{
878
			 */
879
			this.enable = enable;
879
			if (isModalParent() && actualParent == rootParent && !activated) {
880
		}
880
				activated = false;
881
		
881
				forceToBack = false;
882
	}
882
				enable = false;
883
}
883
				updateDelegator(realParent, realParent);
884
				enable = true;
885
886
			}
887
888
		}
889
890
		private void controlCenterDialogDeactivated() {
891
			/*
892
			 * If the parent of the control center dialog is modal, then we need
893
			 * to send it back
894
			 */
895
			if (isModalParent() && actualParent == realParent && activated) {
896
				activated = false;
897
				forceToBack = true;
898
				enable = false;
899
900
				Shell realParent = null;
901
				if (delegator != null) {
902
					realParent = delegator.realParent;
903
				} else
904
					realParent = AutoGUITestControllerDialog.this.realParent;
905
				updateDelegator(rootParent, realParent, realParent);
906
907
				enable = true;
908
			}
909
		}
910
911
		private boolean isModalParent() {
912
			if (realParent == null || realParent.isDisposed())
913
				return false;
914
915
			int parentStyle = realParent.getStyle();
916
			return (parentStyle & SWT.SYSTEM_MODAL) != 0
917
					|| (parentStyle & SWT.PRIMARY_MODAL) != 0
918
					|| (parentStyle & SWT.APPLICATION_MODAL) != 0;
919
		}
920
921
		private void setEnable(boolean enable) {
922
			this.enable = enable;
923
		}
924
925
	}
926
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/runner/AutoGUIRunner.java (-1362 / +1362 lines)
Lines 1-1362 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AutoGUIRunner.java,v 1.25 2008/07/14 19:18:57 paules Exp $
7
 * $Id: AutoGUIRunner.java,v 1.25 2008/07/14 19:18:57 paules Exp $
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.runner;
12
package org.eclipse.tptp.test.auto.gui.internal.runner;
13
13
14
import java.io.ByteArrayInputStream;
14
import java.io.ByteArrayInputStream;
15
import java.io.PrintStream;
15
import java.io.PrintStream;
16
import java.io.UnsupportedEncodingException;
16
import java.io.UnsupportedEncodingException;
17
import java.util.ArrayList;
17
import java.util.ArrayList;
18
import java.util.Hashtable;
18
import java.util.Hashtable;
19
import java.util.Iterator;
19
import java.util.Iterator;
20
import java.util.List;
20
import java.util.List;
21
import java.util.Map;
21
import java.util.Map;
22
import java.util.Stack;
22
import java.util.Stack;
23
import java.util.Vector;
23
import java.util.Vector;
24
24
25
import junit.framework.AssertionFailedError;
25
import junit.framework.AssertionFailedError;
26
import junit.framework.Test;
26
import junit.framework.Test;
27
import junit.framework.TestResult;
27
import junit.framework.TestResult;
28
28
29
import org.eclipse.core.runtime.CoreException;
29
import org.eclipse.core.runtime.CoreException;
30
import org.eclipse.hyades.execution.core.IControlMessage;
30
import org.eclipse.hyades.execution.core.IControlMessage;
31
import org.eclipse.hyades.internal.execution.local.common.CustomCommand;
31
import org.eclipse.hyades.internal.execution.local.common.CustomCommand;
32
import org.eclipse.hyades.internal.execution.remote.CustomCommandHandler;
32
import org.eclipse.hyades.internal.execution.remote.CustomCommandHandler;
33
import org.eclipse.hyades.internal.execution.remote.RemoteComponentSkeleton;
33
import org.eclipse.hyades.internal.execution.remote.RemoteComponentSkeleton;
34
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
34
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
35
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
35
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
36
import org.eclipse.hyades.test.common.event.ExecutionEvent;
36
import org.eclipse.hyades.test.common.event.ExecutionEvent;
37
import org.eclipse.hyades.test.common.event.InvocationEvent;
37
import org.eclipse.hyades.test.common.event.InvocationEvent;
38
import org.eclipse.hyades.test.common.event.LoopEvent;
38
import org.eclipse.hyades.test.common.event.LoopEvent;
39
import org.eclipse.hyades.test.common.event.MessageEvent;
39
import org.eclipse.hyades.test.common.event.MessageEvent;
40
import org.eclipse.hyades.test.common.event.TypedEvent;
40
import org.eclipse.hyades.test.common.event.TypedEvent;
41
import org.eclipse.hyades.test.common.event.VerdictEvent;
41
import org.eclipse.hyades.test.common.event.VerdictEvent;
42
import org.eclipse.hyades.test.common.junit.IHyadesTest;
42
import org.eclipse.hyades.test.common.junit.IHyadesTest;
43
import org.eclipse.hyades.test.common.runner.internal.util.AgentConsoleStream;
43
import org.eclipse.hyades.test.common.runner.internal.util.AgentConsoleStream;
44
import org.eclipse.hyades.test.common.runner.model.Action;
44
import org.eclipse.hyades.test.common.runner.model.Action;
45
import org.eclipse.hyades.test.common.runner.model.IActionOwner;
45
import org.eclipse.hyades.test.common.runner.model.IActionOwner;
46
import org.eclipse.hyades.test.common.runner.model.Loop;
46
import org.eclipse.hyades.test.common.runner.model.Loop;
47
import org.eclipse.hyades.test.common.runner.model.NamedElement;
47
import org.eclipse.hyades.test.common.runner.model.NamedElement;
48
import org.eclipse.hyades.test.common.runner.model.TestInvocation;
48
import org.eclipse.hyades.test.common.runner.model.TestInvocation;
49
import org.eclipse.hyades.test.common.runner.model.TestSuite;
49
import org.eclipse.hyades.test.common.runner.model.TestSuite;
50
import org.eclipse.hyades.test.common.runner.model.util.EventLogger;
50
import org.eclipse.hyades.test.common.runner.model.util.EventLogger;
51
import org.eclipse.hyades.test.common.runner.model.util.ModelUtil;
51
import org.eclipse.hyades.test.common.runner.model.util.ModelUtil;
52
import org.eclipse.hyades.test.common.util.BaseString;
52
import org.eclipse.hyades.test.common.util.BaseString;
53
import org.eclipse.hyades.test.java.runner.HyadesJUnitRunner;
53
import org.eclipse.hyades.test.java.runner.HyadesJUnitRunner;
54
import org.eclipse.jface.dialogs.MessageDialog;
54
import org.eclipse.jface.dialogs.MessageDialog;
55
import org.eclipse.osgi.util.NLS;
55
import org.eclipse.osgi.util.NLS;
56
import org.eclipse.swt.widgets.Display;
56
import org.eclipse.swt.widgets.Display;
57
import org.eclipse.swt.widgets.Shell;
57
import org.eclipse.swt.widgets.Shell;
58
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
58
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
59
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
59
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
60
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
60
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
61
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
61
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
62
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
62
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
63
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
63
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
64
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
64
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCasesForm.GUITestCaseProperties;
65
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
65
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
66
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
66
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
67
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
67
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
68
import org.eclipse.tptp.test.auto.gui.internal.macro.XMLDefaultHandler;
68
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestCase;
69
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestCase;
69
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestInvocation;
70
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestInvocation;
70
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestSuite;
71
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.ExtendedTestSuite;
71
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.GeneralPropertyRetriever;
72
import org.eclipse.tptp.test.auto.gui.internal.runner.ExtendedScriptParser.GeneralPropertyRetriever;
72
import org.eclipse.tptp.test.auto.gui.internal.runner.VariableSubstitution.Variable;
73
import org.eclipse.tptp.test.auto.gui.internal.runner.VariableSubstitution.Variable;
73
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
74
import org.eclipse.ui.IStartup;
74
import org.eclipse.ui.IStartup;
75
import org.eclipse.ui.IWorkbench;
75
import org.eclipse.ui.IWorkbench;
76
import org.eclipse.ui.IWorkbenchWindow;
76
import org.eclipse.ui.IWorkbenchWindow;
77
import org.eclipse.ui.PlatformUI;
77
import org.eclipse.ui.PlatformUI;
78
import org.eclipse.ui.WorkbenchException;
78
import org.eclipse.ui.WorkbenchException;
79
import org.w3c.dom.Element;
79
import org.w3c.dom.Element;
80
import org.w3c.dom.Node;
80
import org.w3c.dom.Node;
81
import org.w3c.dom.NodeList;
81
import org.w3c.dom.NodeList;
82
import org.w3c.dom.Text;
82
import org.w3c.dom.Text;
83
83
84
/**
84
/**
85
 * This is the runner for the automated GUI test suite.  It needs to be under this plug-in
85
 * This is the runner for the automated GUI test suite.  It needs to be under this plug-in
86
 * as opposed to the tools.core plug-in because of the UI operations that it performs.
86
 * as opposed to the tools.core plug-in because of the UI operations that it performs.
87
 * <p/>
87
 * <p/>
88
 * 
88
 * 
89
 * 
89
 * 
90
 * @author  Ali Mehregani
90
 * @author  Ali Mehregani
91
 * @author  Paul E. Slauenwhite
91
 * @author  Paul E. Slauenwhite
92
 * @version July 14, 2008
92
 * @version July 14, 2008
93
 * @since   August 18, 2005
93
 * @since   August 18, 2005
94
 */
94
 */
95
public class AutoGUIRunner extends HyadesJUnitRunner implements IStartup
95
public class AutoGUIRunner extends HyadesJUnitRunner implements IStartup
96
{
96
{
97
	/* The modes that the test cases can run in */
97
	/* The modes that the test cases can run in */
98
	private final static byte QUICK_RUN_MODE = 0x01;
98
	private final static byte QUICK_RUN_MODE = 0x01;
99
	private final static byte EXECUTION_RUN_MODE = 0x02;
99
	private final static byte EXECUTION_RUN_MODE = 0x02;
100
	
100
	
101
	/* The test script */
101
	/* The test script */
102
	private String testScript;
102
	private String testScript;
103
		
103
		
104
	/* Static copy of the script -- lock it before using it*/
104
	/* Static copy of the script -- lock it before using it*/
105
	private static byte[] staticTestCase = new byte[0]; 
105
	private static byte[] staticTestCase = new byte[0]; 
106
	
106
	
107
	/* Set when there is an error in the process of test execution */
107
	/* Set when there is an error in the process of test execution */
108
	private boolean errorOccurred;
108
	private boolean errorOccurred;
109
	
109
	
110
	
110
	
111
	/* Holds the mode that we're running in */
111
	/* Holds the mode that we're running in */
112
	private byte runningMode;
112
	private byte runningMode;
113
	
113
	
114
	/* The test case index that we're currently at when executing in quick mode */
114
	/* The test case index that we're currently at when executing in quick mode */
115
	private int currentTestCaseInx;
115
	private int currentTestCaseInx;
116
	
116
	
117
	/* The last test invocation that was detected is stored here */
117
	/* The last test invocation that was detected is stored here */
118
	private ExtendedTestInvocation lastAction; 
118
	private ExtendedTestInvocation lastAction; 
119
	
119
	
120
	/* Keeps track of the loops */
120
	/* Keeps track of the loops */
121
	private Stack loopStack;
121
	private Stack loopStack;
122
	
122
	
123
	/* Stores the number of loops and test invocations detected so far seen */
123
	/* Stores the number of loops and test invocations detected so far seen */
124
	private int loopNumbersDetected, invocationNumbersDetected;
124
	private int loopNumbersDetected, invocationNumbersDetected;
125
	
125
	
126
	/* Keeps a stack of the execution events.  Elements must be of type ExecutionEvent */
126
	/* Keeps a stack of the execution events.  Elements must be of type ExecutionEvent */
127
	private Stack executionEventStack;
127
	private Stack executionEventStack;
128
	
128
	
129
	/* A reference to the ITestSuite EMF object - Available only in quick mode */
129
	/* A reference to the ITestSuite EMF object - Available only in quick mode */
130
	private ITestSuite testSuiteEMF;
130
	private ITestSuite testSuiteEMF;
131
	
131
	
132
	/* Contains a stack of action iterators that need to be executed */
132
	/* Contains a stack of action iterators that need to be executed */
133
	private Stack actionIteratorStack;
133
	private Stack actionIteratorStack;
134
		
134
		
135
	/* Indicates if the action iterator stack is been initialized */
135
	/* Indicates if the action iterator stack is been initialized */
136
	private boolean isActionIteratorStackInitialized;
136
	private boolean isActionIteratorStackInitialized;
137
	
137
	
138
	/* The extended test suite */
138
	/* The extended test suite */
139
	private ExtendedTestSuite extendedTestSuite;
139
	private ExtendedTestSuite extendedTestSuite;
140
	
140
	
141
	
141
	
142
	/**
142
	/**
143
	 * Default constructor.
143
	 * Default constructor.
144
	 */
144
	 */
145
	public AutoGUIRunner()
145
	public AutoGUIRunner()
146
	{
146
	{
147
		super((RemoteComponentSkeleton)null);		
147
		super((RemoteComponentSkeleton)null);		
148
		init();
148
		init();
149
	}
149
	}
150
	
150
	
151
	/**
151
	/**
152
	 * This constructor is used to create the appropriate agent.
152
	 * This constructor is used to create the appropriate agent.
153
	 * 
153
	 * 
154
	 * @param args The last statement is assumed to be the resource id.
154
	 * @param args The last statement is assumed to be the resource id.
155
	 * @param commandListeners The command listeners
155
	 * @param commandListeners The command listeners
156
	 */
156
	 */
157
	public AutoGUIRunner(String[] args, Vector commandListeners)
157
	public AutoGUIRunner(String[] args, Vector commandListeners)
158
	{
158
	{
159
		super (args, commandListeners);
159
		super (args, commandListeners);
160
		init();
160
		init();
161
	}
161
	}
162
	
162
	
163
	
163
	
164
	private void init()
164
	private void init()
165
	{
165
	{
166
		/* Initialize the event logger here, eventhough nothing will be logged if this constructor is used.
166
		/* Initialize the event logger here, eventhough nothing will be logged if this constructor is used.
167
		 * This is done to avoid an NPE when running in quick mode (all events will be ignored because there
167
		 * This is done to avoid an NPE when running in quick mode (all events will be ignored because there
168
		 * is no agent to send the events to) */
168
		 * is no agent to send the events to) */
169
		ModelUtil.setEventLogger(new EventLogger ()
169
		ModelUtil.setEventLogger(new EventLogger ()
170
			{
170
			{
171
			public void log(ExecutionEvent executionEvent)
171
			public void log(ExecutionEvent executionEvent)
172
			{
172
			{
173
				writeEvent (executionEvent);			
173
				writeEvent (executionEvent);			
174
			}});
174
			}});
175
		
175
		
176
		loopNumbersDetected= 0;
176
		loopNumbersDetected= 0;
177
		executionEventStack = new Stack();
177
		executionEventStack = new Stack();
178
		loopStack = new Stack();
178
		loopStack = new Stack();
179
		actionIteratorStack = new Stack();
179
		actionIteratorStack = new Stack();
180
		isActionIteratorStackInitialized = false;
180
		isActionIteratorStackInitialized = false;
181
	}
181
	}
182
	
182
	
183
	
183
	
184
	/**
184
	/**
185
	 * Invoked when the workbench starts
185
	 * Invoked when the workbench starts
186
	 */
186
	 */
187
	public void earlyStartup()
187
	public void earlyStartup()
188
	{
188
	{
189
		String[] args = null;
189
		String[] args = null;
190
		long startTime = 0;
190
		long startTime = 0;
191
		AutoGUIRunner runner = null;
191
		AutoGUIRunner runner = null;
192
		
192
		
193
		try
193
		try
194
		{
194
		{
195
			/* These first few steps need to be quick and painless - they will impact the workbench 
195
			/* These first few steps need to be quick and painless - they will impact the workbench 
196
			 * startup time */
196
			 * startup time */
197
			final String isHeadlessModeOn = "tptp.automated.gui";
197
			final String isHeadlessModeOn = "tptp.automated.gui";
198
			if (System.getProperty(isHeadlessModeOn) == null)
198
			if (System.getProperty(isHeadlessModeOn) == null)
199
				return;
199
				return;
200
			
200
			
201
			/* We're in the headless mode.  Get the resource id */
201
			/* We're in the headless mode.  Get the resource id */
202
			final String executorProperty = "tptp.automated.gui.executor";
202
			final String executorProperty = "tptp.automated.gui.executor";
203
			final String executor = System.getProperty(executorProperty);
203
			final String executor = System.getProperty(executorProperty);
204
			
204
			
205
			if (executor == null)
205
			if (executor == null)
206
				AutoGUIUtil.showMessage (
206
				AutoGUIUtil.showMessage (
207
						AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_PROP_T, 
207
						AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_PROP_T, 
208
						NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_PROP, executorProperty),
208
						NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_PROP, executorProperty),
209
						MessageDialog.ERROR);
209
						MessageDialog.ERROR);
210
			
210
			
211
			/* Instantiate an instance of this class */
211
			/* Instantiate an instance of this class */
212
			args = new String[1];
212
			args = new String[1];
213
			args[0] = executor;
213
			args[0] = executor;
214
			Vector commandListeners = new Vector();
214
			Vector commandListeners = new Vector();
215
			commandListeners.add(new CustomCommandHandler()
215
			commandListeners.add(new CustomCommandHandler()
216
					{
216
					{
217
				/* Start listening for the script */
217
				/* Start listening for the script */
218
				public void handleCommand(CustomCommand command)
218
				public void handleCommand(CustomCommand command)
219
				{
219
				{
220
					if(command.getData().equals(IControlMessage.START))
220
					if(command.getData().equals(IControlMessage.START))
221
					{
221
					{
222
						/* Don't do anything */
222
						/* Don't do anything */
223
					}
223
					}
224
					else
224
					else
225
					{
225
					{
226
						synchronized(staticTestCase)
226
						synchronized(staticTestCase)
227
						{
227
						{
228
							staticTestCase = command.getDataBinary();
228
							staticTestCase = command.getDataBinary();
229
						}
229
						}
230
					}						
230
					}						
231
				}			
231
				}			
232
			}
232
			}
233
			);
233
			);
234
			
234
			
235
			runner = new AutoGUIRunner(args, commandListeners);
235
			runner = new AutoGUIRunner(args, commandListeners);
236
			
236
			
237
			/* Wait for the script.  The wait is for a maximum of 2 minutes */
237
			/* Wait for the script.  The wait is for a maximum of 2 minutes */
238
			synchronized (this)
238
			synchronized (this)
239
			{
239
			{
240
				try
240
				try
241
				{
241
				{
242
					/* Check every second, and wait for a maximum of 2 minutes */				
242
					/* Check every second, and wait for a maximum of 2 minutes */				
243
					synchronized (staticTestCase)
243
					synchronized (staticTestCase)
244
					{
244
					{
245
						int counter = 0;
245
						int counter = 0;
246
						while (staticTestCase.length <= 0 && counter < 120)
246
						while (staticTestCase.length <= 0 && counter < 120)
247
						{
247
						{
248
							counter++;
248
							counter++;
249
							wait (1000);
249
							wait (1000);
250
						}
250
						}
251
						
251
						
252
						/* Notify the agent that something went wrong, if we still haven't go the script */
252
						/* Notify the agent that something went wrong, if we still haven't go the script */
253
						if (staticTestCase.length <= 0)
253
						if (staticTestCase.length <= 0)
254
						{
254
						{
255
							/* Try and tell the client we are timing out */
255
							/* Try and tell the client we are timing out */
256
							agent.sendMessageToAttachedClient("The test script was not set after two minutes.", 0);
256
							agent.sendMessageToAttachedClient("The test script was not set after two minutes.", 0);
257
	
257
	
258
							/* We have timed out.  exit */
258
							/* We have timed out.  exit */
259
							System.exit(-1);
259
							System.exit(-1);
260
						}
260
						}
261
						else
261
						else
262
						{
262
						{
263
							runner.setTestScript(staticTestCase);
263
							runner.setTestScript(staticTestCase);
264
						}
264
						}
265
					}
265
					}
266
				}
266
				}
267
				catch (InterruptedException e)
267
				catch (InterruptedException e)
268
				{
268
				{
269
					
269
					
270
				}
270
				}
271
			}
271
			}
272
		
272
		
273
			
273
			
274
		
274
		
275
275
276
			/* Get the agent */
276
			/* Get the agent */
277
			RemoteComponentSkeleton agent = runner.getAgent(null);		
277
			RemoteComponentSkeleton agent = runner.getAgent(null);		
278
			
278
			
279
			/* Do the initializations */
279
			/* Do the initializations */
280
			runner.writeExecEvent("<EXECUTION>");
280
			runner.writeExecEvent("<EXECUTION>");
281
			TestSuite testSuiteObj = runner.parseTestScript();
281
			TestSuite testSuiteObj = runner.parseTestScript();
282
			
282
			
283
			/* Redirect std out and err */
283
			/* Redirect std out and err */
284
			System.setOut(new PrintStream(new AgentConsoleStream(agent, AgentConsoleStream.OUT, ModelUtil.getHierarchyId(testSuiteObj),_peekParentEventID())));
284
			System.setOut(new PrintStream(new AgentConsoleStream(agent, AgentConsoleStream.OUT, ModelUtil.getHierarchyId(testSuiteObj),_peekParentEventID())));
285
			System.setErr(new PrintStream(new AgentConsoleStream(agent, AgentConsoleStream.ERR, ModelUtil.getHierarchyId(testSuiteObj),_peekParentEventID())));
285
			System.setErr(new PrintStream(new AgentConsoleStream(agent, AgentConsoleStream.ERR, ModelUtil.getHierarchyId(testSuiteObj),_peekParentEventID())));
286
	
286
	
287
			/* Run the tests */			
287
			/* Run the tests */			
288
			startTime = getCurrentTime();
288
			startTime = getCurrentTime();
289
			
289
			
290
			runner.runTest (testSuiteObj, EXECUTION_RUN_MODE);			
290
			runner.runTest (testSuiteObj, EXECUTION_RUN_MODE);			
291
		}
291
		}
292
		catch(Throwable e)
292
		catch(Throwable e)
293
		{
293
		{
294
			/* We could not find the class (or something else, report the error) */
294
			/* We could not find the class (or something else, report the error) */
295
			try
295
			try
296
			{
296
			{
297
				MessageEvent messageEvent = new MessageEvent();
297
				MessageEvent messageEvent = new MessageEvent();
298
				messageEvent.setText(BaseString.getStackTrace(e));
298
				messageEvent.setText(BaseString.getStackTrace(e));
299
				messageEvent.setSeverity(MessageEvent.ERROR);
299
				messageEvent.setSeverity(MessageEvent.ERROR);
300
				messageEvent.setParentId("ROOT");
300
				messageEvent.setParentId("ROOT");
301
				ModelUtil.getEventLogger().log(messageEvent);
301
				ModelUtil.getEventLogger().log(messageEvent);
302
			}
302
			}
303
			catch (Throwable t)
303
			catch (Throwable t)
304
			{
304
			{
305
				/* We weren't able to report the error */
305
				/* We weren't able to report the error */
306
			}
306
			}
307
			
307
			
308
		}
308
		}
309
309
310
		/* Exit */
310
		/* Exit */
311
		try
311
		try
312
		{
312
		{
313
			long endTime = getCurrentTime();
313
			long endTime = getCurrentTime();
314
			runnerExit(true, (endTime - startTime));
314
			runnerExit(true, (endTime - startTime));
315
			runner.writeExecEvent("</EXECUTION>");
315
			runner.writeExecEvent("</EXECUTION>");
316
		}
316
		}
317
		catch (Throwable t)
317
		catch (Throwable t)
318
		{
318
		{
319
			/* Doesn't need to be handled */
319
			/* Doesn't need to be handled */
320
		}
320
		}
321
		
321
		
322
		/* Always make sure that the headless workbench quits (regardless of errors occurring while running the test runner */
322
		/* Always make sure that the headless workbench quits (regardless of errors occurring while running the test runner */
323
		System.exit(0);
323
		System.exit(0);
324
		
324
		
325
	}
325
	}
326
	
326
	
327
	/**
327
	/**
328
	 * Runs the test cases of 'testSuite' using the current workbench as
328
	 * Runs the test cases of 'testSuite' using the current workbench as
329
	 * the context.
329
	 * the context.
330
	 * 
330
	 * 
331
	 * @param testSuite The testSuite to be tested.
331
	 * @param testSuite The testSuite to be tested.
332
	 */
332
	 */
333
	public void runTestInCurrentContext(ITestSuite testSuiteEMF, final TestSuite testSuite, final ITestRunnerDelegator delegator)
333
	public void runTestInCurrentContext(ITestSuite testSuiteEMF, final TestSuite testSuite, final ITestRunnerDelegator delegator)
334
	{
334
	{
335
		new Thread (new Runnable(){
335
		new Thread (new Runnable(){
336
336
337
			public void run() 
337
			public void run() 
338
			{
338
			{
339
				runTest(testSuite, QUICK_RUN_MODE);
339
				runTest(testSuite, QUICK_RUN_MODE);
340
				delegator.finishedTestRun();
340
				delegator.finishedTestRun();
341
			}
341
			}
342
			
342
			
343
		}).start();
343
		}).start();
344
		
344
		
345
		this.testSuiteEMF = testSuiteEMF;		
345
		this.testSuiteEMF = testSuiteEMF;		
346
	}
346
	}
347
	
347
	
348
	
348
	
349
	/**
349
	/**
350
	 * Runs the actual test script in the mode that it is given.  
350
	 * Runs the actual test script in the mode that it is given.  
351
	 * 
351
	 * 
352
	 * @param testSuite The test script 
352
	 * @param testSuite The test script 
353
	 * @param mode Can be QUICK_RUN_MODE (used when a quick run mode button of the test case form is
353
	 * @param mode Can be QUICK_RUN_MODE (used when a quick run mode button of the test case form is
354
	 * pressed) or EXECUTION_RUN_MODE (used when a proper launch configuration is used)
354
	 * pressed) or EXECUTION_RUN_MODE (used when a proper launch configuration is used)
355
	 */
355
	 */
356
	private void runTest(TestSuite testSuite, final byte mode)
356
	private void runTest(TestSuite testSuite, final byte mode)
357
	{
357
	{
358
		runningMode = mode;
358
		runningMode = mode;
359
		currentTestCaseInx = 0;		
359
		currentTestCaseInx = 0;		
360
		
360
		
361
		if (!(testSuite instanceof ExtendedTestSuite))
361
		if (!(testSuite instanceof ExtendedTestSuite))
362
			return;
362
			return;
363
		
363
		
364
		extendedTestSuite = (ExtendedTestSuite)testSuite;
364
		extendedTestSuite = (ExtendedTestSuite)testSuite;
365
		/* Before running the test cases, set the dependencies of the test suite (if any exist) */
365
		/* Before running the test cases, set the dependencies of the test suite (if any exist) */
366
		if (extendedTestSuite.getDependencies() != null && extendedTestSuite.getDependencies().size() > 0)
366
		if (extendedTestSuite.getDependencies() != null && extendedTestSuite.getDependencies().size() > 0)
367
			MacroManager.getInstance().setDependecies(extendedTestSuite.getDependencies());
367
			MacroManager.getInstance().setDependecies(extendedTestSuite.getDependencies());
368
			
368
			
369
		/* Register this runner */
369
		/* Register this runner */
370
		MacroManager.getInstance().setRunner(this);
370
		MacroManager.getInstance().setRunner(this);
371
		
371
		
372
		if (mode == EXECUTION_RUN_MODE)
372
		if (mode == EXECUTION_RUN_MODE)
373
			/* Log the start of the test suite */
373
			/* Log the start of the test suite */
374
			sendTypeEvent(TypedEvent.START, null);
374
			sendTypeEvent(TypedEvent.START, null);
375
		
375
		
376
	
376
	
377
		/* Do all initializations required before the test run begins */
377
		/* Do all initializations required before the test run begins */
378
		Exception initializeState = null;
378
		Exception initializeState = null;
379
		try
379
		try
380
		{
380
		{
381
			initializeTestRun(mode);
381
			initializeTestRun(mode);
382
		} 
382
		} 
383
		catch (CoreException e)
383
		catch (CoreException e)
384
		{
384
		{
385
			initializeState = e;
385
			initializeState = e;
386
			
386
			
387
		}
387
		}
388
		
388
		
389
		/* Holds the next executable action that is to be executed */
389
		/* Holds the next executable action that is to be executed */
390
		Object nextExecution = null;
390
		Object nextExecution = null;
391
		/* Holds the test suite if we are executing a test suite reference, added for bugzilla_136186*/
391
		/* Holds the test suite if we are executing a test suite reference, added for bugzilla_136186*/
392
		TestSuite nestedSuite = new TestSuite();
392
		TestSuite nestedSuite = new TestSuite();
393
		/* To keep track of when we are in a reference to a test suite*/
393
		/* To keep track of when we are in a reference to a test suite*/
394
		boolean inTestSuite =false;
394
		boolean inTestSuite =false;
395
		/* To keep track of whether we are in a Loop inside of a test suite reference*/
395
		/* To keep track of whether we are in a Loop inside of a test suite reference*/
396
		boolean loopStarted = false;
396
		boolean loopStarted = false;
397
		/* The index of test cases in a references Loop or test suite*/
397
		/* The index of test cases in a references Loop or test suite*/
398
		int index=0;
398
		int index=0;
399
	
399
	
400
		/* Walk through every element that needs to be executed in our test suite */
400
		/* Walk through every element that needs to be executed in our test suite */
401
		if (initializeState == null)
401
		if (initializeState == null)
402
		{
402
		{
403
			
403
			
404
			while (((inTestSuite)|| (nextExecution =nextExecution(mode, testSuite))!=null))
404
			while (((inTestSuite)|| (nextExecution =nextExecution(mode, testSuite))!=null))
405
			{
405
			{
406
				// Added for bugzilla_136186 to add the ability to step through test 
406
				// Added for bugzilla_136186 to add the ability to step through test 
407
				//cases in a referenced test suite
407
				//cases in a referenced test suite
408
				// Liz D.
408
				// Liz D.
409
				if (inTestSuite)
409
				if (inTestSuite)
410
				{
410
				{
411
					nextExecution = nestedSuite.getActions().get(index); 
411
					nextExecution = nestedSuite.getActions().get(index); 
412
					
412
					
413
					if (nextExecution instanceof org.eclipse.hyades.test.common.runner.model.Loop)
413
					if (nextExecution instanceof org.eclipse.hyades.test.common.runner.model.Loop)
414
					{
414
					{
415
						if (loopStarted)
415
						if (loopStarted)
416
						{
416
						{
417
							nextExecution = ((Loop)nextExecution).getActions().get(index);
417
							nextExecution = ((Loop)nextExecution).getActions().get(index);
418
							loopStarted=false;
418
							loopStarted=false;
419
						}
419
						}
420
						else
420
						else
421
							loopStarted=true;
421
							loopStarted=true;
422
					}
422
					}
423
					
423
					
424
				}
424
				}
425
				
425
				
426
				try
426
				try
427
				{
427
				{
428
					errorOccurred = false;
428
					errorOccurred = false;
429
					Object testCaseObject = null;
429
					Object testCaseObject = null;
430
					lastAction = null;
430
					lastAction = null;
431
					
431
					
432
					/* Flush out the system output and error stream if in case the previous test case stored anything in the buffer */
432
					/* Flush out the system output and error stream if in case the previous test case stored anything in the buffer */
433
					System.out.flush();
433
					System.out.flush();
434
					System.err.flush();
434
					System.err.flush();
435
					
435
					
436
					/* Set the test case object of the item that is being executed next */
436
					/* Set the test case object of the item that is being executed next */
437
					if (mode == QUICK_RUN_MODE)
437
					if (mode == QUICK_RUN_MODE)
438
						testCaseObject = nextExecution;				
438
						testCaseObject = nextExecution;				
439
					else if (mode == EXECUTION_RUN_MODE)
439
					else if (mode == EXECUTION_RUN_MODE)
440
					{
440
					{
441
						/* End the last loop if the owner is either the root or from the parent of the last loop */
441
						/* End the last loop if the owner is either the root or from the parent of the last loop */
442
						Loop lastLoop = getLastLoop();					
442
						Loop lastLoop = getLastLoop();					
443
						if (lastLoop != null)
443
						if (lastLoop != null)
444
						{
444
						{
445
							IActionOwner parentOfLastLoop = lastLoop.getOwner();
445
							IActionOwner parentOfLastLoop = lastLoop.getOwner();
446
							String parentOfLastLoopId = getActionId(parentOfLastLoop);
446
							String parentOfLastLoopId = getActionId(parentOfLastLoop);
447
							String nextExecutionId = getActionId(nextExecution);
447
							String nextExecutionId = getActionId(nextExecution);
448
							
448
							
449
							/* Iterating through the same loop */
449
							/* Iterating through the same loop */
450
							if (lastLoop.getId().equals(nextExecutionId))
450
							if (lastLoop.getId().equals(nextExecutionId))
451
							{
451
							{
452
								continue;
452
								continue;
453
							}
453
							}
454
							
454
							
455
							/* End of the last loop */
455
							/* End of the last loop */
456
							else if (nextExecutionId.equals(parentOfLastLoopId))
456
							else if (nextExecutionId.equals(parentOfLastLoopId))
457
							{
457
							{
458
								sendLoopStop();
458
								sendLoopStop();
459
								continue;
459
								continue;
460
							}
460
							}
461
							
461
							
462
							else if (((Action)nextExecution).getOwner() instanceof TestSuite && !inTestSuite)
462
							else if (((Action)nextExecution).getOwner() instanceof TestSuite && !inTestSuite)
463
							{
463
							{
464
								sendAllLoopStop ();
464
								sendAllLoopStop ();
465
								
465
								
466
							}
466
							}
467
						}
467
						}
468
						
468
						
469
						/* If the action happens to be a loop, then simply send the loop start event */
469
						/* If the action happens to be a loop, then simply send the loop start event */
470
						if (nextExecution instanceof Loop)
470
						if (nextExecution instanceof Loop)
471
						{				
471
						{				
472
							sendLoopStart ((Loop)nextExecution);						
472
							sendLoopStart ((Loop)nextExecution);						
473
							continue;
473
							continue;
474
						
474
						
475
						}
475
						}
476
						
476
						
477
						/* If the action is a test invocation, then send the test invocation */
477
						/* If the action is a test invocation, then send the test invocation */
478
						 if (nextExecution instanceof ExtendedTestInvocation )
478
						 if (nextExecution instanceof ExtendedTestInvocation )
479
						{
479
						{
480
							lastAction = (ExtendedTestInvocation)nextExecution;
480
							lastAction = (ExtendedTestInvocation)nextExecution;
481
							testCaseObject = lastAction.getTest();
481
							testCaseObject = lastAction.getTest();
482
							sendTestInvocation(lastAction, InvocationEvent.STATUS_SUCCESSFUL, lastAction.getName());
482
							sendTestInvocation(lastAction, InvocationEvent.STATUS_SUCCESSFUL, lastAction.getName());
483
							
483
							
484
							if (testCaseObject instanceof TestSuite)
484
							if (testCaseObject instanceof TestSuite)
485
							{
485
							{
486
								nestedSuite = ((TestSuite)testCaseObject);
486
								nestedSuite = ((TestSuite)testCaseObject);
487
								inTestSuite=true;
487
								inTestSuite=true;
488
								index =0;
488
								index =0;
489
								continue;
489
								continue;
490
							}
490
							}
491
						}
491
						}
492
						
492
						
493
						/* Otherwise continue with the main loop */
493
						/* Otherwise continue with the main loop */
494
						else
494
						else
495
						{
495
						{
496
							continue;
496
							continue;
497
						}
497
						}
498
					}
498
					}
499
					if (!((testCaseObject instanceof ExtendedTestCase)))
499
					if (!((testCaseObject instanceof ExtendedTestCase)))
500
						continue;
500
						continue;
501
					
501
					
502
					/* Switch to the perspective representing our starting point */
502
					/* Switch to the perspective representing our starting point */
503
					final ExtendedTestCase testCase = (ExtendedTestCase)testCaseObject;	
503
					final ExtendedTestCase testCase = (ExtendedTestCase)testCaseObject;	
504
					
504
					
505
					final String startingPoint = testCase.getProperty(String.valueOf(GUITestCaseProperties.STARTING_PT));
505
					final String startingPoint = testCase.getProperty(String.valueOf(GUITestCaseProperties.STARTING_PT));
506
					
506
					
507
					
507
					
508
					/* This is a required field.  In case it is not set, then mark the test case with
508
					/* This is a required field.  In case it is not set, then mark the test case with
509
					 * a verdict of error */
509
					 * a verdict of error */
510
					if (startingPoint == null || startingPoint.length() <= 0)
510
					if (startingPoint == null || startingPoint.length() <= 0)
511
					{
511
					{
512
						/* Show an error if we're running in quick run mode */
512
						/* Show an error if we're running in quick run mode */
513
						if (mode == QUICK_RUN_MODE)
513
						if (mode == QUICK_RUN_MODE)
514
						{
514
						{
515
							AutoGUIUtil.showMessage(
515
							AutoGUIUtil.showMessage(
516
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP_T, 
516
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP_T, 
517
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP, 
517
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP, 
518
									MessageDialog.ERROR);						
518
									MessageDialog.ERROR);						
519
						}
519
						}
520
						else if (mode == EXECUTION_RUN_MODE)
520
						else if (mode == EXECUTION_RUN_MODE)
521
						{
521
						{
522
							sendVerdict(lastAction, VerdictEvent.VERDICT_ERROR, 
522
							sendVerdict(lastAction, VerdictEvent.VERDICT_ERROR, 
523
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP_T);	
523
									AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MISS_SP_T);	
524
						}
524
						}
525
											
525
											
526
						continue;
526
						continue;
527
					}
527
					}
528
						
528
						
529
					final IWorkbench workbench = PlatformUI.getWorkbench();	
529
					final IWorkbench workbench = PlatformUI.getWorkbench();	
530
					final TestInvocation constantTestInvocation = lastAction;
530
					final TestInvocation constantTestInvocation = lastAction;
531
					workbench.getDisplay().syncExec(new Runnable() {
531
					workbench.getDisplay().syncExec(new Runnable() {
532
				    public void run() 
532
				    public void run() 
533
				    {
533
				    {
534
				    	IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
534
				    	IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
535
				    	if (window != null) 
535
				    	if (window != null) 
536
				    	{
536
				    	{
537
				    		try
537
				    		try
538
							{
538
							{
539
								/* If we are running in execution mode then we may need to close the welcome page and maximize the workbench*/
539
								/* If we are running in execution mode then we may need to close the welcome page and maximize the workbench*/
540
								if (mode == EXECUTION_RUN_MODE)
540
								if (mode == EXECUTION_RUN_MODE)
541
								{
541
								{
542
									MacroUtil.closeWelcomePage();
542
									MacroUtil.closeWelcomePage();
543
									MacroUtil.maximizeWorkbench();
543
									MacroUtil.maximizeWorkbench();
544
								}
544
								}
545
									
545
									
546
								
546
								
547
								workbench.showPerspective(startingPoint, window);
547
								workbench.showPerspective(startingPoint, window);
548
							}
548
							}
549
				    	
549
				    	
550
							catch (WorkbenchException e)
550
							catch (WorkbenchException e)
551
							{			
551
							{			
552
								errorOccurred = true;
552
								errorOccurred = true;
553
								/* If we are running in quick mode, then display the correct error message */
553
								/* If we are running in quick mode, then display the correct error message */
554
								if (mode == QUICK_RUN_MODE)
554
								if (mode == QUICK_RUN_MODE)
555
								{
555
								{
556
									AutoGUIUtil.showMessage(
556
									AutoGUIUtil.showMessage(
557
											AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE, 
557
											AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH_TITLE, 
558
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, new String[] {startingPoint, e.getLocalizedMessage()}), 
558
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, new String[] {startingPoint, e.getLocalizedMessage()}), 
559
											MessageDialog.ERROR);
559
											MessageDialog.ERROR);
560
								}
560
								}
561
								else if (mode == EXECUTION_RUN_MODE)
561
								else if (mode == EXECUTION_RUN_MODE)
562
								{
562
								{
563
									sendVerdict(constantTestInvocation, VerdictEvent.VERDICT_ERROR,
563
									sendVerdict(constantTestInvocation, VerdictEvent.VERDICT_ERROR,
564
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, new String[] {startingPoint, e.getLocalizedMessage()}));
564
										NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_PERS_SWITCH, new String[] {startingPoint, e.getLocalizedMessage()}));
565
								}							
565
								}							
566
							}
566
							}
567
				    	}
567
				    	}
568
				    }
568
				    }
569
				    });
569
				    });
570
					
570
					
571
					if (errorOccurred)
571
					if (errorOccurred)
572
						continue;
572
						continue;
573
					
573
					
574
					
574
					
575
					/* Time to run the macro */
575
					/* Time to run the macro */
576
					final String macro = testCase.getProperty(String.valueOf(GUITestCaseProperties.MACRO_FRAGMENT));				
576
					final String macro = testCase.getProperty(String.valueOf(GUITestCaseProperties.MACRO_FRAGMENT));				
577
					
577
					
578
					class MacroPlayWrapper implements Runnable
578
					class MacroPlayWrapper implements Runnable
579
					{
579
					{
580
						private Object objectToNotify;
580
						private Object objectToNotify;
581
						private boolean isDone;
581
						private boolean isDone;
582
						
582
						
583
						public MacroPlayWrapper (Object objectToNotify)
583
						public MacroPlayWrapper (Object objectToNotify)
584
						{
584
						{
585
							this.objectToNotify = objectToNotify;
585
							this.objectToNotify = objectToNotify;
586
							isDone = false;
586
							isDone = false;
587
						}
587
						}
588
						
588
						
589
						
589
						
590
					    public void run() 
590
					    public void run() 
591
					    {
591
					    {
592
				    		try
592
				    		try
593
							{
593
							{
594
				    			/* Not interested if there is no macro */
594
				    			/* Not interested if there is no macro */
595
								if (macro == null || macro.length() <= 0)
595
								if (macro == null || macro.length() <= 0)
596
									return;
596
									return;
597
								
597
								
598
								XMLDefaultHandler handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(macro.getBytes("UTF-8")));
598
								XMLDefaultHandler handler = MacroManager.getInstance().createMacroDocument(new ByteArrayInputStream(macro.getBytes("UTF-8")));
599
								int timeout = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD;
599
								int timeout = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD;
600
								if (mode == EXECUTION_RUN_MODE)
600
								if (mode == EXECUTION_RUN_MODE)
601
								{
601
								{
602
									linkUserInput(handler);
602
									linkUserInput(handler);
603
									String timeoutStr = lastAction.getProperty(GlobalConstants.COMMAND_TIMEOUT_THRESHOLD); 
603
									String timeoutStr = lastAction.getProperty(GlobalConstants.COMMAND_TIMEOUT_THRESHOLD); 
604
									if (timeoutStr != null)
604
									if (timeoutStr != null)
605
									{
605
									{
606
										try
606
										try
607
										{
607
										{
608
											timeout = Integer.parseInt(timeoutStr);
608
											timeout = Integer.parseInt(timeoutStr);
609
										}
609
										}
610
										catch (Exception e)
610
										catch (Exception e)
611
										{
611
										{
612
											/* Doesn't need to be handled -- timeout is already set to default */
612
											/* Doesn't need to be handled -- timeout is already set to default */
613
										}
613
										}
614
									}
614
									}
615
								}
615
								}
616
								/* We may need to do variable substitution if we're running in quick mode */
616
								/* We may need to do variable substitution if we're running in quick mode */
617
								else if (mode == QUICK_RUN_MODE)
617
								else if (mode == QUICK_RUN_MODE)
618
								{
618
								{
619
									doVariableSubstitution(handler);
619
									doVariableSubstitution(handler);
620
								}
620
								}
621
															
621
															
622
				    			MacroManager mng = MacroManager.getInstance();
622
				    			MacroManager mng = MacroManager.getInstance();
623
				    			mng.setCommandTimeoutThreshold(timeout);
623
				    			mng.setCommandTimeoutThreshold(timeout);
624
				    			mng.play(GuiPlugin.getDefault().getWorkbench().getDisplay(), null, testCase.getName(), handler, Boolean.TRUE);				    			
624
				    			mng.play(GuiPlugin.getDefault().getWorkbench().getDisplay(), null, testCase.getName(), handler, Boolean.TRUE);				    			
625
				    			handler = null;
625
				    			handler = null;
626
				    			
626
				    			
627
				    			if (objectToNotify != null)
627
				    			if (objectToNotify != null)
628
				    			{
628
				    			{
629
				    				synchronized (objectToNotify)
629
				    				synchronized (objectToNotify)
630
				    				{
630
				    				{
631
				    					objectToNotify.notify();
631
				    					objectToNotify.notify();
632
				    				}
632
				    				}
633
				    			}
633
				    			}
634
				    			
634
				    			
635
				    			isDone = true;
635
				    			isDone = true;
636
							}
636
							}
637
							catch (Throwable t)
637
							catch (Throwable t)
638
							{						
638
							{						
639
								/* If we are running in quick mode, then display the correct error message */
639
								/* If we are running in quick mode, then display the correct error message */
640
								if (mode == QUICK_RUN_MODE)
640
								if (mode == QUICK_RUN_MODE)
641
								{	
641
								{	
642
									AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, 
642
									AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING_T, 
643
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING, testCase.getName()), t);
643
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING, testCase.getName()), t);
644
									
644
									
645
								}
645
								}
646
								else if (mode == EXECUTION_RUN_MODE)
646
								else if (mode == EXECUTION_RUN_MODE)
647
								{														
647
								{														
648
									sendVerdict(constantTestInvocation, VerdictEvent.VERDICT_FAIL,
648
									sendVerdict(constantTestInvocation, VerdictEvent.VERDICT_FAIL,
649
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING, testCase.getName()) + ".  " + AutoGUIUtil.getExceptionStackTrace(t));									
649
											NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_RUNNING, testCase.getName()) + ".  " + AutoGUIUtil.getExceptionStackTrace(t));									
650
								}
650
								}
651
								
651
								
652
								
652
								
653
								/* Give a chance for unfinished threads to exit */
653
								/* Give a chance for unfinished threads to exit */
654
								int outstandingShellCommandCount = MacroManager.getInstance().getOutstandShellCommands();		
654
								int outstandingShellCommandCount = MacroManager.getInstance().getOutstandShellCommands();		
655
								final int INCREMENT = 3000;
655
								final int INCREMENT = 3000;
656
								final int MAX_COUNT = 3;
656
								final int MAX_COUNT = 3;
657
								int count = 0;
657
								int count = 0;
658
								while (outstandingShellCommandCount > 0 && count < MAX_COUNT)
658
								while (outstandingShellCommandCount > 0 && count < MAX_COUNT)
659
								{
659
								{
660
									MacroUtil.closeSecondaryShells(GuiPlugin.getDefault().getWorkbench().getDisplay());
660
									MacroUtil.closeSecondaryShells(GuiPlugin.getDefault().getWorkbench().getDisplay());
661
									Thread.yield();
661
									Thread.yield();
662
									synchronized(this)
662
									synchronized(this)
663
									{
663
									{
664
										try
664
										try
665
										{
665
										{
666
											wait(INCREMENT);
666
											wait(INCREMENT);
667
										}
667
										}
668
										catch (Exception e)
668
										catch (Exception e)
669
										{
669
										{
670
											
670
											
671
										}
671
										}
672
									}
672
									}
673
									
673
									
674
									count++;								
674
									count++;								
675
									outstandingShellCommandCount = MacroManager.getInstance().getOutstandShellCommands();
675
									outstandingShellCommandCount = MacroManager.getInstance().getOutstandShellCommands();
676
								}
676
								}
677
													
677
													
678
								errorOccurred = true;
678
								errorOccurred = true;
679
								isDone = true;
679
								isDone = true;
680
								
680
								
681
							}// end whlie						
681
							}// end whlie						
682
					    }
682
					    }
683
					    	
683
					    	
684
					    public boolean isDone()
684
					    public boolean isDone()
685
					    {
685
					    {
686
					    	return isDone;
686
					    	return isDone;
687
					    }
687
					    }
688
					    
688
					    
689
					    /**
689
					    /**
690
					     * Used to link the user input to datapools, custom inputs, etc...
690
					     * Used to link the user input to datapools, custom inputs, etc...
691
					     */
691
					     */
692
						private void linkUserInput(XMLDefaultHandler handler)
692
						private void linkUserInput(XMLDefaultHandler handler)
693
						{											
693
						{											
694
							Map modifiableFields = new Hashtable();
694
							Map modifiableFields = new Hashtable();
695
							getModifiableFields(handler, modifiableFields, new ArrayList());
695
							getModifiableFields(handler, modifiableFields, new ArrayList());
696
							int modifyCounter = 0, waitCounter = 0;
696
							int modifyCounter = 0, waitCounter = 0;
697
							
697
							
698
							/* For every linkable command */
698
							/* For every linkable command */
699
							for (Iterator linkableCommands = modifiableFields.keySet().iterator(); linkableCommands.hasNext();)
699
							for (Iterator linkableCommands = modifiableFields.keySet().iterator(); linkableCommands.hasNext();)
700
							{
700
							{
701
								String currentCommandType = (String)linkableCommands.next();
701
								String currentCommandType = (String)linkableCommands.next();
702
								List commandList = (List)modifiableFields.get(currentCommandType);
702
								List commandList = (List)modifiableFields.get(currentCommandType);
703
								if (commandList == null)
703
								if (commandList == null)
704
									continue;
704
									continue;
705
								
705
								
706
								for (int i = 0, commandCount = commandList.size(); i < commandCount; i++)
706
								for (int i = 0, commandCount = commandList.size(); i < commandCount; i++)
707
								{
707
								{
708
									Element currentCommand = (Element)commandList.get(i);
708
									Element currentCommand = (Element)commandList.get(i);
709
									if (currentCommand == null)
709
									if (currentCommand == null)
710
										continue;
710
										continue;
711
									
711
									
712
									String propertySuffix = "";
712
									String propertySuffix = "";
713
									if (ModifyCommand.TYPE.equals(currentCommandType))
713
									if (ModifyCommand.TYPE.equals(currentCommandType))
714
									{
714
									{
715
										modifyCounter++;
715
										modifyCounter++;
716
										propertySuffix += modifyCounter;
716
										propertySuffix += modifyCounter;
717
									}
717
									}
718
									else if (WaitCommand.TYPE.equals(currentCommandType))
718
									else if (WaitCommand.TYPE.equals(currentCommandType))
719
									{
719
									{
720
										waitCounter++;
720
										waitCounter++;
721
										propertySuffix = currentCommandType + waitCounter;
721
										propertySuffix = currentCommandType + waitCounter;
722
									}																	
722
									}																	
723
															
723
															
724
									/* First attempt datapool link */
724
									/* First attempt datapool link */
725
									String property = lastAction.getProperty(GlobalConstants.DATAPOOL_LINK_PROPERTY_BASE + propertySuffix);
725
									String property = lastAction.getProperty(GlobalConstants.DATAPOOL_LINK_PROPERTY_BASE + propertySuffix);
726
									
726
									
727
									/* No datapool link present, give user input a try */
727
									/* No datapool link present, give user input a try */
728
									if (property == null)
728
									if (property == null)
729
										property = lastAction.getProperty(GlobalConstants.CUSTOM_INPUT_LINK_PROPERTY_BASE + propertySuffix);
729
										property = lastAction.getProperty(GlobalConstants.CUSTOM_INPUT_LINK_PROPERTY_BASE + propertySuffix);
730
																									
730
																									
731
									if (property != null)
731
									if (property != null)
732
									{
732
									{
733
										String subsProperty = VariableSubstitution.getInstance().doSubstitutions(property);
733
										String subsProperty = VariableSubstitution.getInstance().doSubstitutions(property);
734
										linkUserInput ((Element)currentCommand, subsProperty);
734
										linkUserInput ((Element)currentCommand, subsProperty);
735
									}
735
									}
736
									/* Otherwise we may need to do variable substitution */
736
									/* Otherwise we may need to do variable substitution */
737
									else
737
									else
738
									{
738
									{
739
										doVarSubstitutionForModifiedField (((Element)currentCommand).getChildNodes());
739
										doVarSubstitutionForModifiedField (((Element)currentCommand).getChildNodes());
740
									}
740
									}
741
								}
741
								}
742
							}
742
							}
743
						}
743
						}
744
						
744
						
745
						private void doVariableSubstitution (XMLDefaultHandler handler)
745
						private void doVariableSubstitution (XMLDefaultHandler handler)
746
						{						
746
						{						
747
							List modifiableFields = new ArrayList(5);
747
							List modifiableFields = new ArrayList(5);
748
							getModifiableFields(handler, new Hashtable(), modifiableFields);
748
							getModifiableFields(handler, new Hashtable(), modifiableFields);
749
							
749
							
750
							/* Replace values accordingly */
750
							/* Replace values accordingly */
751
							for (int i = 0, modifiableSize = modifiableFields.size(); i < modifiableSize; i++)
751
							for (int i = 0, modifiableSize = modifiableFields.size(); i < modifiableSize; i++)
752
							{
752
							{
753
								doVarSubstitutionForModifiedField (((Element)modifiableFields.get(i)).getChildNodes());
753
								doVarSubstitutionForModifiedField (((Element)modifiableFields.get(i)).getChildNodes());
754
							}
754
							}
755
							
755
							
756
						}
756
						}
757
						
757
						
758
						
758
						
759
						private void doVarSubstitutionForModifiedField (NodeList modifyChildren)
759
						private void doVarSubstitutionForModifiedField (NodeList modifyChildren)
760
						{							
760
						{							
761
							for (int j = 0, modifyChildCount = modifyChildren.getLength(); j < modifyChildCount; j++)
761
							for (int j = 0, modifyChildCount = modifyChildren.getLength(); j < modifyChildCount; j++)
762
							{
762
							{
763
								if (modifyChildren.item(j).getNodeType() == Node.TEXT_NODE)
763
								if (modifyChildren.item(j).getNodeType() == Node.TEXT_NODE)
764
								{
764
								{
765
									Text textModifyElement = (Text)modifyChildren.item(j);
765
									Text textModifyElement = (Text)modifyChildren.item(j);
766
									String modifyCommandText = textModifyElement.getData();
766
									String modifyCommandText = textModifyElement.getData();
767
									String modifyCommandTextSubs = VariableSubstitution.getInstance().doSubstitutions(modifyCommandText);
767
									String modifyCommandTextSubs = VariableSubstitution.getInstance().doSubstitutions(modifyCommandText);
768
									
768
									
769
									if (!(modifyCommandText.equals(modifyCommandTextSubs)))
769
									if (!(modifyCommandText.equals(modifyCommandTextSubs)))
770
										textModifyElement.setData(modifyCommandTextSubs);
770
										textModifyElement.setData(modifyCommandTextSubs);
771
									break;
771
									break;
772
								}
772
								}
773
							}
773
							}
774
						}
774
						}
775
						
775
						
776
						private void getModifiableFields (XMLDefaultHandler handler, Map modifiableFields, List orderedList)
776
						private void getModifiableFields (XMLDefaultHandler handler, Map modifiableFields, List orderedList)
777
						{
777
						{
778
							Node root = handler.getDocumentElement();
778
							Node root = handler.getDocumentElement();
779
							if (root == null)
779
							if (root == null)
780
								return;
780
								return;
781
							
781
							
782
							AutoGUIUtil.walkDomTree (root.getChildNodes(), modifiableFields, orderedList);
782
							AutoGUIUtil.walkDomTree (root.getChildNodes(), modifiableFields, orderedList);
783
						}
783
						}
784
						
784
						
785
						
785
						
786
						private void linkUserInput (Element element, String newModifiedField)
786
						private void linkUserInput (Element element, String newModifiedField)
787
						{
787
						{
788
							String elementType = element.getAttribute(MacroConstants.TYPE_ATTRIBUTE);
788
							String elementType = element.getAttribute(MacroConstants.TYPE_ATTRIBUTE);
789
							
789
							
790
							/* Is the element a modify command */
790
							/* Is the element a modify command */
791
							if (ModifyCommand.TYPE.equals(elementType))
791
							if (ModifyCommand.TYPE.equals(elementType))
792
							{
792
							{
793
								NodeList modifyChildren = element.getChildNodes();
793
								NodeList modifyChildren = element.getChildNodes();
794
								boolean childChanged = false;
794
								boolean childChanged = false;
795
								for (int j = 0, modifyChildCount = modifyChildren.getLength(); j < modifyChildCount; j++)
795
								for (int j = 0, modifyChildCount = modifyChildren.getLength(); j < modifyChildCount; j++)
796
								{
796
								{
797
									if (childChanged && modifyChildren.item(j) instanceof Text)
797
									if (childChanged && modifyChildren.item(j) instanceof Text)
798
										element.removeChild(modifyChildren.item(j));
798
										element.removeChild(modifyChildren.item(j));
799
									
799
									
800
									if (modifyChildren.item(j) instanceof Text)
800
									if (modifyChildren.item(j) instanceof Text)
801
									{				
801
									{				
802
										((Text)modifyChildren.item(j)).setData(newModifiedField);
802
										((Text)modifyChildren.item(j)).setData(newModifiedField);
803
										childChanged = true;
803
										childChanged = true;
804
									}
804
									}
805
								}
805
								}
806
								
806
								
807
							}
807
							}
808
							/* Is the element a wait command */
808
							/* Is the element a wait command */
809
							else if (WaitCommand.TYPE.equals(elementType))
809
							else if (WaitCommand.TYPE.equals(elementType))
810
							{
810
							{
811
								Node timeToWaitAttribute = element.getAttributeNode(MacroConstants.TIME_TO_WAIT_ATTRIBUTE);
811
								Node timeToWaitAttribute = element.getAttributeNode(MacroConstants.TIME_TO_WAIT_ATTRIBUTE);
812
								timeToWaitAttribute.setNodeValue(newModifiedField);
812
								timeToWaitAttribute.setNodeValue(newModifiedField);
813
							}
813
							}
814
						}
814
						}
815
					}
815
					}
816
					
816
					
817
					MacroPlayWrapper macroPlayWrapper = new MacroPlayWrapper (this.getClass());
817
					MacroPlayWrapper macroPlayWrapper = new MacroPlayWrapper (this.getClass());
818
					Thread macroPlayThread = new Thread(macroPlayWrapper);
818
					Thread macroPlayThread = new Thread(macroPlayWrapper);
819
					macroPlayThread.start();
819
					macroPlayThread.start();
820
					while (!macroPlayWrapper.isDone())
820
					while (!macroPlayWrapper.isDone())
821
					{
821
					{
822
						synchronized (this.getClass())
822
						synchronized (this.getClass())
823
						{
823
						{
824
							this.getClass().wait(500);
824
							this.getClass().wait(500);
825
						}					
825
						}					
826
					}
826
					}
827
					
827
					
828
				}
828
				}
829
				
829
				
830
				/* An error occurred while attempting to run this test case */
830
				/* An error occurred while attempting to run this test case */
831
				catch (Throwable t)
831
				catch (Throwable t)
832
				{
832
				{
833
					errorOccurred = true;
833
					errorOccurred = true;
834
					String messageWithOrigin = AutoGUIUtil.getOriginOfException(t);
834
					String messageWithOrigin = AutoGUIUtil.getOriginOfException(t);
835
					
835
					
836
					/* If we are running in quick mode, then display the correct error message */
836
					/* If we are running in quick mode, then display the correct error message */
837
					if (mode == QUICK_RUN_MODE)
837
					if (mode == QUICK_RUN_MODE)
838
					{					
838
					{					
839
						String stackTrace = AutoGUIUtil.getExceptionStackTrace(t); 					
839
						String stackTrace = AutoGUIUtil.getExceptionStackTrace(t); 					
840
						String cause = messageWithOrigin + "\n" + stackTrace;
840
						String cause = messageWithOrigin + "\n" + stackTrace;
841
						
841
						
842
						AutoGUIUtil.openErrorWithDetail(
842
						AutoGUIUtil.openErrorWithDetail(
843
								Display.getDefault().getActiveShell(), 
843
								Display.getDefault().getActiveShell(), 
844
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_UNCAP_T, 
844
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_UNCAP_T, 
845
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_UNCAP, 
845
								AutoGUIMessages.AUTO_GUI_ERROR_MACRO_UNCAP, 
846
								cause);
846
								cause);
847
					}
847
					}
848
					else if (mode == EXECUTION_RUN_MODE)
848
					else if (mode == EXECUTION_RUN_MODE)
849
						sendVerdict (lastAction, VerdictEvent.VERDICT_ERROR, messageWithOrigin);
849
						sendVerdict (lastAction, VerdictEvent.VERDICT_ERROR, messageWithOrigin);
850
									
850
									
851
				}
851
				}
852
				
852
				
853
				
853
				
854
				/* If we got to this point without any errors, then pass the test case */
854
				/* If we got to this point without any errors, then pass the test case */
855
				if (!errorOccurred && lastAction != null)
855
				if (!errorOccurred && lastAction != null)
856
					sendVerdict(lastAction, VerdictEvent.VERDICT_PASS, null);
856
					sendVerdict(lastAction, VerdictEvent.VERDICT_PASS, null);
857
				
857
				
858
				/* Send out a stop event on the test case invocation */
858
				/* Send out a stop event on the test case invocation */
859
				if (mode == EXECUTION_RUN_MODE)
859
				if (mode == EXECUTION_RUN_MODE)
860
					sendTypeEvent(TypedEvent.STOP, null);
860
					sendTypeEvent(TypedEvent.STOP, null);
861
				index ++;
861
				index ++;
862
				if (index >= (nestedSuite.getActions().size()) && inTestSuite)
862
				if (index >= (nestedSuite.getActions().size()) && inTestSuite)
863
				{
863
				{
864
					sendSuiteStop();
864
					sendSuiteStop();
865
					inTestSuite=false;
865
					inTestSuite=false;
866
				}
866
				}
867
					
867
					
868
			}// end while
868
			}// end while
869
		}// end if	
869
		}// end if	
870
				
870
				
871
		if (mode == EXECUTION_RUN_MODE)
871
		if (mode == EXECUTION_RUN_MODE)
872
		{
872
		{
873
			System.out.flush();
873
			System.out.flush();
874
			System.err.flush();
874
			System.err.flush();
875
			
875
			
876
			/* Close loops if they have already not been done so */
876
			/* Close loops if they have already not been done so */
877
			while (loopStack.size() > 0)
877
			while (loopStack.size() > 0)
878
			{
878
			{
879
				sendTypeEvent(TypedEvent.STOP, null);
879
				sendTypeEvent(TypedEvent.STOP, null);
880
				loopStack.pop();
880
				loopStack.pop();
881
			}
881
			}
882
				
882
				
883
			/* Send the verdict of the test suite */
883
			/* Send the verdict of the test suite */
884
			if (initializeState != null)
884
			if (initializeState != null)
885
			{
885
			{
886
				initializeState.printStackTrace();
886
				initializeState.printStackTrace();
887
			}
887
			}
888
			
888
			
889
			VerdictEvent testSuiteVerdict = ModelUtil.DEFAULT_ARBITER.analyse();
889
			VerdictEvent testSuiteVerdict = ModelUtil.DEFAULT_ARBITER.analyse();
890
			testSuiteVerdict.setParentId("ROOT");
890
			testSuiteVerdict.setParentId("ROOT");
891
			ModelUtil.getEventLogger().log(testSuiteVerdict);
891
			ModelUtil.getEventLogger().log(testSuiteVerdict);
892
			
892
			
893
			sendTypeEvent(TypedEvent.STOP, null);
893
			sendTypeEvent(TypedEvent.STOP, null);
894
		}
894
		}
895
		else if (mode == QUICK_RUN_MODE && initializeState != null)
895
		else if (mode == QUICK_RUN_MODE && initializeState != null)
896
		{
896
		{
897
			AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_COMMON_ERROR, AutoGUIMessages.AUTO_GUI_ERROR_MACRO_INITIALIZE, initializeState);
897
			AutoGUIUtil.openErrorWithDetail(AutoGUIMessages.AUTO_GUI_COMMON_ERROR, AutoGUIMessages.AUTO_GUI_ERROR_MACRO_INITIALIZE, initializeState);
898
		}
898
		}
899
	}
899
	}
900
900
901
	
901
	
902
	private String getActionId(Object action) 
902
	private String getActionId(Object action) 
903
	{
903
	{
904
		if (action instanceof NamedElement)
904
		if (action instanceof NamedElement)
905
			return ((NamedElement)action).getId();
905
			return ((NamedElement)action).getId();
906
		
906
		
907
		return null;
907
		return null;
908
	}
908
	}
909
909
910
	private Loop getLastLoop() 
910
	private Loop getLastLoop() 
911
	{		
911
	{		
912
		if (loopStack.size() <= 0)
912
		if (loopStack.size() <= 0)
913
			return null;
913
			return null;
914
		
914
		
915
		return (Loop)loopStack.peek();
915
		return (Loop)loopStack.peek();
916
	}
916
	}
917
917
918
	
918
	
919
	/**
919
	/**
920
	 * Used to do the required initialization prior to the beginning
920
	 * Used to do the required initialization prior to the beginning
921
	 * of a test run.
921
	 * of a test run.
922
	 * @throws CoreException 
922
	 * @throws CoreException 
923
	 */
923
	 */
924
	private void initializeTestRun(byte mode) throws CoreException 
924
	private void initializeTestRun(byte mode) throws CoreException 
925
	{
925
	{
926
		/* A good time to initialize the variables declared in VariableSubstitution */
926
		/* A good time to initialize the variables declared in VariableSubstitution */
927
		initializeVariable(extendedTestSuite, mode);
927
		initializeVariable(extendedTestSuite, mode);
928
		
928
		
929
		/* Tag the existing shells so that they don't accidently get closed when the macro playback
929
		/* Tag the existing shells so that they don't accidently get closed when the macro playback
930
		 * closes nested shells in the case of an error */
930
		 * closes nested shells in the case of an error */
931
		final Display currentDisplay = GuiPlugin.getDefault().getWorkbench().getDisplay(); 
931
		final Display currentDisplay = GuiPlugin.getDefault().getWorkbench().getDisplay(); 
932
		currentDisplay.syncExec(new Runnable(){
932
		currentDisplay.syncExec(new Runnable(){
933
933
934
			public void run() 
934
			public void run() 
935
			{
935
			{
936
				Shell[] openedShells = currentDisplay.getShells();
936
				Shell[] openedShells = currentDisplay.getShells();
937
				for (int i = 0; i < openedShells.length; i++)
937
				for (int i = 0; i < openedShells.length; i++)
938
				{
938
				{
939
					openedShells[i].setData(GlobalConstants.OPENED_SHELL_INDICATOR, Boolean.TRUE);
939
					openedShells[i].setData(GlobalConstants.OPENED_SHELL_INDICATOR, Boolean.TRUE);
940
				}
940
				}
941
				
941
				
942
			}});
942
			}});
943
		
943
		
944
		/* Retrieve the object mine of the test suite */
944
		/* Retrieve the object mine of the test suite */
945
		String objectMineXML = null;
945
		String objectMineXML = null;
946
		if (mode == QUICK_RUN_MODE && testSuiteEMF != null)
946
		if (mode == QUICK_RUN_MODE && testSuiteEMF != null)
947
		{
947
		{
948
			objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteEMF, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
948
			objectMineXML = HyadesUtil.getTestSuiteVariable(testSuiteEMF, GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
949
		}
949
		}
950
		else if (mode == EXECUTION_RUN_MODE)
950
		else if (mode == EXECUTION_RUN_MODE)
951
		{
951
		{
952
			GeneralPropertyRetriever properties = extendedTestSuite.getProperties();
952
			GeneralPropertyRetriever properties = extendedTestSuite.getProperties();
953
			objectMineXML = properties == null ? null : (String)properties.getProperty(GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
953
			objectMineXML = properties == null ? null : (String)properties.getProperty(GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
954
		}	
954
		}	
955
		
955
		
956
		if (objectMineXML != null)
956
		if (objectMineXML != null)
957
		{
957
		{
958
			MacroManager.getInstance().prepareForPlayBack(objectMineXML);
958
			MacroManager.getInstance().prepareForPlayBack(objectMineXML);
959
		}
959
		}
960
		
960
		
961
	}
961
	}
962
	/**
962
	/**
963
	 * Initialize the variables decalred in VariableSubstitution
963
	 * Initialize the variables decalred in VariableSubstitution
964
	 */
964
	 */
965
	private void initializeVariable(ExtendedTestSuite testSuite, byte mode) 
965
	private void initializeVariable(ExtendedTestSuite testSuite, byte mode) 
966
	{
966
	{
967
		Hashtable variableContainer = VariableSubstitution.getInstance().getVariableContainer();
967
		Hashtable variableContainer = VariableSubstitution.getInstance().getVariableContainer();
968
		Variable contextWorkbenchVar = (Variable)variableContainer.get(VariableSubstitution.VAR_CONTEXT_WORKSPACE);
968
		Variable contextWorkbenchVar = (Variable)variableContainer.get(VariableSubstitution.VAR_CONTEXT_WORKSPACE);
969
		contextWorkbenchVar.initialize(AutoGUIUtil.getWorkspaceLocation());
969
		contextWorkbenchVar.initialize(AutoGUIUtil.getWorkspaceLocation());
970
		
970
		
971
		Variable projectLocationVar = (Variable)variableContainer.get(VariableSubstitution.VAR_PROJECT_LOCATION);
971
		Variable projectLocationVar = (Variable)variableContainer.get(VariableSubstitution.VAR_PROJECT_LOCATION);
972
		
972
		
973
		/* If we're running in standard mode, then the value of this variable is expected to be defined as
973
		/* If we're running in standard mode, then the value of this variable is expected to be defined as
974
		 * a property of our test suite */
974
		 * a property of our test suite */
975
		String projectLocation = null;
975
		String projectLocation = null;
976
		if (mode == EXECUTION_RUN_MODE)
976
		if (mode == EXECUTION_RUN_MODE)
977
		{
977
		{
978
			GeneralPropertyRetriever properties = testSuite.getProperties();
978
			GeneralPropertyRetriever properties = testSuite.getProperties();
979
			projectLocation = (String)properties.getProperty(GlobalConstants.TEST_SUITE_PROPERTY_BASE + "0");
979
			projectLocation = (String)properties.getProperty(GlobalConstants.TEST_SUITE_PROPERTY_BASE + "0");
980
		}
980
		}
981
		/* In quick mode, we have to retrieve the value of the variable */
981
		/* In quick mode, we have to retrieve the value of the variable */
982
		else if (mode == QUICK_RUN_MODE && testSuiteEMF != null)
982
		else if (mode == QUICK_RUN_MODE && testSuiteEMF != null)
983
		{
983
		{
984
			projectLocation =  AutoGUIUtil.getTestSuiteProjectLocation(testSuiteEMF);	
984
			projectLocation =  AutoGUIUtil.getTestSuiteProjectLocation(testSuiteEMF);	
985
		}
985
		}
986
		
986
		
987
		if (projectLocation != null)
987
		if (projectLocation != null)
988
			projectLocationVar.initialize(projectLocation);		
988
			projectLocationVar.initialize(projectLocation);		
989
	}
989
	}
990
	
990
	
991
991
992
	/**
992
	/**
993
	 * Returns the id of the last execution event detected
993
	 * Returns the id of the last execution event detected
994
	 */
994
	 */
995
	private String lastExecutionEventId()
995
	private String lastExecutionEventId()
996
	{
996
	{
997
		if (executionEventStack.size() <= 0)
997
		if (executionEventStack.size() <= 0)
998
			return "ROOT";
998
			return "ROOT";
999
		return ((ExecutionEvent)executionEventStack.peek()).getId();
999
		return ((ExecutionEvent)executionEventStack.peek()).getId();
1000
		
1000
		
1001
	}
1001
	}
1002
	
1002
	
1003
	
1003
	
1004
	/**
1004
	/**
1005
	 * Returns the last container id according to what is stored in the
1005
	 * Returns the last container id according to what is stored in the
1006
	 * execution event stack.  A container is either a loop or the ROOT. It could also be a nested test suite invocation
1006
	 * execution event stack.  A container is either a loop or the ROOT. It could also be a nested test suite invocation
1007
	 * 
1007
	 * 
1008
	 * @return The last container id.
1008
	 * @return The last container id.
1009
	 */
1009
	 */
1010
	private String lastContainerId()
1010
	private String lastContainerId()
1011
	{
1011
	{
1012
		/* Walk through the stack and find the container */
1012
		/* Walk through the stack and find the container */
1013
		Object[] stackItems = executionEventStack.toArray();
1013
		Object[] stackItems = executionEventStack.toArray();
1014
		for (int i = stackItems.length - 1; i >= 0 ; i--)
1014
		for (int i = stackItems.length - 1; i >= 0 ; i--)
1015
		{
1015
		{
1016
			if (stackItems[i] instanceof LoopEvent)
1016
			if (stackItems[i] instanceof LoopEvent)
1017
				return ((LoopEvent)stackItems[i]).getId();
1017
				return ((LoopEvent)stackItems[i]).getId();
1018
			else if (stackItems[i] instanceof InvocationEvent){
1018
			else if (stackItems[i] instanceof InvocationEvent){
1019
				return ((InvocationEvent)stackItems[i]).getId();
1019
				return ((InvocationEvent)stackItems[i]).getId();
1020
			}
1020
			}
1021
		}
1021
		}
1022
		return "ROOT";
1022
		return "ROOT";
1023
	}
1023
	}
1024
	
1024
	
1025
	
1025
	
1026
	/**
1026
	/**
1027
	 * Sends typed events representing start/stop events for the last event on
1027
	 * Sends typed events representing start/stop events for the last event on
1028
	 * the execution event stack.
1028
	 * the execution event stack.
1029
	 */
1029
	 */
1030
	private void sendTypeEvent(int type, String text)
1030
	private void sendTypeEvent(int type, String text)
1031
	{			
1031
	{			
1032
		TypedEvent event = new TypedEvent();
1032
		TypedEvent event = new TypedEvent();
1033
		String parentId = lastExecutionEventId();
1033
		String parentId = lastExecutionEventId();
1034
                                                                                                          		if (executionEventStack.size() > 0)
1034
                                                                                                          		if (executionEventStack.size() > 0)
1035
			event.setOwnerId(((ExecutionEvent)executionEventStack.peek()).getOwnerId());
1035
			event.setOwnerId(((ExecutionEvent)executionEventStack.peek()).getOwnerId());
1036
		event.setParentId(parentId);
1036
		event.setParentId(parentId);
1037
		event.setType(type);
1037
		event.setType(type);
1038
		
1038
		
1039
		ModelUtil.getEventLogger().log(event);
1039
		ModelUtil.getEventLogger().log(event);
1040
		
1040
		
1041
		if (type == TypedEvent.STOP && executionEventStack.size() > 0)
1041
		if (type == TypedEvent.STOP && executionEventStack.size() > 0)
1042
			executionEventStack.pop();
1042
			executionEventStack.pop();
1043
	}
1043
	}
1044
	
1044
	
1045
	/**
1045
	/**
1046
	 * Added for bugzilla_136186 in order to send an additional Stop event for a test suite
1046
	 * Added for bugzilla_136186 in order to send an additional Stop event for a test suite
1047
	 */
1047
	 */
1048
	private void sendSuiteStop()
1048
	private void sendSuiteStop()
1049
	{
1049
	{
1050
		sendTypeEvent(TypedEvent.STOP, null);
1050
		sendTypeEvent(TypedEvent.STOP, null);
1051
1051
1052
	}
1052
	}
1053
	/**
1053
	/**
1054
	 * Sends a loop event
1054
	 * Sends a loop event
1055
	 */
1055
	 */
1056
	private void sendLoopStart (Loop loop)
1056
	private void sendLoopStart (Loop loop)
1057
	{	
1057
	{	
1058
		loopNumbersDetected++;		
1058
		loopNumbersDetected++;		
1059
		
1059
		
1060
		LoopEvent loopEvent = new LoopEvent();
1060
		LoopEvent loopEvent = new LoopEvent();
1061
		loopEvent.setIterations(loop.getIterations());
1061
		loopEvent.setIterations(loop.getIterations());
1062
		associateEventIds(loop, loopEvent);
1062
		associateEventIds(loop, loopEvent);
1063
		
1063
		
1064
		ModelUtil.getEventLogger().log(loopEvent);
1064
		ModelUtil.getEventLogger().log(loopEvent);
1065
		sendTypeEvent (TypedEvent.START, null);
1065
		sendTypeEvent (TypedEvent.START, null);
1066
		loopStack.push(loop);
1066
		loopStack.push(loop);
1067
	}
1067
	}
1068
	
1068
	
1069
	private void sendLoopStop ()
1069
	private void sendLoopStop ()
1070
	{
1070
	{
1071
		sendTypeEvent(TypedEvent.STOP, null);
1071
		sendTypeEvent(TypedEvent.STOP, null);
1072
		loopStack.pop();
1072
		loopStack.pop();
1073
	}
1073
	}
1074
		
1074
		
1075
	
1075
	
1076
	private void sendAllLoopStop ()
1076
	private void sendAllLoopStop ()
1077
	{
1077
	{
1078
		while (loopStack.size() > 0)
1078
		while (loopStack.size() > 0)
1079
		{
1079
		{
1080
			sendLoopStop();
1080
			sendLoopStop();
1081
		}
1081
		}
1082
	}
1082
	}
1083
1083
1084
	/**
1084
	/**
1085
	 * Sends a test invocation event
1085
	 * Sends a test invocation event
1086
	 * 
1086
	 * 
1087
	 * @param testInvocation
1087
	 * @param testInvocation
1088
	 * @param status
1088
	 * @param status
1089
	 * @param text
1089
	 * @param text
1090
	 */
1090
	 */
1091
	private void sendTestInvocation (TestInvocation testInvocation, int status, String text)
1091
	private void sendTestInvocation (TestInvocation testInvocation, int status, String text)
1092
	{
1092
	{
1093
		invocationNumbersDetected++;		
1093
		invocationNumbersDetected++;		
1094
		
1094
		
1095
		InvocationEvent event = new InvocationEvent();
1095
		InvocationEvent event = new InvocationEvent();
1096
		associateEventIds(testInvocation, event);
1096
		associateEventIds(testInvocation, event);
1097
1097
1098
		
1098
		
1099
		
1099
		
1100
		if(testInvocation.getTest() == null)
1100
		if(testInvocation.getTest() == null)
1101
		{
1101
		{
1102
			event.setStatus(InvocationEvent.STATUS_UNSUCCESSFUL);
1102
			event.setStatus(InvocationEvent.STATUS_UNSUCCESSFUL);
1103
			event.setReason(InvocationEvent.REASON_NO_BEHAVIOR);
1103
			event.setReason(InvocationEvent.REASON_NO_BEHAVIOR);
1104
			
1104
			
1105
		}
1105
		}
1106
		else
1106
		else
1107
		{
1107
		{
1108
			event.setInvokedId(ModelUtil.appendHierarchyId(testInvocation.getTest(), event.getOwnerId()));
1108
			event.setInvokedId(ModelUtil.appendHierarchyId(testInvocation.getTest(), event.getOwnerId()));
1109
			event.setStatus(status);
1109
			event.setStatus(status);
1110
			
1110
			
1111
			
1111
			
1112
		}	
1112
		}	
1113
		
1113
		
1114
		ModelUtil.getEventLogger().log(event);
1114
		ModelUtil.getEventLogger().log(event);
1115
		sendTypeEvent (TypedEvent.START, null);
1115
		sendTypeEvent (TypedEvent.START, null);
1116
	}
1116
	}
1117
	
1117
	
1118
1118
1119
	/**
1119
	/**
1120
	 * Associates a verdict with a test test invocation.
1120
	 * Associates a verdict with a test test invocation.
1121
	 * 
1121
	 * 
1122
	 * @param testInvocation The test invocation
1122
	 * @param testInvocation The test invocation
1123
	 * @param verdict Can either be VerdictEvent.VERDICT_PASS, VerdictEvent.VERDICT_FAIL, 
1123
	 * @param verdict Can either be VerdictEvent.VERDICT_PASS, VerdictEvent.VERDICT_FAIL, 
1124
	 * VerdictEvent.VERDICT_ERROR
1124
	 * VerdictEvent.VERDICT_ERROR
1125
	 * @param reason The reason for the verdict.  Can be null.
1125
	 * @param reason The reason for the verdict.  Can be null.
1126
	 */
1126
	 */
1127
	private void sendVerdict (TestInvocation testInvocation, int verdict, String reason)
1127
	private void sendVerdict (TestInvocation testInvocation, int verdict, String reason)
1128
	{
1128
	{
1129
		VerdictEvent verdictEvent = ModelUtil.createTestVerdictEvent(testInvocation);
1129
		VerdictEvent verdictEvent = ModelUtil.createTestVerdictEvent(testInvocation);
1130
				
1130
				
1131
		/* We're expected to have a test invocation on our stack */
1131
		/* We're expected to have a test invocation on our stack */
1132
		if (executionEventStack.size() <= 0 && !(executionEventStack.peek() instanceof InvocationEvent) && lastAction == null)
1132
		if (executionEventStack.size() <= 0 && !(executionEventStack.peek() instanceof InvocationEvent) && lastAction == null)
1133
			return;			/* Should never happen */
1133
			return;			/* Should never happen */
1134
		
1134
		
1135
		/* Determine the ids: 
1135
		/* Determine the ids: 
1136
		 * 	- The id is the same as the invocation id appended with '_verdict'
1136
		 * 	- The id is the same as the invocation id appended with '_verdict'
1137
		 *  - The owner id is the id of the test from the test invocation
1137
		 *  - The owner id is the id of the test from the test invocation
1138
		 *  - The parent id is the id of the test invocation
1138
		 *  - The parent id is the id of the test invocation
1139
		 */
1139
		 */
1140
		InvocationEvent invocationEvent = (InvocationEvent)executionEventStack.peek();
1140
		InvocationEvent invocationEvent = (InvocationEvent)executionEventStack.peek();
1141
		verdictEvent.setId(invocationEvent.getId() + "_verdict");
1141
		verdictEvent.setId(invocationEvent.getId() + "_verdict");
1142
		//verdictEvent.setOwnerId(ModelUtil.getHierarchyId(lastAction.getTest()));
1142
		//verdictEvent.setOwnerId(ModelUtil.getHierarchyId(lastAction.getTest()));
1143
		verdictEvent.setParentId(invocationEvent.getId());
1143
		verdictEvent.setParentId(invocationEvent.getId());
1144
		verdictEvent.setVerdict(verdict);				
1144
		verdictEvent.setVerdict(verdict);				
1145
		verdictEvent.setOwnerId(invocationEvent.getId());
1145
		verdictEvent.setOwnerId(invocationEvent.getId());
1146
		
1146
		
1147
		if(reason != null && reason.trim().length() > 0)
1147
		if(reason != null && reason.trim().length() > 0)
1148
		{
1148
		{
1149
			verdictEvent.setText(reason);
1149
			verdictEvent.setText(reason);
1150
			verdictEvent.setReason(VerdictEvent.REASON_SEE_DESCRIPTION);
1150
			verdictEvent.setReason(VerdictEvent.REASON_SEE_DESCRIPTION);
1151
		}
1151
		}
1152
		ModelUtil.getEventLogger().log(verdictEvent);
1152
		ModelUtil.getEventLogger().log(verdictEvent);
1153
		testInvocation.setVerdictEvent(verdictEvent);
1153
		testInvocation.setVerdictEvent(verdictEvent);
1154
	}
1154
	}
1155
	
1155
	
1156
	
1156
	
1157
	/**
1157
	/**
1158
	 * A helper method used to associate id, parentId, ownerId to the event.
1158
	 * A helper method used to associate id, parentId, ownerId to the event.
1159
	 * 
1159
	 * 
1160
	 * @param event
1160
	 * @param event
1161
	 * @param type 0 indicates loop, 1 indicates test invocation  
1161
	 * @param type 0 indicates loop, 1 indicates test invocation  
1162
	 */
1162
	 */
1163
	private void associateEventIds(NamedElement namedElement, ExecutionEvent event)
1163
	private void associateEventIds(NamedElement namedElement, ExecutionEvent event)
1164
	{
1164
	{
1165
		String ownerId = namedElement.getId();
1165
		String ownerId = namedElement.getId();
1166
		String eventId = (namedElement instanceof Loop ? ownerId + "(" + loopNumbersDetected + ")" : ownerId + "(" + invocationNumbersDetected + ")");
1166
		String eventId = (namedElement instanceof Loop ? ownerId + "(" + loopNumbersDetected + ")" : ownerId + "(" + invocationNumbersDetected + ")");
1167
		String parentId = lastContainerId();
1167
		String parentId = lastContainerId();
1168
1168
1169
		event.setOwnerId(ownerId);
1169
		event.setOwnerId(ownerId);
1170
		event.setId(eventId);
1170
		event.setId(eventId);
1171
		event.setParentId(parentId);
1171
		event.setParentId(parentId);
1172
	
1172
	
1173
		
1173
		
1174
		executionEventStack.push(event);
1174
		executionEventStack.push(event);
1175
	}
1175
	}
1176
	
1176
	
1177
	/**
1177
	/**
1178
	 * Returns the next execution based on the mode that we're running in. The first 
1178
	 * Returns the next execution based on the mode that we're running in. The first 
1179
	 * execution in quick mode is the test case in the testSuite argument passed in 
1179
	 * execution in quick mode is the test case in the testSuite argument passed in 
1180
	 * and in the execution mode, it is the next test invocation
1180
	 * and in the execution mode, it is the next test invocation
1181
	 * 
1181
	 * 
1182
	 * @return The next element to be executed
1182
	 * @return The next element to be executed
1183
	 */
1183
	 */
1184
	private Object nextExecution (byte mode, TestSuite testSuite)
1184
	private Object nextExecution (byte mode, TestSuite testSuite)
1185
	{
1185
	{
1186
		Object nextExecution = null;
1186
		Object nextExecution = null;
1187
		
1187
		
1188
		if (mode == QUICK_RUN_MODE)
1188
		if (mode == QUICK_RUN_MODE)
1189
		{
1189
		{
1190
			int testCaseSize = testSuite.getTestCases().size();
1190
			int testCaseSize = testSuite.getTestCases().size();
1191
			if (currentTestCaseInx >= 0 && currentTestCaseInx < testCaseSize)
1191
			if (currentTestCaseInx >= 0 && currentTestCaseInx < testCaseSize)
1192
			{
1192
			{
1193
				nextExecution = testSuite.getTestCases().get(currentTestCaseInx);
1193
				nextExecution = testSuite.getTestCases().get(currentTestCaseInx);
1194
				currentTestCaseInx++;
1194
				currentTestCaseInx++;
1195
			}			
1195
			}			
1196
		}			
1196
		}			
1197
		else if (mode == EXECUTION_RUN_MODE)
1197
		else if (mode == EXECUTION_RUN_MODE)
1198
		{
1198
		{
1199
			if (!isActionIteratorStackInitialized)
1199
			if (!isActionIteratorStackInitialized)
1200
			{
1200
			{
1201
				actionIteratorStack.push(ModelUtil.DEFAULT_EXECUTION_MANAGER.getRoot().getActions().iterator());
1201
				actionIteratorStack.push(ModelUtil.DEFAULT_EXECUTION_MANAGER.getRoot().getActions().iterator());
1202
				isActionIteratorStackInitialized = true;
1202
				isActionIteratorStackInitialized = true;
1203
			}
1203
			}
1204
			if (actionIteratorStack.size() > 0)
1204
			if (actionIteratorStack.size() > 0)
1205
				nextExecution = getNextExecutableAction();
1205
				nextExecution = getNextExecutableAction();
1206
		}
1206
		}
1207
		
1207
		
1208
		return nextExecution;
1208
		return nextExecution;
1209
	}
1209
	}
1210
	
1210
	
1211
	private Object getNextExecutableAction() 
1211
	private Object getNextExecutableAction() 
1212
	{
1212
	{
1213
		if (actionIteratorStack.size() <= 0)
1213
		if (actionIteratorStack.size() <= 0)
1214
			return null;
1214
			return null;
1215
		
1215
		
1216
		Iterator actionIterator = (Iterator)actionIteratorStack.peek();
1216
		Iterator actionIterator = (Iterator)actionIteratorStack.peek();
1217
		if (actionIterator.hasNext())
1217
		if (actionIterator.hasNext())
1218
		{
1218
		{
1219
			Object nextExecutableAction = actionIterator.next();
1219
			Object nextExecutableAction = actionIterator.next();
1220
			if (nextExecutableAction instanceof Loop)
1220
			if (nextExecutableAction instanceof Loop)
1221
			{
1221
			{
1222
				actionIteratorStack.push(((Loop)nextExecutableAction).getActions().iterator());
1222
				actionIteratorStack.push(((Loop)nextExecutableAction).getActions().iterator());
1223
			}
1223
			}
1224
					
1224
					
1225
			return nextExecutableAction;
1225
			return nextExecutableAction;
1226
		}
1226
		}
1227
		else
1227
		else
1228
		{
1228
		{
1229
			actionIteratorStack.pop();
1229
			actionIteratorStack.pop();
1230
			return getNextExecutableAction();
1230
			return getNextExecutableAction();
1231
		}
1231
		}
1232
	}
1232
	}
1233
1233
1234
	/**
1234
	/**
1235
	 * Runs a verificaiton hook
1235
	 * Runs a verification hook
1236
	 * 
1236
	 * 
1237
	 * @param verfHook The verification hook
1237
	 * @param verfHook The verification hook
1238
	 */
1238
	 */
1239
	public void runVerificaitonHook(IHyadesTest verificationHook)
1239
	public void runVerificationHook(IHyadesTest verificationHook)
1240
	{
1240
	{
1241
		/* Set the root, if it hasn't already been set */
1241
		/* Set the root, if it hasn't already been set */
1242
		if (super.getRoot() == null)
1242
		if (super.getRoot() == null)
1243
			super.setRoot (verificationHook);
1243
			super.setRoot (verificationHook);
1244
1244
1245
		TestResult result = super.createTestResult();
1245
		TestResult result = super.createTestResult();
1246
		result.addListener(this);
1246
		result.addListener(this);
1247
1247
1248
		verificationHook.run(result);
1248
		verificationHook.run(result);
1249
	}
1249
	}
1250
	
1250
	
1251
	
1251
	
1252
	/**
1252
	/**
1253
	 * Parses the test script and does the appropriate initializations
1253
	 * Parses the test script and does the appropriate initializations
1254
	 * 
1254
	 * 
1255
	 * @throws Exception 
1255
	 * @throws Exception 
1256
	 * @throws UnsupportedEncodingException 
1256
	 * @throws UnsupportedEncodingException 
1257
	 */
1257
	 */
1258
	protected TestSuite parseTestScript() throws UnsupportedEncodingException, Exception
1258
	protected TestSuite parseTestScript() throws UnsupportedEncodingException, Exception
1259
	{
1259
	{
1260
		TestInvocation.addListener(ModelUtil.DEFAULT_EXECUTION_MANAGER);
1260
		TestInvocation.addListener(ModelUtil.DEFAULT_EXECUTION_MANAGER);
1261
		
1261
		
1262
		ExtendedScriptParser scriptParser = new ExtendedScriptParser();
1262
		ExtendedScriptParser scriptParser = new ExtendedScriptParser();
1263
		TestSuite testSuite = scriptParser.parse(testScript.getBytes("UTF-8"));
1263
		TestSuite testSuite = scriptParser.parse(testScript.getBytes("UTF-8"));
1264
		
1264
		
1265
		if(testSuite == null)
1265
		if(testSuite == null)
1266
		{
1266
		{
1267
			System.err.println("\n" + testScript);
1267
			System.err.println("\n" + testScript);
1268
			throw new IllegalArgumentException(AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_SCRIPT);
1268
			throw new IllegalArgumentException(AutoGUIMessages.AUTO_GUI_ERROR_PLAYBACK_SCRIPT);
1269
		}
1269
		}
1270
		
1270
		
1271
		ModelUtil.DEFAULT_EXECUTION_MANAGER.setRoot(testSuite);
1271
		ModelUtil.DEFAULT_EXECUTION_MANAGER.setRoot(testSuite);
1272
		ModelUtil.DEFAULT_EXECUTION_MANAGER.registerTestInvocations(scriptParser.getTestInvocations());
1272
		ModelUtil.DEFAULT_EXECUTION_MANAGER.registerTestInvocations(scriptParser.getTestInvocations());
1273
		ModelUtil.setVerdicts(scriptParser.getVerdicts());
1273
		ModelUtil.setVerdicts(scriptParser.getVerdicts());
1274
	
1274
	
1275
		scriptParser.dispose();
1275
		scriptParser.dispose();
1276
		
1276
		
1277
		return testSuite;
1277
		return testSuite;
1278
	}
1278
	}
1279
	
1279
	
1280
	
1280
	
1281
	/**
1281
	/**
1282
	 * Returns the test script
1282
	 * Returns the test script
1283
	 * 
1283
	 * 
1284
	 * @return The test script
1284
	 * @return The test script
1285
	 */
1285
	 */
1286
	protected String getTestScript()
1286
	protected String getTestScript()
1287
	{
1287
	{
1288
		return testScript;
1288
		return testScript;
1289
	}
1289
	}
1290
	
1290
	
1291
	
1291
	
1292
	/**
1292
	/**
1293
	 * Set the test script
1293
	 * Set the test script
1294
	 * 
1294
	 * 
1295
	 * @param data The data for the test script
1295
	 * @param data The data for the test script
1296
	 */
1296
	 */
1297
	protected void setTestScript(byte[] data)
1297
	protected void setTestScript(byte[] data)
1298
	{
1298
	{
1299
		try
1299
		try
1300
		{
1300
		{
1301
			testScript = new String(data, "UTF-8");
1301
			testScript = new String(data, "UTF-8");
1302
		}
1302
		}
1303
		catch (UnsupportedEncodingException e)
1303
		catch (UnsupportedEncodingException e)
1304
		{
1304
		{
1305
		}
1305
		}
1306
	}
1306
	}
1307
	
1307
	
1308
	/**
1308
	/**
1309
	 * Overwrite the methods that are invoked when the verification hook result is being
1309
	 * Overwrite the methods that are invoked when the verification hook result is being
1310
	 * reported. 
1310
	 * reported. 
1311
	 */
1311
	 */
1312
	protected VerdictEvent getDefaultVerdictEvent(Test test)
1312
	protected VerdictEvent getDefaultVerdictEvent(Test test)
1313
	{
1313
	{
1314
		/* We don't need to do anything here, because by default a verdict on the
1314
		/* We don't need to do anything here, because by default a verdict on the
1315
		 * overall test case will be send. */
1315
		 * overall test case will be send. */
1316
		return null;
1316
		return null;
1317
	}
1317
	}
1318
1318
1319
	
1319
	
1320
	public void addError(Test test, Throwable throwable)
1320
	public void addError(Test test, Throwable throwable)
1321
	{
1321
	{
1322
		if (runningMode == EXECUTION_RUN_MODE && lastAction != null)
1322
		if (runningMode == EXECUTION_RUN_MODE && lastAction != null)
1323
		{
1323
		{
1324
			errorOccurred = true;
1324
			errorOccurred = true;
1325
			sendVerdict(lastAction, VerdictEvent.VERDICT_ERROR, BaseString.getStackTrace(throwable));
1325
			sendVerdict(lastAction, VerdictEvent.VERDICT_ERROR, BaseString.getStackTrace(throwable));
1326
		}
1326
		}
1327
	}
1327
	}
1328
	
1328
	
1329
	
1329
	
1330
	public void addFailure(Test test, AssertionFailedError throwable)
1330
	public void addFailure(Test test, AssertionFailedError throwable)
1331
	{
1331
	{
1332
		if (runningMode == EXECUTION_RUN_MODE && lastAction != null)
1332
		if (runningMode == EXECUTION_RUN_MODE && lastAction != null)
1333
		{
1333
		{
1334
			errorOccurred = true;
1334
			errorOccurred = true;
1335
			sendVerdict(lastAction, VerdictEvent.VERDICT_FAIL, BaseString.getStackTrace(throwable));
1335
			sendVerdict(lastAction, VerdictEvent.VERDICT_FAIL, BaseString.getStackTrace(throwable));
1336
		}
1336
		}
1337
	}
1337
	}
1338
	
1338
	
1339
	
1339
	
1340
	/**
1340
	/**
1341
	 * These methods are over-written to diable the Junit runner from sending anything to
1341
	 * These methods are over-written to diable the Junit runner from sending anything to
1342
	 * our agent.
1342
	 * our agent.
1343
	 */
1343
	 */
1344
	protected void runnerExit(boolean runnerStopped, long elapsedTime) {}
1344
	protected void runnerExit(boolean runnerStopped, long elapsedTime) {}
1345
	public void startTest(Test test) {}
1345
	public void startTest(Test test) {}
1346
	public void endTest(Test test) {}
1346
	public void endTest(Test test) {}
1347
	
1347
	
1348
	/**
1348
	/**
1349
	 * A primitive interface used to notify the status of the test runs to a caller that invokes
1349
	 * A primitive interface used to notify the status of the test runs to a caller that invokes
1350
	 * this test runner.
1350
	 * this test runner.
1351
	 * 
1351
	 * 
1352
	 * @author Ali Mehregani
1352
	 * @author Ali Mehregani
1353
	 */
1353
	 */
1354
	public interface ITestRunnerDelegator
1354
	public interface ITestRunnerDelegator
1355
	{
1355
	{
1356
		/**
1356
		/**
1357
		 * Invoked to indicate the end of a test suite run 
1357
		 * Invoked to indicate the end of a test suite run 
1358
		 */
1358
		 */
1359
		public void finishedTestRun();
1359
		public void finishedTestRun();
1360
	}
1360
	}
1361
1361
1362
}
1362
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverToUIObjectResolverDelegateAdapter.java (+48 lines)
Added Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.core;
2
3
4
import org.eclipse.core.runtime.CoreException;
5
import org.eclipse.swt.widgets.Control;
6
import org.eclipse.swt.widgets.MenuItem;
7
import org.eclipse.swt.widgets.Widget;
8
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
9
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
10
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
11
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate;
12
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade;
13
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport;
14
15
public class WidgetResolverToUIObjectResolverDelegateAdapter implements
16
		IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade {
17
18
	private IWidgetResolver widgetResolver = null;
19
20
	public WidgetResolverToUIObjectResolverDelegateAdapter(IWidgetResolver widgetResolver) {
21
		super();
22
		this.widgetResolver = widgetResolver;
23
	}
24
25
	public boolean foundWidget(Widget object, IUIObjectIdentifier objectId) {
26
		return widgetResolver.foundWidget(object, objectId.getWidgetId());
27
	}
28
29
	public IUIObject deresolve(Object context,
30
			IUIObjectIdentifier uiObjectIdentifier) throws CoreException {
31
		return UIObjectDeprecatedDeresolvingSupport.deresolve(context,
32
				uiObjectIdentifier);
33
	}
34
35
	public IUIObjectIdentifier resolve(Object context, IUIObject uiObject)
36
			throws CoreException {
37
		
38
		IWidgetId widgetId = null;
39
		if(uiObject.getObject() == null){
40
			widgetId = widgetResolver.getUniqueId(uiObject.getWidget() instanceof Control ? ((Control)uiObject.getWidget()).getParent() : null, uiObject.getWidget());
41
		}
42
		else{
43
			widgetId = widgetResolver.getUniqueId(uiObject.getWidget(), uiObject.getObject());
44
		}
45
		return widgetId == null ? null : new PrimitiveUIObjectIdentifier(widgetId.toString(), widgetId.getResolverId());
46
	}
47
48
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/util/VerificationHookClassLoader.java (+104 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: VerificationHookClassLoader.java,v 1.2 2006/07/14 23:17:02 amehregani Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.util;
13
14
import java.net.URL;
15
import java.net.URLClassLoader;
16
import java.util.Vector;
17
18
import org.eclipse.core.runtime.Platform;
19
import org.eclipse.osgi.util.NLS;
20
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
21
22
/**
23
 * A custom class loader that is used to resolve a class that the verificaiton hook is in along
24
 * with any other classes that are imported by the verification class.
25
 * 
26
 * @author Ali Mehregani
27
 */
28
public class VerificationHookClassLoader extends URLClassLoader
29
{
30
	/* The plugins that the verification plugin requires */
31
	private Vector reqPluginNames;
32
	
33
	public VerificationHookClassLoader (URL[] urls, ClassLoader parent, Vector requiredPluginNames)
34
	{
35
		super (urls, parent);		
36
		reqPluginNames = requiredPluginNames;
37
	}
38
	
39
   
40
	/**
41
	 * Invoked when a class can't be resolved by the upper level class loaders associated with
42
	 * this class.
43
	 */
44
	protected Class findClass(final String name) 
45
	 throws ClassNotFoundException 			 
46
    {  	
47
		
48
    	/* Try and walk through the required plugins of the plugin
49
    	 * containing the test suite */
50
    	try
51
    	{			
52
    		Class classFile = loadFromReqPlugins(name, 0);
53
    		if (classFile != null)
54
    			return classFile;
55
    	}
56
    	catch (Throwable t)
57
    	{
58
    		/* Doesn't need to be handled */
59
    	}
60
    	
61
		
62
		try
63
		{
64
			Class classFile = super.findClass(name);
65
			if (classFile != null)
66
				return classFile;
67
		}
68
		catch (Throwable t)
69
		{
70
			/* Doesn't need to be handled */
71
		}
72
		
73
	    		    	
74
    	
75
    	throw new ClassNotFoundException (NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_VER_CLASS_NOT_FS, name));
76
    }
77
78
79
	/**
80
	 * Attempt to load the class from the required plugins.
81
	 * 
82
	 * @param name
83
	 * @param inx
84
	 * @return
85
	 */
86
	private Class loadFromReqPlugins(String name, int inx)
87
	{
88
		try
89
		{
90
			if (reqPluginNames == null || inx >= reqPluginNames.size())
91
				return null;
92
			
93
			Class classFile = Platform.getBundle(((String)reqPluginNames.get(inx))).loadClass(name);				
94
			if (classFile != null)
95
				return classFile;
96
		}
97
		catch (Throwable t)
98
		{
99
			/* Handled by next statement */
100
		}
101
		
102
		return loadFromReqPlugins(name, inx + 1);
103
	}
104
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptor.java (+236 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.LinkedList;
16
import java.util.Map;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.osgi.util.NLS;
20
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
22
import org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand;
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
24
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
25
26
public class MacroObjectDescriptor {
27
28
	/** The context id */
29
	private String contextId;
30
31
	/** The widget id of the UI object being resolved */
32
	private String widgetId;
33
	
34
	/** The (optional) object id of the UI object to be resolved */
35
	private String objectId;
36
37
	/** The reference id of this object */
38
	private String referenceId;
39
40
	/** The descriptive attribute (a human readable identification) of this UI object */
41
	private String descriptive;
42
43
	/** Keeps track of the hierarchical relationship */
44
	private LinkedList hierarchicalRelation;
45
46
	/** The parent of this UI object */
47
	private MacroObjectDescriptor parent;
48
49
	/** The properties of this UI Object */
50
	private Hashtable properties;
51
52
	/** The id of the resolver that has resolved this object */
53
	private String resolverId;
54
55
	/** The children of this object */
56
	private ArrayList children;
57
58
	/** The associated data of this object */
59
	private Object data;
60
61
	/**
62
	 * Children indexed based on their reference id KEY = Reference id VALUE = MacroObjectDescriptor that is a child of this object
63
	 */
64
	private Hashtable idIndexedChildren;
65
66
	public MacroObjectDescriptor(MacroObjectDescriptor parent) {
67
		this.parent = parent;
68
		properties = new Hashtable();
69
		children = new ArrayList();
70
		idIndexedChildren = new Hashtable();
71
	}
72
73
	/**
74
	 * Creates an instace of this class based on a command passed in.
75
	 * 
76
	 * @param objectMine
77
	 *            The object mine that this object will be registered with
78
	 * @param command
79
	 *            The command that this object will be based on
80
	 * @param parent
81
	 *            The parent of this object
82
	 * 
83
	 * @return An instance of this class based on widgetIdentifier
84
	 */
85
	public static MacroObjectDescriptor createInstance(ObjectBasedCommand command, MacroObjectDescriptor parent) {
86
		IMacroObjectIdentifier macroObjectIdentifier = command.getMacroObjectIdentifier();
87
		MacroObjectDescriptor uiObject = new MacroObjectDescriptor(parent);
88
		uiObject.setContextId(macroObjectIdentifier.getContextIdentifier() != null
89
			? macroObjectIdentifier.getContextIdentifier().toString()
90
			: MacroConstants.EMPTY_STRING);
91
		uiObject.setWidgetId(macroObjectIdentifier.getObjectIdentifier().getWidgetId());
92
		uiObject.setObjectId(macroObjectIdentifier.getObjectIdentifier().getObjectId());
93
		uiObject.setDescriptive(command.getDescriptiveField());
94
		uiObject.setResolver(macroObjectIdentifier.getObjectIdentifier().getResolverId());
95
96
		return uiObject;
97
	}
98
99
	public String getContextId() {
100
		return contextId;
101
	}
102
103
	public String getDescriptive() {
104
		return descriptive;
105
	}
106
107
	public LinkedList getHierarchicalRelation() {
108
		if (hierarchicalRelation != null)
109
			return hierarchicalRelation;
110
111
		hierarchicalRelation = new LinkedList();
112
		findHierarchicalRelation(this);
113
114
		return hierarchicalRelation;
115
	}
116
117
	private void findHierarchicalRelation(MacroObjectDescriptor currentObject) {
118
		if (currentObject == null)
119
			return;
120
		hierarchicalRelation.addFirst(currentObject);
121
		findHierarchicalRelation(currentObject.getParent());
122
	}
123
124
	public String getObjectId(){
125
		return objectId;
126
	}
127
	
128
	public void setObjectId(String objectId){
129
		this.objectId = objectId;
130
	}
131
	
132
	public String getWidgetId() {
133
		return widgetId;
134
	}
135
136
	public Map getProperties() {
137
		return properties;
138
	}
139
140
	public String getProperty(String name) {
141
		return (String) properties.get(name);
142
	}
143
144
	public String getReferenceId() {
145
		return referenceId;
146
	}
147
148
	public void setContextId(String contextId) {
149
		this.contextId = contextId;
150
	}
151
152
	public void setDescriptive(String descriptive) {
153
		this.descriptive = descriptive;
154
	}
155
156
	public void setWidgetId(String id) {
157
		this.widgetId = id;
158
	}
159
160
	public void addProperty(String name, String value) {
161
		properties.put(name,
162
			value);
163
	}
164
165
	public void setReferenceId(String referenceId) {
166
		this.referenceId = referenceId;
167
	}
168
169
	public MacroObjectDescriptor getParent() {
170
		return parent;
171
	}
172
173
	public void setParent(MacroObjectDescriptor parent) {
174
		this.parent = parent;
175
	}
176
177
	public String getResolverId() {
178
		return resolverId;
179
	}
180
181
	public void setResolver(String resolverId) {
182
		this.resolverId = resolverId;
183
	}
184
185
	public void addChild(MacroObjectDescriptor child) throws CoreException {
186
		if (!children.contains(child)) {
187
			try {
188
				/* If there is a collision, then try to resolve it */
189
				int referenceId = Integer.parseInt(child.getReferenceId());
190
				while (idIndexedChildren.get(child.getReferenceId()) != null) {
191
					referenceId++;
192
				}
193
				child.setReferenceId(String.valueOf(referenceId));
194
			}
195
			catch (NumberFormatException nfe) {
196
				/* Ignore the error */
197
			}
198
199
			/* If there is still a collision, then throw an exception */
200
			if (idIndexedChildren.get(child.getReferenceId()) != null)
201
				AutoGUIUtil.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID,
202
					child.getReferenceId()));
203
204
			idIndexedChildren.put(child.getReferenceId(),
205
				child);
206
			children.add(child);
207
		}
208
	}
209
210
	public int childCount() {
211
		return children.size();
212
	}
213
214
	public MacroObjectDescriptor[] getChildren() {
215
		MacroObjectDescriptor[] objects = new MacroObjectDescriptor[children.size()];
216
		children.toArray(objects);
217
		return objects;
218
	}
219
220
	public MacroObjectDescriptor removeChild(MacroObjectDescriptor child) {
221
		children.remove(child);
222
		return child;
223
	}
224
225
	public Object getData() {
226
		return data;
227
	}
228
229
	public void setData(Object data) {
230
		this.data = data;
231
	}
232
233
	public MacroObjectDescriptor findChild(String referenceId) {
234
		return (MacroObjectDescriptor) idIndexedChildren.get(referenceId);
235
	}
236
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/IPlayable.java (+21 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.core.runtime.IProgressMonitor;
15
import org.eclipse.swt.widgets.Display;
16
import org.eclipse.swt.widgets.Shell;
17
18
public interface IPlayable {
19
20
	boolean playback(Display display, Shell parent, IProgressMonitor monitor) throws CoreException;
21
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/SingleSelectionCommand.java (+30 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
14
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
15
16
17
/**
18
 * @author Alexander Nyssen
19
 *
20
 */
21
public abstract class SingleSelectionCommand extends ObjectBasedCommand {
22
23
	/**
24
	 * @param parent
25
	 * @param widgetId
26
	 */
27
	public SingleSelectionCommand(MacroCommandShell parent) {
28
		super(parent);
29
	}
30
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObject.java (+26 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject;
13
14
import org.eclipse.swt.widgets.Widget;
15
16
17
/**
18
 * @author Alexander Nyssen
19
 *
20
 */
21
public interface IUIObject {
22
23
	public abstract Widget getWidget();
24
25
	public abstract Object getObject();
26
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/core/WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter.java (+12 lines)
Added Link Here
1
package org.eclipse.tptp.test.auto.gui.internal.core;
2
3
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader;
4
5
public class WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter extends UIObjectResolverDelegateLoader {
6
7
	public WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter(WidgetResolverLoader widgetResolverLoader) {
8
		super(widgetResolverLoader.getId(), new WidgetResolverToUIObjectResolverDelegateAdapter(widgetResolverLoader.getWidgetResolver()), widgetResolverLoader.getPriority());
9
	}
10
11
	
12
}
(-)schema/macroCommandFactory.exsd (+111 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.tptp.test.auto.gui">
4
<annotation>
5
      <appInfo>
6
         <meta.schema plugin="org.eclipse.tptp.test.auto.gui" id="macroCommandFactory" name="macroCommandFactory"/>
7
      </appInfo>
8
      <documentation>
9
         Extension point to replace the macro command factory with a custom implementation.
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <complexType>
15
         <sequence>
16
            <element ref="macroCommandFactory"/>
17
         </sequence>
18
         <attribute name="point" type="string" use="required">
19
            <annotation>
20
               <documentation>
21
                  
22
               </documentation>
23
            </annotation>
24
         </attribute>
25
         <attribute name="id" type="string">
26
            <annotation>
27
               <documentation>
28
                  
29
               </documentation>
30
            </annotation>
31
         </attribute>
32
         <attribute name="name" type="string">
33
            <annotation>
34
               <documentation>
35
                  
36
               </documentation>
37
               <appInfo>
38
                  <meta.attribute translatable="true"/>
39
               </appInfo>
40
            </annotation>
41
         </attribute>
42
      </complexType>
43
   </element>
44
45
   <element name="macroCommandFactory">
46
      <complexType>
47
         <attribute name="id" type="string" use="required">
48
            <annotation>
49
               <documentation>
50
                  
51
               </documentation>
52
            </annotation>
53
         </attribute>
54
         <attribute name="class" type="string" use="required">
55
            <annotation>
56
               <documentation>
57
                  
58
               </documentation>
59
               <appInfo>
60
                  <meta.attribute kind="java" basedOn=":org.eclipse.tptp.test.auto.gui.commands.factory.IMacroCommandFactory"/>
61
               </appInfo>
62
            </annotation>
63
         </attribute>
64
         <attribute name="priority" type="string" use="required">
65
            <annotation>
66
               <documentation>
67
                  The priority of the factory. The factory with the highest priority is loaded and used, all others are disregarded.
68
               </documentation>
69
            </annotation>
70
         </attribute>
71
      </complexType>
72
   </element>
73
74
   <annotation>
75
      <appInfo>
76
         <meta.section type="since"/>
77
      </appInfo>
78
      <documentation>
79
         [Enter the first release in which this extension point appears.]
80
      </documentation>
81
   </annotation>
82
83
   <annotation>
84
      <appInfo>
85
         <meta.section type="examples"/>
86
      </appInfo>
87
      <documentation>
88
         [Enter extension point usage example here.]
89
      </documentation>
90
   </annotation>
91
92
   <annotation>
93
      <appInfo>
94
         <meta.section type="apiInfo"/>
95
      </appInfo>
96
      <documentation>
97
         [Enter API information here.]
98
      </documentation>
99
   </annotation>
100
101
   <annotation>
102
      <appInfo>
103
         <meta.section type="implementation"/>
104
      </appInfo>
105
      <documentation>
106
         [Enter information about supplied implementation of this extension point.]
107
      </documentation>
108
   </annotation>
109
110
111
</schema>
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObjectIdentifier.java (+27 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macroobject;
13
14
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
15
16
/**
17
 * 
18
 * @author Alexander Nyssen
19
 * 
20
 */
21
public interface IMacroObjectIdentifier {
22
23
	public String getContextIdentifier();
24
25
	public IUIObjectIdentifier getObjectIdentifier();
26
27
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/editor/AutoGUIMacroObjectDescriptorMineTreeStructure.java (+510 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.editor;
12
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.Iterator;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.emf.ecore.EStructuralFeature;
20
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
21
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
22
import org.eclipse.hyades.test.common.util.XMLUtil;
23
import org.eclipse.hyades.test.ui.adapter.TestWorkbenchAdapter;
24
import org.eclipse.hyades.test.ui.internal.editor.form.util.EObjectTreeContentProvider;
25
import org.eclipse.hyades.ui.editor.IEditorExtension;
26
import org.eclipse.hyades.ui.internal.provider.WorkbenchAdapterLabelProvider;
27
import org.eclipse.jface.action.Action;
28
import org.eclipse.jface.action.IMenuManager;
29
import org.eclipse.jface.dialogs.IDialogConstants;
30
import org.eclipse.jface.resource.ImageDescriptor;
31
import org.eclipse.jface.viewers.IContentProvider;
32
import org.eclipse.jface.viewers.ILabelProvider;
33
import org.eclipse.jface.viewers.IStructuredSelection;
34
import org.eclipse.jface.viewers.Viewer;
35
import org.eclipse.osgi.util.NLS;
36
import org.eclipse.swt.SWT;
37
import org.eclipse.swt.graphics.Image;
38
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIImages;
39
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
40
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
41
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
42
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
43
import org.eclipse.tptp.test.auto.gui.internal.dialogs.AutoGUITestSuiteDialog;
44
import org.eclipse.tptp.test.auto.gui.internal.editor.AutoGUITestCaseTreeStructure.MessageUIElement;
45
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
46
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
47
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
48
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMineManager;
49
50
/**
51
 * Represents the object mine tree that is displayed in the test case page of
52
 * the editor.
53
 * 
54
 * @author Ali Mehregani
55
 * @author Paul E. Slauenwhite
56
 * @version March 7, 2008
57
 * @since July 10, 2006
58
 */
59
public class AutoGUIMacroObjectDescriptorMineTreeStructure extends
60
		AutoGUIAbstractTreeStructure {
61
	/** Represents the root element in the object mine tree */
62
	private static final RootUMacroObjectDescriptorMineTreeNode ROOT_ELEMENT = new RootUMacroObjectDescriptorMineTreeNode();
63
64
	/** The test case form */
65
	private AutoGUITestCasesForm testCaseForm;
66
67
	/** The content provider */
68
	private ObjectMineTreeContentProvider contentProvider;
69
70
	/** The label provider */
71
	private ObjectMineLabelProvider labelProvider;
72
73
	/**
74
	 * The line number and offset relation. The index of the list represents the
75
	 * line number and the value is an object of type Integer[0] indicating the
76
	 * start and end offset
77
	 */
78
	private List lineOffsetRelation;
79
80
	/** The include object mine menu item */
81
	private IncludeObjectMineAction includeObjectMineAction;
82
83
	/** Change output menu item */
84
	private ChangeOutputAction changeOutputAction;
85
86
	/** Keeps track of the test suite used as input */
87
	private ITestSuite testSuiteInput;
88
89
	/** Stores any error that occurred while loading the object mine */
90
	private Object[] error;
91
92
	public AutoGUIMacroObjectDescriptorMineTreeStructure(
93
			AutoGUITestCasesForm testCaseForm, IEditorExtension editorPart) {
94
		super(editorPart, null);
95
		this.testCaseForm = testCaseForm;
96
		lineOffsetRelation = new ArrayList();
97
		includeObjectMineAction = new IncludeObjectMineAction();
98
		changeOutputAction = new ChangeOutputAction();
99
	}
100
101
	/**
102
	 * Overwrite this method so that a custom content provider can be registered
103
	 * with the tree
104
	 */
105
	protected IContentProvider createContentProvider() {
106
		if (contentProvider == null)
107
			contentProvider = new ObjectMineTreeContentProvider(editorPart,
108
					getEStructuralFeature());
109
		return contentProvider;
110
	}
111
112
	/**
113
	 * Overwrite this method so that a custom label provider can be registered
114
	 * with the tree
115
	 * 
116
	 * @return The label provider for the object mine tree
117
	 */
118
	protected ILabelProvider createLabelProvider() {
119
		if (labelProvider == null)
120
			labelProvider = new ObjectMineLabelProvider(
121
					TestWorkbenchAdapter.class);
122
		return labelProvider;
123
	}
124
125
	/**
126
	 * Overwrite this method so that custom buttons can be added beside the
127
	 * object mine tree.
128
	 */
129
	protected void adjustButtonLabels(String addLabel) {
130
		setButtonLabels(new String[0]);
131
	}
132
133
	/**
134
	 * Need to overwrite this method since there are no buttons whose status
135
	 * need to be updated.
136
	 */
137
	protected void updateActionsAndButtons(
138
			IStructuredSelection structuredSelection) {
139
		/* purposely left blank */
140
	}
141
142
	/**
143
	 * Refreshes the content of this tree by forcing the test suite to reload
144
	 * its object mine.
145
	 */
146
	public void refresh() {
147
		MacroObjectDescriptorMineManager.getInstance().clearCache();
148
		loadObjectMine(testSuiteInput, false);
149
		getTreeViewer().refresh();
150
	}
151
152
	public List getLineOffsetRelation() {
153
		return lineOffsetRelation;
154
	}
155
156
	/**
157
	 * Needs to be overwritten to modify the default tree style
158
	 */
159
	public int getTreeStryle() {
160
		return super.getTreeStryle() | SWT.BORDER;
161
	}
162
163
	private Object[] createErrorItem(String prefix, Exception e) {
164
		Throwable cause = AutoGUIUtil.findCause(e);
165
		prefix += prefix == null ? "" : ": ";
166
		prefix += (cause.getMessage() == cause.getClass().getName() ? "" : " "
167
				+ cause.getMessage());
168
		prefix += ": " + e.getStackTrace()[0].getClassName() + ":"
169
				+ e.getStackTrace()[0].getLineNumber();
170
		return new Object[] { new MessageUIElement(IStatus.ERROR, prefix) };
171
	}
172
173
	/**
174
	 * Overwrite this method so that custom menu items can be added to the
175
	 * entries that are displayed in the object mine tree.
176
	 * 
177
	 * @param menuManager
178
	 *            The menu manager
179
	 */
180
	protected void fillContextMenu(IMenuManager menuManager) {
181
		IStructuredSelection selection = getStructuredSelection();
182
		if (!selection.isEmpty()
183
				&& selection.size() == 1
184
				&& selection.getFirstElement() instanceof RootUMacroObjectDescriptorMineTreeNode) {
185
			menuManager.add(includeObjectMineAction);
186
			menuManager.add(changeOutputAction);
187
		}
188
	}
189
190
	private MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite,
191
			boolean showError) {
192
		MacroObjectDescriptorMine input = null;
193
		if (testSuite == null) {
194
			testSuiteInput = null;
195
			return null;
196
		}
197
198
		try {
199
			testSuiteInput = (ITestSuite) testSuite;
200
			input = MacroObjectDescriptorMineManager.getInstance()
201
					.loadObjectMine(testSuiteInput);
202
			String objectMineXML = HyadesUtil.getTestSuiteVariable(
203
					testSuiteInput,
204
					GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
205
			lineOffsetRelation = AutoGUIMacroObjectDescriptorMineTreeStructure.this
206
					.findLineOffsetIndicator(objectMineXML);
207
			error = null;
208
		} catch (Exception e) {
209
			if (showError) {
210
				AutoGUIUtil.openErrorWithDetail(
211
						AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
212
						AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE + ": "
213
								+ testSuite.getName(), e);
214
			} else {
215
				error = createErrorItem(
216
						AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, e);
217
			}
218
219
			input = null;
220
		}
221
222
		return input;
223
	}
224
225
	/**
226
	 * The content provider for the object mine tree.
227
	 * 
228
	 * @author Ali Mehregani
229
	 */
230
	private class ObjectMineTreeContentProvider extends
231
			EObjectTreeContentProvider {
232
		public ObjectMineTreeContentProvider(IEditorExtension editorPart,
233
				EStructuralFeature eStructuralFeature) {
234
			super(editorPart, eStructuralFeature);
235
		}
236
237
		public Object[] getElements(Object inputElement) {
238
			return new Object[] { ROOT_ELEMENT };
239
		}
240
241
		/**
242
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
243
		 */
244
		public Object[] getChildren(Object parentElement) {
245
			MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput,
246
					false);
247
			if (input == null) {
248
				if (parentElement == ROOT_ELEMENT && error != null)
249
					return error;
250
			}
251
252
			/*
253
			 * If the test suite doesn't have an object mine then return an
254
			 * empty list
255
			 */
256
			String objectMineXML = null;
257
			if (testSuiteInput == null
258
					|| (objectMineXML = HyadesUtil.getTestSuiteVariable(
259
							testSuiteInput,
260
							GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE)) == null
261
					|| objectMineXML.length() <= 0)
262
				return null;
263
264
			if (parentElement == ROOT_ELEMENT) {
265
				return input.getChildren();
266
			} else if (parentElement instanceof MacroObjectDescriptor) {
267
				return ((MacroObjectDescriptor) parentElement).getChildren();
268
			}
269
270
			return null;
271
		}
272
273
		public boolean hasChildren(Object parentElement) {
274
			MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput,
275
					false);
276
			if (parentElement == ROOT_ELEMENT) {
277
				return input == null ? error != null
278
						: input.getChildren().length > 0;
279
			} else if (parentElement instanceof MacroObjectDescriptor) {
280
				return ((MacroObjectDescriptor) parentElement).childCount() > 0;
281
			}
282
283
			return false;
284
		}
285
286
		/**
287
		 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
288
		 */
289
		public Object getParent(Object element) {
290
			if (element instanceof MacroObjectDescriptor) {
291
				MacroObjectDescriptor parent = ((MacroObjectDescriptor) element)
292
						.getParent();
293
				return parent == null ? (Object) ROOT_ELEMENT : parent;
294
			}
295
			return null;
296
		}
297
298
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
299
			if (!(newInput instanceof ITestSuite))
300
				return;
301
302
			loadObjectMine((ITestSuite) newInput, false);
303
304
		}
305
	}
306
307
	private class ObjectMineLabelProvider extends WorkbenchAdapterLabelProvider {
308
309
		public ObjectMineLabelProvider(Class cl)
310
				throws IllegalArgumentException {
311
			super(cl);
312
		}
313
314
		public String getText(Object element) {
315
			if (element == ROOT_ELEMENT) {
316
				return AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_MINE;
317
			} else if (element instanceof MacroObjectDescriptor) {
318
				String descriptiveField = ((MacroObjectDescriptor) element)
319
						.getDescriptive();
320
				return descriptiveField == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_OBJ_OBJECT
321
						: XMLUtil.removeXMLSymbols(descriptiveField);
322
			} else if (element instanceof MessageUIElement) {
323
				String message = ((MessageUIElement) element).getText();
324
				return message == null ? AutoGUIMessages.TST_SUITE_AUTO_MACRO_MESSAGE
325
						: message;
326
			}
327
328
			return MacroConstants.EMPTY_STRING;
329
		}
330
331
		public Image getImage(Object element) {
332
			if (element == ROOT_ELEMENT) {
333
				return AutoGUIImages.getInstance().getImage(
334
						AutoGUIImages.OBJECT_MINE);
335
			} else if (element instanceof MacroObjectDescriptor) {
336
				MacroObjectDescriptor parent = ((MacroObjectDescriptor) element)
337
						.getParent();
338
				return parent == null ? AutoGUIImages.getInstance().getImage(
339
						AutoGUIImages.SHELL) : AutoGUIImages.getInstance()
340
						.getImage(AutoGUIImages.WIDGET);
341
			} else if (element instanceof MessageUIElement) {
342
				return ((MessageUIElement) element).getIcon();
343
			}
344
345
			return null;
346
		}
347
	}
348
349
	/**
350
	 * A dummy class that represents the root element in the object mine tree.
351
	 */
352
	private static class RootUMacroObjectDescriptorMineTreeNode {
353
	}
354
355
	/**
356
	 * The include object mine action. The purpose of this action is to allow
357
	 * the user to include object mines under the test suite's object mine
358
	 * 
359
	 * @author Ali Mehregani
360
	 */
361
	private class IncludeObjectMineAction extends Action {
362
		/**
363
		 * Perform the action.
364
		 * 
365
		 */
366
		public void run() {
367
			/* Display the test suite list dialog */
368
			AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog(
369
					GuiPlugin.getDefault().getWorkbench()
370
							.getActiveWorkbenchWindow().getShell(),
371
					testSuiteInput,
372
					AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, false);
373
374
			if (autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID)
375
				return;
376
377
			/*
378
			 * Get the selected test suites and include them as part of this
379
			 * test suite's object mine
380
			 */
381
			Collection tests = autoGUITestSuiteDialog.getTests();
382
			MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput,
383
					true);
384
			boolean markdirty = false;
385
			for (Iterator testIterator = tests.iterator(); testIterator
386
					.hasNext();) {
387
				Object currentTestSuite = testIterator.next();
388
				if (!(currentTestSuite instanceof ITestSuite))
389
					continue;
390
391
				ITestSuite testSuite = (ITestSuite) currentTestSuite;
392
				try {
393
					MacroObjectDescriptorMine objectMine = MacroObjectDescriptorMineManager
394
							.getInstance().loadObjectMine(testSuite);
395
					if (objectMine != null
396
							&& !input.getIncludes().contains(objectMine)) {
397
						markdirty = true;
398
						input.addInclude(objectMine);
399
					}
400
				} catch (Exception e) {
401
					/* Display an error */
402
					AutoGUIUtil
403
							.openErrorWithDetail(
404
									AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
405
									NLS
406
											.bind(
407
													AutoGUIMessages.AUTO_GUI_ERROR_DIALOG_TST_INCL,
408
													testSuite.getName()), e);
409
				}
410
			}
411
412
			if (markdirty) {
413
				testCaseForm.updateTestProperty(null,
414
						input.serializeToString(), true);
415
				getTreeViewer().setSelection(getTreeViewer().getSelection());
416
			}
417
		}
418
419
		public boolean isEnabled() {
420
			return testSuiteInput != null;
421
		}
422
423
		public String getText() {
424
			return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_INCL;
425
		}
426
427
		public ImageDescriptor getImageDescriptor() {
428
			return AutoGUIImages.getInstance().getImageDescriptor("e",
429
					AutoGUIImages.INCLUDE);
430
		}
431
	}
432
433
	/**
434
	 * This action changes the output of the object mine to another test suite.
435
	 * 
436
	 * @author Ali Mehregani
437
	 */
438
	private class ChangeOutputAction extends Action {
439
		/**
440
		 * Perform the action.
441
		 */
442
		public void run() {
443
			/* Display the test suite list dialog */
444
			AutoGUITestSuiteDialog autoGUITestSuiteDialog = new AutoGUITestSuiteDialog(
445
					GuiPlugin.getDefault().getWorkbench()
446
							.getActiveWorkbenchWindow().getShell(),
447
					testSuiteInput,
448
					AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_ITITLE, true);
449
450
			if (autoGUITestSuiteDialog.open() == IDialogConstants.CANCEL_ID)
451
				return;
452
453
			/*
454
			 * Get the selected test suites and include them as part of this
455
			 * test suite's object mine
456
			 */
457
			Collection tests = autoGUITestSuiteDialog.getTests();
458
			if (tests == null)
459
				return;
460
461
			Object[] selectedTestContainer = tests.toArray();
462
			if (selectedTestContainer.length != 1
463
					|| !(selectedTestContainer[0] instanceof ITestSuite))
464
				return;
465
466
			MacroObjectDescriptorMine input = loadObjectMine(testSuiteInput,
467
					true);
468
			MacroObjectDescriptorMine oldOutputObjectMine = input
469
					.getOutputSource();
470
			ITestSuite oldOutput = oldOutputObjectMine == null ? null
471
					: oldOutputObjectMine.getOwner();
472
			ITestSuite newOutput = (ITestSuite) selectedTestContainer[0];
473
			if (oldOutput == null
474
					|| (!oldOutput.getId().equals(newOutput.getId()))) {
475
				MacroObjectDescriptorMine objectMine = null;
476
				try {
477
					objectMine = MacroObjectDescriptorMineManager.getInstance()
478
							.loadObjectMine(newOutput);
479
					input.setOutputSource(objectMine);
480
					testCaseForm.updateTestProperty(null, input
481
							.serializeToString(), true);
482
					getTreeViewer()
483
							.setSelection(getTreeViewer().getSelection());
484
				} catch (Exception e) {
485
					input.setOutputSource(null);
486
					AutoGUIUtil
487
							.openErrorWithDetail(
488
									AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
489
									NLS
490
											.bind(
491
													AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT,
492
													newOutput.getName()), e);
493
				}
494
			}
495
		}
496
497
		public boolean isEnabled() {
498
			return testSuiteInput != null;
499
		}
500
501
		public String getText() {
502
			return AutoGUIMessages.AUTO_GUI_TST_DIALOG_TREE_OUPUT;
503
		}
504
505
		public ImageDescriptor getImageDescriptor() {
506
			return AutoGUIImages.getInstance().getImageDescriptor("e",
507
					AutoGUIImages.OUTPUT);
508
		}
509
	}
510
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/IUIObjectDeprecatedDeresolvingFacade.java (+38 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport;
13
14
import org.eclipse.swt.widgets.Widget;
15
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
16
17
18
/**
19
 * Used to migrate the old WidgetResolvers to the new IUIObjectResolverDelegate interface 
20
 * while preserving their implementation. 
21
 * @author ANy
22
 * @version $Revision$
23
 *
24
 */
25
public interface IUIObjectDeprecatedDeresolvingFacade {
26
27
	/**
28
	 * 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
29
	 * in.
30
	 * 
31
	 * @param object
32
	 *            An object
33
	 * @param objectId
34
	 *            The being searched for
35
	 * @return true iff object's id is equalled to 'id'
36
	 */
37
	public boolean foundWidget(Widget object, IUIObjectIdentifier objectId);
38
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/MacroCommandShell.java (+1076 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.Vector;
16
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.IProgressMonitor;
19
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.Status;
21
import org.eclipse.core.runtime.SubProgressMonitor;
22
import org.eclipse.jface.window.Window;
23
import org.eclipse.osgi.util.NLS;
24
import org.eclipse.swt.SWT;
25
import org.eclipse.swt.SWTException;
26
import org.eclipse.swt.widgets.Control;
27
import org.eclipse.swt.widgets.Display;
28
import org.eclipse.swt.widgets.Event;
29
import org.eclipse.swt.widgets.Listener;
30
import org.eclipse.swt.widgets.Shell;
31
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
32
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
33
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
34
import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand;
35
import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand;
36
import org.eclipse.tptp.test.auto.gui.internal.commands.MouseEventCommand;
37
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
38
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
39
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
40
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
41
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
42
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
43
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
44
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
45
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
46
import org.w3c.dom.Node;
47
import org.w3c.dom.NodeList;
48
49
/**
50
 * Keeps track of the macro commands while they are being captured.
51
 * 
52
 * @author Alexander Nyssen (factored creation of commands out into respective
53
 *         factory)
54
 */
55
public class MacroCommandShell extends AbstractMacroInstruction implements
56
		IMacroInstruction {
57
58
	/** The widget id associated with this macro command shell */
59
	private IMacroObjectIdentifier macroObjectIdentifier;
60
61
	/** The corresponding UI object for this macro command shell */
62
	private MacroObjectDescriptor macroObjectDescriptor;
63
64
	/* The commands of this macro shell */
65
	private ArrayList commands;
66
67
	/* The expected return code */
68
	private int expectedReturnCode;
69
70
	/* The display object */
71
	private transient Display display;
72
73
	/* The shell that this macro command shell represents */
74
	private transient Shell shell;
75
76
	/* The reference id of the macro shell object */
77
	// private String referenceId;
78
	/* The title of the shell that this macro command shell represents */
79
	private String shellTitle;
80
81
	private transient Window window;
82
83
	/* Set when there is a listener registered with this MacroCommandShell */
84
	private transient boolean isListenerRegistered;
85
86
	/*
87
	 * A queue of nested shell waiting to be activated (this is used during
88
	 * playback)
89
	 */
90
	private static Vector nestedShellQueue;
91
92
	/* Last index of the nested shell queue */
93
	private static int lastNestedShellInx;
94
95
	/* Stores the last command line executed */
96
	private static int lastCommandLineExecuted;
97
98
	/*
99
	 * Mutual lock used to block when a command is being executed. This lock is
100
	 * used to forcefully wake up the thread that this object is running in if
101
	 * the command has caused a stall
102
	 */
103
	private Boolean mutualLock;
104
105
	/*
106
	 * A mutual lock shared across multiple instances of this class -- It's
107
	 * general purpose is to lock shared static resources
108
	 */
109
	private static Boolean mutualGlobalLock;
110
111
	/*
112
	 * The parent of this macro command shell. This is null if this macro shell
113
	 * command is the root
114
	 */
115
	private MacroCommandShell parent;
116
117
	/*
118
	 * The index of the command being executed -- this will correspond to the
119
	 * last command index if isComplete = true
120
	 */
121
	private int currentCommandInx;
122
123
	/* Indicates if all the commands of this shell has been completed */
124
	private boolean isComplete;
125
126
	/* Indicates that the process needs to be interrupted -- due to an error */
127
	private static boolean interruptProcess;
128
129
	/* Set to true when process has been terminated */
130
	private static boolean processTerminated;
131
132
	/* The exception causing the interruption */
133
	private static Throwable interruptedException;
134
135
	/* A central container for all macro command operation being played */
136
	private static Vector macroCommandsBeingPlayed;
137
138
	/* A central container for all instances of this class */
139
	private static Vector macroCommandShellContainer;
140
141
	/* A central repository for all macro command shells */
142
	static {
143
		nestedShellQueue = new Vector();
144
		macroCommandsBeingPlayed = new Vector();
145
		macroCommandShellContainer = new Vector();
146
		mutualGlobalLock = new Boolean(true);
147
	}
148
149
	public MacroCommandShell(MacroCommandShell parent) {
150
		this(parent, null, null);
151
	}
152
153
	public MacroCommandShell(MacroCommandShell parent, Shell shell,
154
			IMacroObjectIdentifier wid) {
155
		setMacroObjectIdentifier(wid);
156
		commands = new ArrayList();
157
		this.shell = shell;
158
		this.shellTitle = shell == null || shell.isDisposed() ? null : shell
159
				.getText();
160
		hookWindow(false);
161
		expectedReturnCode = -1;
162
		isListenerRegistered = false;
163
		mutualLock = new Boolean(true);
164
		this.parent = parent;
165
		isComplete = false;
166
		macroCommandShellContainer.add(this);
167
	}
168
169
	public IMacroObjectIdentifier getMacroObjectIdentifier() {
170
		return macroObjectIdentifier;
171
	}
172
173
	public void setMacroObjectIdentifier(IMacroObjectIdentifier objectIdentifier) {
174
		this.macroObjectIdentifier = objectIdentifier;
175
	}
176
177
	public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() {
178
		return macroObjectDescriptor;
179
	}
180
181
	public void setCorrespondingMacroObjectDescriptor(
182
			MacroObjectDescriptor uiObject) {
183
		this.macroObjectDescriptor = uiObject;
184
	}
185
186
	private void hookWindow(boolean playback) {
187
		if (shell != null) {
188
			if (!playback)
189
				doHookWindow();
190
			else
191
				display.syncExec(new Runnable() {
192
193
					public void run() {
194
						doHookWindow();
195
					}
196
				});
197
		}
198
	}
199
200
	private void doHookWindow() {
201
		Object data = shell.getData();
202
		if (data != null && data instanceof Window)
203
			this.window = (Window) data;
204
	}
205
206
	/**
207
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.AbstractMacroInstruction#load(org.w3c.dom.Node,
208
	 *      java.util.Hashtable)
209
	 */
210
	public void load(Node node, Hashtable lineTable) throws CoreException {
211
		super.load(node, lineTable);
212
213
		/*
214
		 * If the corresponding shell of this command is referenced then attempt
215
		 * to find the corresponding object in the object mine.
216
		 */
217
		if (MacroManager.getInstance().getObjectMine() != null) {
218
			MacroObjectDescriptor descriptor = MacroManager.getInstance()
219
					.getObjectMine().lookupReferenceId(null, node, lineTable);
220
			if (descriptor != null) {
221
				setCorrespondingMacroObjectDescriptor(descriptor);
222
			}
223
		}
224
		boolean useObjectMine = getCorrespondingMacroObjectDescriptor() != null;
225
		setMacroObjectIdentifier(new MacroObjectIdentifier(null,
226
				new PrimitiveUIObjectIdentifier(
227
						useObjectMine ? getCorrespondingMacroObjectDescriptor()
228
								.getWidgetId() : MacroUtil.getAttribute(node,
229
								MacroConstants.WIDGET_ID_ATTRIBUTE),
230
						useObjectMine ? getCorrespondingMacroObjectDescriptor()
231
								.getResolverId() : MacroUtil.getAttribute(node,
232
								MacroConstants.RESOLVER_ID_ATTRIBUTE))));
233
		String codeId = MacroUtil.getAttribute(node,
234
				MacroConstants.RETURN_CODE_ATTRIBUTE);
235
		if (codeId != null) {
236
			try {
237
				expectedReturnCode = new Integer(codeId).intValue();
238
			} catch (NumberFormatException e) {
239
			}
240
		}
241
		NodeList children = node.getChildNodes();
242
		for (int i = 0; i < children.getLength(); i++) {
243
			Node child = children.item(i);
244
			if (child.getNodeType() == Node.ELEMENT_NODE) {
245
				String name = child.getNodeName();
246
				if (name.equals(MacroConstants.COMMAND_ELEMENT))
247
					processCommand(child, lineTable);
248
				else if (name.equals(MacroConstants.SHELL_ELEMENT))
249
					processShell(child, lineTable);
250
			}
251
		}
252
	}
253
254
	/**
255
	 * Used to process the node that is passed in as argument, the lineTable
256
	 * hashtable indicates the range of line numbers that the node corresponds
257
	 * to in the macro script
258
	 * 
259
	 * @param node
260
	 *            The node to be processed
261
	 * @param lineTable
262
	 *            The line number range that the node corresponds to in the
263
	 *            script.
264
	 */
265
	private void processCommand(Node node, Hashtable lineTable)
266
			throws CoreException {
267
268
		String type = MacroUtil.getAttribute(node,
269
				MacroConstants.TYPE_ATTRIBUTE);
270
		if (type == null)
271
			return;
272
273
		IMacroCommand command = MacroManager.getInstance()
274
				.getMacroCommandFactory().createCommand(this, type);
275
276
		if (command != null) {
277
			command.load(node, lineTable);
278
			commands.add(command);
279
		}
280
	}
281
282
	private void processShell(Node node, Hashtable lineTable)
283
			throws CoreException {
284
		MacroCommandShell shell = new MacroCommandShell(this);
285
		shell.load(node, lineTable);
286
		commands.add(shell);
287
	}
288
289
	public void addCommandShell(MacroCommandShell cshell) {
290
		commands.add(cshell);
291
	}
292
293
	public void write(int indent, StringBuffer sb) {
294
		/* If this shell command doesn't have any commands, then exit */
295
		if (commands == null || commands.size() <= 0)
296
			return;
297
298
		/* <shell */
299
		MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, false,
300
				false);
301
		boolean objectMineInUse = MacroManager.getInstance().isObjectMineOn();
302
		MacroUtil.addAttribute(sb, new String[] {
303
				MacroConstants.DESCRIPTIVE_ATTRIBUTE,
304
				MacroConstants.RESOLVER_ID_ATTRIBUTE,
305
				MacroConstants.WIDGET_ID_ATTRIBUTE,
306
				MacroConstants.REFERENCE_ID_ATTRIBUTE,
307
				MacroConstants.RETURN_CODE_ATTRIBUTE }, new String[] {
308
				getDescriptiveField(),
309
				objectMineInUse ? null : getMacroObjectIdentifier()
310
						.getObjectIdentifier().getResolverId(),
311
				objectMineInUse ? null : getMacroObjectIdentifier()
312
						.getObjectIdentifier().getWidgetId(),
313
				objectMineInUse ? getCorrespondingMacroObjectDescriptor()
314
						.getReferenceId() /*
315
											 * CHANGED BY ANY: use the ref id of
316
											 * the corresponing
317
											 * MacroObjectDescriptor rather than
318
											 * the id stored in the widgetId
319
											 */
320
				: null, String.valueOf(expectedReturnCode) }, false, true);
321
		int cindent = indent + 1;
322
		for (int i = 0; i < commands.size(); i++) {
323
			IPersistable persistable = (IPersistable) commands.get(i);
324
			persistable.writeStart(cindent, sb);
325
			persistable.write(cindent, sb);
326
			persistable.writeFinish(cindent, sb);
327
		}
328
		MacroUtil.addElement(sb, indent, MacroConstants.SHELL_ELEMENT, true,
329
				true);
330
	}
331
332
	public String getDescriptiveField() {
333
		return shellTitle == null ? null : MacroUtil
334
				.normalizeDescriptiveField(MacroUtil.boundSize(shellTitle,
335
						IMacroCommand.DESCRIPTIVE_FIELD_BOUND));
336
	}
337
338
	public void addEvent(Event event) {
339
		if (event.widget instanceof Control) {
340
			if (((Control) event.widget).isVisible() == false)
341
				return;
342
		}
343
344
		IMacroCommand command = null;
345
		try {
346
			command = MacroManager.getInstance().getMacroCommandFactory()
347
					.createCommand(this, commands, event);
348
		} catch (CoreException e) {
349
			// it may be the case we are waiting for a verification command to
350
			// be created, so notify a waiting listener (just in case)
351
			MacroManager.getInstance().notifyVerificationListener(
352
					e.getMessage());
353
		}
354
355
		// if we are waiting for a verification command, notify the listener
356
		// that is was correctly created
357
		if (command != null && command instanceof VerificationCommand) {
358
			MacroManager.getInstance().notifyVerificationListener(
359
					(VerificationCommand) command);
360
		}
361
	}
362
363
	/**
364
	 * Adds a wait command for as long as the last command is not already a wait
365
	 * (i.e. duplicate addition of wait commands are avoided through this
366
	 * method)
367
	 */
368
	public void addPause() {
369
		WaitCommand command = new WaitCommand(this);
370
371
		Object lastCommand = null;
372
		int commandSize = commands.size();
373
		boolean isLastCommandWait = false;
374
375
		if (commandSize <= 0)
376
			return;
377
378
		lastCommand = commands.get(commandSize - 1);
379
		int lastCmdInx = 2;
380
381
		/*
382
		 * Avoid MacroCommandShells that have no commands (since these will not
383
		 * be included as part of the macro)
384
		 */
385
		while (lastCommand instanceof MacroCommandShell
386
				&& ((MacroCommandShell) lastCommand).getCommands().size() <= 0) {
387
			if (commandSize - lastCmdInx >= 0)
388
				lastCommand = commands.get(commandSize - lastCmdInx);
389
			else {
390
				lastCommand = null;
391
				break;
392
			}
393
394
			lastCmdInx++;
395
		}
396
397
		AbstractMacroCommand lastMacroCommand = null;
398
		if (lastCommand instanceof AbstractMacroCommand)
399
			lastMacroCommand = (AbstractMacroCommand) lastCommand;
400
401
		isLastCommandWait = lastMacroCommand != null
402
				&& lastMacroCommand.getType() == WaitCommand.TYPE;
403
		if (commands.size() > 0 && !isLastCommandWait) {
404
			commands.add(command);
405
		}
406
	}
407
408
	public void extractExpectedReturnCode() {
409
		if (window != null)
410
			expectedReturnCode = window.getReturnCode();
411
	}
412
413
	public boolean matchesReturnCode() {
414
		if (window != null) {
415
			return window.getReturnCode() == expectedReturnCode;
416
		}
417
		return true;
418
	}
419
420
	public boolean isDisposed() {
421
		return this.shell != null && this.shell.isDisposed();
422
	}
423
424
	public void close() {
425
		if (this.shell != null && !this.shell.isDisposed())
426
			this.shell.close();
427
	}
428
429
	public boolean tracks(Shell shell) {
430
		if (this.shell != null && this.shell.equals(shell))
431
			return true;
432
		return false;
433
	}
434
435
	public boolean playback(final Display display, Shell parent,
436
			final IProgressMonitor monitor) throws CoreException {
437
		if (parent instanceof Shell) {
438
			this.shell = (Shell) parent;
439
			this.display = display;
440
			hookWindow(true);
441
		}
442
443
		NestedShell nestedShell = null;
444
		int commandSize = commands.size();
445
		monitor.beginTask("", commandSize);
446
		final int commandTimeOut;
447
448
		int potentialTimeoutValue = MacroManager.getInstance()
449
				.getCommandTimeoutThreshold();
450
		if (MacroManager.getInstance().getCommandTimeoutThreshold() > 0)
451
			commandTimeOut = potentialTimeoutValue;
452
		else
453
			commandTimeOut = GlobalConstants.DEFAULT_COMMAND_TIME_OUT_PERIOD;
454
455
		for (int i = 0; i < commandSize; i++) {
456
			currentCommandInx = i;
457
			checkForInterruptions();
458
			Object c = commands.get(i);
459
			final IPlayable playable = (IPlayable) c;
460
461
			/*
462
			 * If this is the last command of this macro command shell, then
463
			 * take out its entry in the shell queue
464
			 */
465
			if (isLastCommand(i)) {
466
				if (getNestedShellQueue() != null
467
						&& getNestedShellQueue().size() > 0) {
468
					if (lastNestedShellInx > 0)
469
						lastNestedShellInx--;
470
					removeNestedShell(0);
471
				}
472
			}
473
474
			/*
475
			 * If this command is a nested shell, then we need to wait until it
476
			 * completes before proceeding to the next command.
477
			 */
478
			if (c instanceof MacroCommandShell) {
479
				MacroCommandShell nestedCommandShell = (MacroCommandShell) c;
480
				// System.out.println("NESTED SHELL WAIT: " +
481
				// nestedCommandShell.getId());
482
				Object lastNestedCommand = null;
483
				Object currentNestedCommand = null;
484
				synchronized (nestedCommandShell) {
485
					/*
486
					 * Give each command in the nested shell a maximum of
487
					 * commandTimeOut to execute
488
					 */
489
					while (!nestedCommandShell.isComplete()
490
							&& (currentNestedCommand == null || lastNestedCommand != currentNestedCommand)
491
							&& !interruptProcess) {
492
						try {
493
							nestedCommandShell.wait(commandTimeOut);
494
							lastNestedCommand = currentNestedCommand;
495
							currentNestedCommand = nestedCommandShell
496
									.getCommandBeingExecuted();
497
						} catch (InterruptedException e) {
498
							/* Handled by next set of code */
499
						}
500
					}
501
502
					/* Indicate an error if the nested shell never completed */
503
					if (!nestedCommandShell.isComplete()) {
504
						synchronized (mutualGlobalLock) {
505
							interruptProcess = true;
506
							if (interruptedException == null)
507
								interruptedException = new CoreException(
508
										new Status(
509
												IStatus.ERROR,
510
												GuiPlugin.getID(),
511
												0,
512
												NLS
513
														.bind(
514
																AutoGUIMessages.AUTO_GUI_ERROR_MACRO_NEST_TOUT,
515
																nestedCommandShell
516
																		.getMacroObjectIdentifier()
517
																		.getObjectIdentifier()
518
																		.toString()),
519
												null));
520
						}
521
522
						continue; /* Interrupt the normal flow */
523
					}
524
					// System.out.println("NESTED SHELL FINISH: " +
525
					// nestedCommandShell.getId());
526
				}
527
			}
528
529
			if (i < commandSize - 1) {
530
				/*
531
				 * Ali M.: We need to iterate through all the shell commands and
532
				 * register listeners before it's too late. It's not sufficient
533
				 * to just register a listener with the next command
534
				 */
535
				int counter = 1;
536
				IPlayable next = (IPlayable) commands.get(i + counter);
537
				while (next instanceof MacroCommandShell) {
538
					/*
539
					 * This command will open a new shell. Add a listener before
540
					 * it is too late
541
					 */
542
					MacroCommandShell nestedCommand = (MacroCommandShell) next;
543
544
					if (!nestedCommand.isListenerRegistered()) {
545
						nestedShell = new NestedShell(display, nestedCommand,
546
								new SubProgressMonitor(monitor, 1));
547
						final NestedShell fnestedShell = nestedShell;
548
549
						/*
550
						 * If this is a child of the previous shell, then it
551
						 * takes precedence. If it's a sibling, then it should
552
						 * go to the end of the queue.
553
						 */
554
						nestedCommand.setListenerRegistered(true);
555
						if (nestedShellQueue.size() > 0
556
								&& ((NestedShell) nestedShellQueue.get(0))
557
										.isParent(nestedCommand)) {
558
							addNestedShell(0, fnestedShell);
559
							lastNestedShellInx = 0;
560
						} else {
561
							if (nestedShellQueue.size() > 0)
562
								addNestedShell(++lastNestedShellInx,
563
										fnestedShell);
564
							else
565
								addNestedShell(fnestedShell);
566
						}
567
568
						display.syncExec(new Runnable() {
569
570
							public void run() {
571
								// System.out.println("ADDED");
572
								display.addFilter(SWT.Activate, fnestedShell);
573
							}
574
						});
575
					}
576
					counter++;
577
					next = (i + counter <= commandSize - 1 ? (IPlayable) commands
578
							.get(i + counter)
579
							: null);
580
				}
581
			}
582
			if (playable instanceof AbstractMacroCommand) {
583
				final boolean last = i == commandSize - 1;
584
585
				class WakeUpOperaion implements Runnable {
586
587
					private AbstractMacroCommand command;
588
					private boolean invalidate;
589
590
					public WakeUpOperaion(AbstractMacroCommand command) {
591
						this.command = command;
592
						invalidate = false;
593
					}
594
595
					public void run() {
596
						if (!invalidate
597
								&& MacroCommandShell.lastCommandLineExecuted == command
598
										.getStartLine()) {
599
							/*
600
							 * Ali M.: A command just timed-out. We need to
601
							 * indicate the error and wakeup the thread
602
							 */
603
							synchronized (mutualGlobalLock) {
604
								interruptProcess = true;
605
								if (interruptedException == null)
606
									interruptedException = new CoreException(
607
											new Status(
608
													IStatus.ERROR,
609
													GuiPlugin.getID(),
610
													0,
611
													NLS
612
															.bind(
613
																	AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT,
614
																	command
615
																			.toString()),
616
													null));
617
							}
618
619
							synchronized (mutualLock) {
620
								mutualLock.notify();
621
							}
622
						}
623
					}
624
625
					public void invalidate() {
626
						this.invalidate = true;
627
					}
628
629
				}
630
				WakeUpOperaion wakeupOpt = null;
631
				if (i < commandSize - 1) {
632
					wakeupOpt = new WakeUpOperaion(
633
							(AbstractMacroCommand) playable);
634
					final Runnable wakeupOperation = wakeupOpt;
635
					display.asyncExec(new Runnable() {
636
637
						public void run() {
638
							display.timerExec(commandTimeOut, wakeupOperation);
639
						};
640
641
					});
642
				}
643
644
				class RunCommandOperation implements Runnable {
645
646
					private boolean isComplete;
647
648
					public void run() {
649
						try {
650
							if (!macroCommandsBeingPlayed.contains(this))
651
								macroCommandsBeingPlayed.add(this);
652
653
							lastCommandLineExecuted = ((AbstractMacroCommand) playable)
654
									.getStartLine();
655
							playInGUIThread(display, playable, last, monitor);
656
657
							macroCommandsBeingPlayed.remove(this);
658
							isComplete = true;
659
							synchronized (mutualLock) {
660
								mutualLock.notify();
661
							}
662
						} catch (Throwable e) {
663
							macroCommandsBeingPlayed.remove(this);
664
							synchronized (mutualGlobalLock) {
665
								interruptProcess = true;
666
								if (interruptedException == null)
667
									interruptedException = e;
668
							}
669
							isComplete = true;
670
							synchronized (mutualLock) {
671
								mutualLock.notify();
672
							}
673
						}
674
					}
675
676
					public boolean isComplete() {
677
						return isComplete;
678
					}
679
680
				}
681
682
				RunCommandOperation runCommandOpt = new RunCommandOperation();
683
684
				/* Run the command */
685
				synchronized (mutualLock) {
686
					new Thread(runCommandOpt).start();
687
					long start = System.currentTimeMillis();
688
					long wakeUpTime = start;
689
					long timeToSleep = commandTimeOut;
690
					try {
691
						while (!runCommandOpt.isComplete() && timeToSleep > 0
692
								&& !interruptProcess) {
693
							// System.out.println("WAITING on command: " +
694
							// playable);
695
							mutualLock.wait(timeToSleep);
696
							wakeUpTime = System.currentTimeMillis();
697
							timeToSleep = timeToSleep - (wakeUpTime - start);
698
						}
699
					} catch (InterruptedException e) {
700
						/* Doesn't need to be handled */
701
					}
702
703
					/* Indicate an error if command didn't complete */
704
					if (!runCommandOpt.isComplete()) {
705
						synchronized (mutualGlobalLock) {
706
							interruptProcess = true;
707
							if (interruptedException == null)
708
								interruptedException = new CoreException(
709
										new Status(
710
												IStatus.ERROR,
711
												GuiPlugin.getID(),
712
												0,
713
												NLS
714
														.bind(
715
																AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TIME_OUT,
716
																playable
717
																		.toString()),
718
												null));
719
						}
720
					}
721
					/*
722
					 * Otherwise invalidate the wake up operation that was
723
					 * suppose to wake this command up
724
					 */
725
					else if (wakeupOpt != null)
726
						wakeupOpt.invalidate();
727
728
					// System.out.println("FINISHED WAITING on command: " +
729
					// playable);
730
				}
731
732
				monitor.worked(1);
733
			}
734
		}
735
736
		checkForInterruptions();
737
		shell = null;
738
739
		/*
740
		 * We made it out alive -- mark this as complete and wake any parents
741
		 * that are waiting upon our completion
742
		 */
743
		isComplete = true;
744
		synchronized (this) {
745
			this.notify();
746
		}
747
748
		macroCommandShellContainer.remove(this);
749
		return true;
750
	}
751
752
	private boolean isComplete() {
753
		return isComplete;
754
	}
755
756
	private Object getCommandBeingExecuted() {
757
		if (commands == null || currentCommandInx >= commands.size())
758
			return null;
759
		return commands.get(currentCommandInx);
760
	}
761
762
	private void checkForInterruptions() throws CoreException {
763
		if (interruptProcess) {
764
			/* Wake up all threads in case they are asleep */
765
			if (!processTerminated) {
766
				processTerminated = true;
767
				interruptOperation();
768
				MacroCommandShell.macroStopped();
769
				MacroUtil.closeSecondaryShells(display);
770
			}
771
772
			for (int i = 0; i < macroCommandShellContainer.size(); i++) {
773
				synchronized (mutualLock) {
774
					mutualLock.notify();
775
				}
776
777
				synchronized (macroCommandShellContainer.get(i)) {
778
					macroCommandShellContainer.get(i).notify();
779
				}
780
			}
781
782
			/* Try to close all nested shells */
783
			synchronized (mutualGlobalLock) {
784
				if (interruptedException instanceof CoreException)
785
					throw (CoreException) interruptedException;
786
				throw new CoreException(new Status(IStatus.ERROR, GuiPlugin
787
						.getID(), 0,
788
						interruptedException.getLocalizedMessage(),
789
						interruptedException));
790
			}
791
		}
792
793
	}
794
795
	/**
796
	 * A helper method that walks through all macro command shells and
797
	 * interrupts their normal flow.
798
	 */
799
	private void interruptOperation() {
800
		MacroCommandShell currentMacroShell = this;
801
		while (currentMacroShell != null) {
802
			Boolean lock = currentMacroShell.mutualLock;
803
			synchronized (lock) {
804
				lock.notify();
805
			}
806
807
			currentMacroShell = currentMacroShell.getParent();
808
		}
809
810
	}
811
812
	private boolean isLastCommand(int index) {
813
		for (int i = index + 1; i < commands.size(); i++) {
814
			if (commands.get(i) instanceof AbstractMacroCommand)
815
				return false;
816
		}
817
		return true;
818
	}
819
820
	private void playInGUIThread(final Display display,
821
			final IPlayable playable, boolean last,
822
			final IProgressMonitor monitor) throws CoreException {
823
		final CoreException[] ex = new CoreException[1];
824
825
		Runnable runnable = new Runnable() {
826
827
			public void run() {
828
				try {
829
					boolean status = playable.playback(display,
830
							MacroCommandShell.this.shell, monitor);
831
832
					/* Something went wrong playing this item */
833
					if (!status)
834
						ex[0] = createPlaybackException(playable, null);
835
					else
836
						MacroUtil.processDisplayEvents(display);
837
				} catch (ClassCastException e) {
838
					ex[0] = createPlaybackException(playable, e);
839
				} catch (CoreException e) {
840
					ex[0] = e;
841
				} catch (SWTException e) {
842
					/* Don't handle */
843
				} catch (Throwable error) {
844
					ex[0] = createPlaybackException(playable, error);
845
				}
846
			}
847
		};
848
849
		if (playable instanceof WaitCommand) {
850
			playable.playback(display, this.shell, monitor);
851
		} else {
852
			display.syncExec(runnable);
853
		}
854
855
		try {
856
			Thread.sleep(100);
857
		} catch (InterruptedException e) {
858
		}
859
860
		if (ex[0] != null)
861
			throw ex[0];
862
863
	}
864
865
	private CoreException createPlaybackException(IPlayable playable,
866
			Throwable th) {
867
		IStatus status = new Status(IStatus.ERROR, "org.eclipse.pde.ui.tests",
868
				IStatus.OK, NLS.bind(
869
						AutoGUIMessages.AUTO_GUI_ERROR_MACRO_COMMAND, playable
870
								.toString()), th);
871
		return new CoreException(status);
872
	}
873
874
	public ArrayList getCommands() {
875
		return commands;
876
	}
877
878
	public boolean isListenerRegistered() {
879
		return isListenerRegistered;
880
	}
881
882
	public void setListenerRegistered(boolean isListenerRegistered) {
883
		this.isListenerRegistered = isListenerRegistered;
884
	}
885
886
	public static Vector getNestedShellQueue() {
887
		return nestedShellQueue;
888
	}
889
890
	public static void addNestedShell(int inx, NestedShell nestedShell) {
891
		synchronized (nestedShellQueue) {
892
			if (inx >= 0)
893
				nestedShellQueue.add(inx, nestedShell);
894
			else
895
				nestedShellQueue.add(nestedShell);
896
		}
897
	}
898
899
	private static void addNestedShell(NestedShell fnestedShell) {
900
		addNestedShell(-1, fnestedShell);
901
	}
902
903
	public static void removeNestedShell(int inx) {
904
		synchronized (nestedShellQueue) {
905
			nestedShellQueue.remove(inx);
906
		}
907
	}
908
909
	public static void initializeForNewPlay() {
910
		nestedShellQueue.clear();
911
		lastNestedShellInx = 0;
912
		interruptProcess = false;
913
		processTerminated = false;
914
		interruptedException = null;
915
		MouseEventCommand.init();
916
		macroCommandsBeingPlayed.clear();
917
		macroCommandShellContainer.clear();
918
	}
919
920
	public Shell getShell() {
921
		return shell;
922
	}
923
924
	public void writeStart(int indent, StringBuffer sb) {
925
		/* Doesn't need to be implemented */
926
	}
927
928
	public void writeFinish(int indent, StringBuffer sb) {
929
		/* Doesn't need to be implemented */
930
	}
931
932
	public MacroCommandShell getParent() {
933
		return parent;
934
	}
935
936
	public void setParent(MacroCommandShell parent) {
937
		this.parent = parent;
938
	}
939
940
	public static void macroStopped() {
941
		/* Walk through nested shell listeners and remove them if any exists */
942
		final Display display = GuiPlugin.getDefault().getWorkbench()
943
				.getDisplay();
944
		display.syncExec(new Runnable() {
945
946
			public void run() {
947
				for (int i = 0, nestedShellListenerSize = nestedShellQueue
948
						.size(); i < nestedShellListenerSize; i++) {
949
					display.removeFilter(SWT.Activate,
950
							(NestedShell) nestedShellQueue.get(i));
951
				}
952
			}
953
		});
954
	}
955
956
	public static Vector getMacroCommandsBeingPlayed() {
957
		return macroCommandsBeingPlayed;
958
	}
959
960
	private static class NestedShell implements Listener, Runnable {
961
962
		private MacroCommandShell cshell;
963
964
		private Display display;
965
966
		private Shell nshell;
967
968
		private boolean released;
969
970
		private CoreException exception;
971
972
		private IProgressMonitor monitor;
973
974
		private boolean served;
975
976
		public NestedShell(Display display, MacroCommandShell cshell,
977
				IProgressMonitor monitor) {
978
			this.display = display;
979
			this.cshell = cshell;
980
			this.monitor = monitor;
981
		}
982
983
		public void handleEvent(Event event) {
984
			try {
985
				if (event.widget instanceof Shell) {
986
					// shell activated
987
					Shell shell = (Shell) event.widget;
988
					// ANY: CHANGED: IPath path = new
989
					// Path(UIObjectResolverUtil.getShellId(shell,null).toString());
990
					// String sid = path.toString();
991
					String sid = MacroObjectResolver.resolve(shell,
992
							new MacroObject(new UIObject(shell)))
993
							.getObjectIdentifier().getWidgetId();
994
995
					/* Debug */
996
					// System.out.println();
997
					// System.out.println(sid + " : " + cshell.getId());
998
					// if (MacroCommandShell.getNestedShellQueue() != null &&
999
					// MacroCommandShell.getNestedShellQueue().size() > 0)
1000
					// System.out.println("Is Served: " +
1001
					// ((NestedShell)MacroCommandShell.getNestedShellQueue().get(0)).isServed());
1002
					// System.out.println(this + " : " +
1003
					// MacroCommandShell.getNestedShellQueue().get(0));
1004
					// System.out.println();
1005
					if (sid.equals(cshell.getMacroObjectIdentifier()
1006
							.getObjectIdentifier().getWidgetId())
1007
							&& (MacroCommandShell.getNestedShellQueue() == null
1008
									|| MacroCommandShell.getNestedShellQueue()
1009
											.size() <= 0 || (!((NestedShell) MacroCommandShell
1010
									.getNestedShellQueue().get(0)).isServed() && this
1011
									.equals(MacroCommandShell
1012
											.getNestedShellQueue().get(0))))) {
1013
						// System.out.println("REMOVED FILTER: " +
1014
						// cshell.getId());
1015
						shell.getDisplay().removeFilter(SWT.Activate, this);
1016
						released = true;
1017
						this.nshell = shell;
1018
1019
						/*
1020
						 * We need to start this in a separate thread.
1021
						 * MacroCommandShells should not be played in UI threads
1022
						 * (otherwise wait commands will not work properly)
1023
						 */
1024
						this.setServed(true);
1025
						new Thread(this).start();
1026
					}
1027
				}
1028
			} catch (Throwable t) {
1029
				// System.out.println("REMOVED filter");
1030
				/* Something unexpected has happened -- Remove this listener */
1031
				event.display.removeFilter(SWT.Activate, this);
1032
			}
1033
		}
1034
1035
		public void setServed(boolean served) {
1036
			this.served = served;
1037
		}
1038
1039
		public boolean isServed() {
1040
			return served;
1041
		}
1042
1043
		public boolean getResult() {
1044
			return cshell.matchesReturnCode();
1045
		}
1046
1047
		public boolean isReleased() {
1048
			return released;
1049
		}
1050
1051
		public void run() {
1052
			try {
1053
				cshell.playback(display, nshell, monitor);
1054
			} catch (CoreException e) {
1055
				synchronized (mutualGlobalLock) {
1056
					interruptProcess = true;
1057
					if (interruptedException == null)
1058
						interruptedException = e;
1059
				}
1060
1061
				synchronized (cshell.mutualLock) {
1062
					cshell.mutualLock.notify();
1063
				}
1064
			}
1065
		}
1066
1067
		public CoreException getException() {
1068
			return exception;
1069
		}
1070
1071
		public boolean isParent(MacroCommandShell macroCommandShell) {
1072
			return macroCommandShell.getParent().equals(cshell);
1073
		}
1074
	}
1075
1076
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/IUIObjectResolverDelegate.java (+53 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
12
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
15
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
16
17
/**
18
 * This interface is registered using extension point
19
 * <code>org.eclipse.tptp.test.auto.gui.internal.widgetResolver</code> which is
20
 * expected to return a unique identifier from a provided widget. The identifier
21
 * must be reproducable between sessions so that it can be used to locate the
22
 * widget on playback.
23
 * 
24
 * @since 3.1
25
 */
26
public interface IUIObjectResolverDelegate {
27
28
	/**
29
	 * Returns a unique identifier for the provided UI object.
30
	 * 
31
	 * @param context
32
	 *            The context of the UI object (usually retrieved from an
33
	 *            IMacroObject)
34
	 * @param uiObject
35
	 *            The object whose id is suppose to be resolved. The type of
36
	 *            this object is <b>usually</b> a widget, but it can also be a
37
	 *            <code>java.lang.String</code> or any other arbitrary type
38
	 *            depending on the implementation of the widget. For example,
39
	 *            when attempting to resolve a combo box item, parent will point
40
	 *            to the combo box and object will point to a
41
	 *            <code>java.lang.String</code> item representing the item
42
	 *            selected.
43
	 * 
44
	 * @return unique identifier that can be used to locate the UI object within
45
	 *         the context or <code>null</code> if none can be found.
46
	 */
47
	public IUIObjectIdentifier resolve(Object context, IUIObject uiObject)
48
			throws CoreException;
49
50
	public IUIObject deresolve(Object context,
51
			IUIObjectIdentifier uiObjectIdentifier) throws CoreException;
52
53
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateLoader.java (+61 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
12
13
/**
14
 * Represents each widgetResolver element that appears under a widgetResolver
15
 * extension
16
 * 
17
 * @author Ali Mehregani
18
 * @author Alexander Nyssen
19
 */
20
public class UIObjectResolverDelegateLoader {
21
22
	/** The id of the widget resolver */
23
	private String id;
24
25
	/** The widget resolver class */
26
	private IUIObjectResolverDelegate uiObjectResolverDelegate;
27
28
	/** The priority of this widget resolver registeration */
29
	private int priority;
30
31
	/**
32
	 * Limit the visibility of the constructor
33
	 */
34
	protected UIObjectResolverDelegateLoader(String id,
35
			IUIObjectResolverDelegate resolver, int priority) {
36
		this.id = id;
37
		this.uiObjectResolverDelegate = resolver;
38
		this.priority = priority;
39
	}
40
41
	/**
42
	 * @return the id
43
	 */
44
	public String getId() {
45
		return id;
46
	}
47
48
	/**
49
	 * @return the priority
50
	 */
51
	public int getPriority() {
52
		return priority;
53
	}
54
55
	/**
56
	 * @return the widgetResolver
57
	 */
58
	public IUIObjectResolverDelegate getUIObjectResolverDelegate() {
59
		return uiObjectResolverDelegate;
60
	}
61
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/IMacroInstruction.java (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
14
/**
15
 * Represents a macro instruction. The instruction is expected to both be writable and playable.
16
 * 
17
 * @author Ali Mehregani
18
 */
19
public interface IMacroInstruction extends IPersistable, IPlayable {
20
21
	/**
22
	 * Returns the starting line number of this macro instruction in the macro script that it belongs to.
23
	 * 
24
	 * @return The starting line
25
	 */
26
	public int getStartLine();
27
28
	/**
29
	 * Returns the last line number of this macro instruction in the macro script that it belongs to.
30
	 * 
31
	 * @return The last line
32
	 */
33
	public int getStopLine();
34
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/NonTrivialUIObjectResolverDelegate.java (+879 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: NonTrivialUIObjectResolverDelegate.java,v 1.4 2007/05/02 19:35:58 paules Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
13
14
import java.util.Vector;
15
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.hyades.models.hierarchy.TRCAgentProxy;
18
import org.eclipse.jface.action.ActionContributionItem;
19
import org.eclipse.jface.action.IAction;
20
import org.eclipse.jface.action.IContributionItem;
21
import org.eclipse.jface.window.Window;
22
import org.eclipse.jface.wizard.IWizardPage;
23
import org.eclipse.jface.wizard.WizardDialog;
24
import org.eclipse.swt.custom.CCombo;
25
import org.eclipse.swt.custom.CTabFolder;
26
import org.eclipse.swt.custom.CTabItem;
27
import org.eclipse.swt.graphics.Point;
28
import org.eclipse.swt.widgets.Button;
29
import org.eclipse.swt.widgets.Combo;
30
import org.eclipse.swt.widgets.Composite;
31
import org.eclipse.swt.widgets.Control;
32
import org.eclipse.swt.widgets.Group;
33
import org.eclipse.swt.widgets.Item;
34
import org.eclipse.swt.widgets.Label;
35
import org.eclipse.swt.widgets.Menu;
36
import org.eclipse.swt.widgets.MenuItem;
37
import org.eclipse.swt.widgets.Shell;
38
import org.eclipse.swt.widgets.TabFolder;
39
import org.eclipse.swt.widgets.TabItem;
40
import org.eclipse.swt.widgets.Text;
41
import org.eclipse.swt.widgets.ToolBar;
42
import org.eclipse.swt.widgets.ToolItem;
43
import org.eclipse.swt.widgets.Tree;
44
import org.eclipse.swt.widgets.TreeItem;
45
import org.eclipse.swt.widgets.Widget;
46
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
47
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
48
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
49
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
50
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
51
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
52
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
53
import org.eclipse.tptp.test.auto.gui.internal.uiobject.WeightedPropertyUIObjectIdentifier;
54
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver;
55
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade;
56
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport;
57
import org.eclipse.tptp.trace.ui.internal.launcher.core.AnalysisType;
58
import org.eclipse.tptp.trace.ui.internal.launcher.core.DataCollectorTreeContentProvider.ParentChildNode;
59
import org.eclipse.ui.IPluginContribution;
60
import org.eclipse.ui.IViewPart;
61
import org.eclipse.ui.IWorkbenchPage;
62
import org.eclipse.ui.IWorkbenchPart;
63
import org.eclipse.ui.IWorkbenchWindow;
64
import org.eclipse.ui.dialogs.FileSystemElement;
65
import org.eclipse.ui.model.IWorkbenchAdapter;
66
import org.eclipse.ui.views.IViewCategory;
67
68
/**
69
 * <p>
70
 * The purpose of this class is to resolve widgets that cannot be resolved using
71
 * the AdaptiveUIObjectResolverDelegate. These widgets will likely require
72
 * nested calls in order to be determined.
73
 * </p>
74
 * <p>
75
 * Some of the properties used to resolve a widget are locale dependent (e.g.
76
 * the name of a button or the closest label to a text box)
77
 * </p>
78
 * 
79
 * @since 4.1
80
 * @author Ali Mehregani
81
 * @author Alexander Nyssen
82
 */
83
public class NonTrivialUIObjectResolverDelegate implements
84
		IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade {
85
86
	/**
87
	 * The id of this resolver -- must be in sync with the id registered with
88
	 * the widgetResolver extension.
89
	 */
90
	public static final String ID = "org.eclipse.tptp.test.auto.gui.nontrivial";
91
92
	public IUIObjectIdentifier resolve(Object context, IUIObject uiObject)
93
			throws CoreException {
94
		Widget widget = uiObject.getWidget();
95
		Object object = uiObject.getObject();
96
97
		Object data = widget.getData();
98
99
		IUIObjectIdentifier widgetId = null;
100
101
		/* Resolve the object based on the data type of the widget */
102
		/* An agent */
103
		if (data instanceof TRCAgentProxy) {
104
			widgetId = resolveAgentProxy(widget);
105
		}
106
		/* A file system element */
107
		else if (data instanceof FileSystemElement) {
108
			widgetId = resolveFileSystemElement(widget);
109
		}
110
		/* A view catgory */
111
		else if (data instanceof IViewCategory) {
112
			String id = ((IViewCategory) data).getId();
113
			if (id != null && id.length() > 0) {
114
				widgetId = new PrimitiveUIObjectIdentifier(id, ID);
115
			}
116
		}
117
		/* Analysis type */
118
		else if (data instanceof ParentChildNode) {
119
			Object child = ((ParentChildNode) data).child;
120
			if (child instanceof AnalysisType) {
121
				widgetId = resolveAnalysisType((AnalysisType) child);
122
			}
123
		}
124
		/* A menu item or a tree item */
125
		else if (widget instanceof MenuItem || widget instanceof TreeItem) {
126
			widgetId = resolveItem((Item) widget);
127
		}
128
		/* A TabItem or CTabItem */
129
		else if (widget instanceof TabItem || widget instanceof CTabItem) {
130
			String itemText = validateText(widget instanceof TabItem ? ((TabItem) widget)
131
					.getText()
132
					: ((CTabItem) widget).getText());
133
			widgetId = itemText != null ? new PrimitiveUIObjectIdentifier(
134
					itemText, ID) : null;
135
		}
136
		/* A tool item */
137
		else if (widget instanceof ToolItem) {
138
			widgetId = resolveToolbarItem((ToolItem) widget);
139
		}
140
		/* A menu (added by ANy) */
141
		else if (widget instanceof Menu) {
142
			widgetId = getActionId((Menu) widget);
143
		}
144
		// controls
145
		else if (widget instanceof Control) {
146
			/* A button */
147
			if (widget instanceof Button) {
148
				widgetId = resolveButton((Button) widget);
149
			}
150
			/* A text box */
151
			else if (widget instanceof Text) {
152
				widgetId = resolveText((Text) widget);
153
			}
154
			/* A toolbar */
155
			else if (widget instanceof ToolBar) {
156
				widgetId = resolveToolBar((ToolBar) widget);
157
			}
158
			/* Resolve the object based on its widget type */
159
			/* A control (added by ANy) */
160
			else if (widget instanceof Shell) {
161
				widgetId = getShellId((Shell) widget);
162
			}
163
164
			if (widgetId == null) {
165
				Control control = (Control) widget;
166
				Shell shell = control.getShell();
167
				Object shellData = shell.getData();
168
				if (shellData instanceof WizardDialog) {
169
					// in wizard
170
					WizardDialog wd = (WizardDialog) shellData;
171
					IWizardPage page = wd.getCurrentPage();
172
					Control pageControl = page.getControl();
173
					widgetId = computeRelativePath((Composite) pageControl,
174
							null, control);
175
					if (widgetId == null) {
176
						// check for wizard buttons
177
						if (control instanceof Button) {
178
							widgetId = computeRelativePath(shell,
179
									(Composite) pageControl, control);
180
						}
181
					}
182
				} else if (shellData instanceof IWorkbenchWindow) {
183
184
					IWorkbenchWindow window = (IWorkbenchWindow) shellData;
185
					IWorkbenchPage page = window.getActivePage();
186
					IWorkbenchPart part = page.getActivePart();
187
188
					Composite paneComposite = MacroUtil
189
							.getWorkbenchPartControl(part);
190
191
					/*
192
					 * If the control we are looking for is a local tool bar, go
193
					 * up one level
194
					 */
195
					if (part instanceof IViewPart && control instanceof ToolBar) {
196
						paneComposite = paneComposite.getParent();
197
					}
198
					widgetId = computeRelativePath(paneComposite, null, control);					
199
				} else {
200
					/* unknown shell - fetch controls starting from the shell */
201
					widgetId = computeRelativePath(shell, null, control);
202
				}
203
204
				// ANy: in case we have items on a combo box or tab folder
205
				if (uiObject.getObject() != null && (widget instanceof Combo
206
						|| widget instanceof CCombo)) {
207
208
					widgetId = new PrimitiveUIObjectIdentifier(widgetId
209
							.getWidgetId(), computeDefaultChoiceId(widget,
210
							uiObject.getObject()).toString(), ID);
211
				}
212
			}
213
		}
214
215
		/*
216
		 * (added by ANy) Defect #: 112668: If we have to resolve an Item try
217
		 * the old policy before giving up
218
		 */
219
		if (widgetId == null && widget instanceof Item) {
220
			widgetId = determineItemId((Item) widget);
221
		}
222
223
		return widgetId;
224
	}
225
226
	public IUIObject deresolve(Object context,
227
			IUIObjectIdentifier uiObjectIdentifier) throws CoreException {
228
		return UIObjectDeprecatedDeresolvingSupport.deresolve(context,
229
				uiObjectIdentifier);
230
	}
231
232
	private IUIObjectIdentifier resolveAnalysisType(AnalysisType analysisType) {
233
		Object[] properties = { new Object[] { analysisType.getId(), "1.0" }, };
234
235
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
236
				(float) 1.0, ID);
237
	}
238
239
	private IUIObjectIdentifier resolveToolBar(ToolBar toolbar) {
240
		int itemCount = toolbar.getItemCount();
241
		String firstItem = itemCount > 1 ? limitText(toolbar.getItem(0)
242
				.getToolTipText()) : null, lastItem = itemCount > 2 ? limitText(toolbar
243
				.getItem(itemCount - 1).getToolTipText())
244
				: null;
245
		int style = toolbar.getStyle();
246
247
		if (firstItem == null && lastItem == null)
248
			return null;
249
250
		Object[] properties = { new Object[] { firstItem, "0.5" },
251
				new Object[] { lastItem, "0.5" },
252
				new Object[] { String.valueOf(itemCount), "0.3" },
253
				new Object[] { String.valueOf(style), "0.2" } };
254
255
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
256
				(float) 1.0, ID);
257
	}
258
259
	private IUIObjectIdentifier resolveToolbarItem(ToolItem item) {
260
		String text = limitText(item.getToolTipText());
261
		String actionId = getActionId(item).toString();
262
		String style = String.valueOf(item.getStyle());
263
264
		Object[] properties = { new Object[] { text, "0.7" },
265
				new Object[] { actionId, "0.7" }, new Object[] { style, "0.3" } };
266
267
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
268
				(float) 1.0, ID);
269
	}
270
271
	private String limitText(String str) {
272
		final int MAX_HOVER_TEXT_SIZE = 20;
273
		if (str != null && str.length() > MAX_HOVER_TEXT_SIZE) {
274
			return str.substring(0, MAX_HOVER_TEXT_SIZE) + "...";
275
		}
276
		return str;
277
	}
278
279
	/*
280
	 * Needed to find buttons, which are identified by a deprecated identifier
281
	 * format
282
	 */
283
	private IUIObjectIdentifier resolveButtonDeprecated(Button button,
284
			IUIObjectIdentifier id) {
285
		String text = null, hoverText = null, size = null, location = null;
286
		if ((text = button.getText()) != null) {
287
			text = text.replaceAll("\\&", "");
288
		}
289
		/* First 20 characters of the hover text */
290
		hoverText = limitText(button.getToolTipText());
291
		Point sizePt = button.getSize();
292
		Point locationPt = button.getLocation();
293
		size = "(" + sizePt.x + "," + sizePt.y + ")";
294
295
		if (id != null && countTokens(id.toString()) == 3) {
296
297
			Object[] properties = { new Object[] { text, "0.5" },
298
					new Object[] { hoverText, "0.5" },
299
					new Object[] { size, "0.5" } };
300
301
			return WeightedPropertyUIObjectIdentifier.constructId(properties,
302
					(float) 1.0, ID);
303
		}
304
		return null;
305
	}
306
307
	private IUIObjectIdentifier resolveButton(Button button) {
308
		String text = null, hoverText = null, size = null, location = null;
309
		if ((text = button.getText()) != null) {
310
			text = text.replaceAll("\\&", "");
311
		}
312
		/* First 20 characters of the hover text */
313
		hoverText = limitText(button.getToolTipText());
314
		Point sizePt = button.getSize();
315
		Point locationPt = button.getLocation();
316
		size = "(" + sizePt.x + "," + sizePt.y + ")";
317
		location = "(" + locationPt.x + "," + locationPt.y + ")";
318
319
		if (button.getParent() != null) {
320
			// Control[] children = ((Composite)parent).getChildren();
321
			Control[] children = button.getParent().getChildren();
322
			int buttonInx = 0;
323
324
			/* Find the index of the button */
325
			for (int i = 0; i < children.length; i++) {
326
				if (button == children[i]) {
327
					buttonInx = i;
328
					break;
329
				}
330
			}
331
332
			Object[] properties = { new Object[] { text, "0.3" },
333
					new Object[] { hoverText, "0.3" },
334
					new Object[] { String.valueOf(children.length), "0.3" },
335
					new Object[] { size, "0.2" },
336
					new Object[] { location, "0.1" },
337
					new Object[] { String.valueOf(buttonInx), "0.2" }, };
338
339
			float threshold = 0.7f;
340
			threshold += text != null ? 0.3 : 0;
341
			threshold += hoverText != null ? 0.3 : 0;
342
343
			if (threshold >= 1.0)
344
				return WeightedPropertyUIObjectIdentifier.constructId(
345
						properties, (float) 1.0, ID);
346
		}
347
348
		return null;
349
	}
350
351
	/**
352
	 * The text of the closest label to a text box is used as a unique
353
	 * identifier of the text box. The label must be in a limited vicinity of
354
	 * the text box for its text to be considered as an identifier. If the text
355
	 * box is owned by a group and the group only owns one text box, then the
356
	 * group text is used to identify the widget.
357
	 * 
358
	 * @param text
359
	 *            The text box
360
	 * @return The widget id for text
361
	 */
362
	private IUIObjectIdentifier resolveText(Text text) {
363
		Composite parent = text.getParent();
364
		Control[] children = parent.getChildren();
365
366
		String groupText = null;
367
		if (parent instanceof Group
368
				&& (groupText = ((Group) parent).getText()) != null
369
				&& (groupText = groupText.replaceAll("\\&", "")).length() > 0) {
370
			int textBoxNum = 0;
371
			for (int i = 0; i < children.length && textBoxNum <= 1; i++) {
372
				if (children[i] instanceof Text)
373
					textBoxNum++;
374
			}
375
376
			if (textBoxNum <= 1)
377
				return new PrimitiveUIObjectIdentifier(groupText, ID);
378
		}
379
380
		Label closestLabel = null;
381
		Point textLocation = text.getLocation();
382
		Point currentDistance = new Point(0, 0);
383
		Point tempDistance = new Point(0, 0);
384
		for (int i = 0; i < children.length; i++) {
385
			Point childLocation = children[i].getLocation();
386
			if (children[i] instanceof Label
387
					&& (closestLabel == null || (tempDistance = isLabelCloser(
388
							childLocation, currentDistance, textLocation)) != null)) {
389
				boolean firstLabel = closestLabel == null;
390
				closestLabel = (Label) children[i];
391
				;
392
				if (firstLabel) {
393
					currentDistance = new Point(Math.abs(childLocation.x
394
							- textLocation.x), Math.abs(childLocation.y
395
							- textLocation.y));
396
				} else {
397
					currentDistance = tempDistance;
398
				}
399
			}
400
		}
401
402
		String closestLabelText = null;
403
		if (closestLabel != null
404
				&& currentDistance.x + currentDistance.y <= 100
405
				&& closestLabel.getText() != null
406
				&& (closestLabelText = closestLabel.getText().replaceAll("\\&",
407
						"")).length() > 0)
408
			return new PrimitiveUIObjectIdentifier(closestLabelText, ID);
409
		return null;
410
	}
411
412
	private Point isLabelCloser(Point newlblLocation, Point currentDistance,
413
			Point textLocation) {
414
		Point tempLocation = new Point(Math.abs(newlblLocation.x
415
				- textLocation.x), Math.abs(newlblLocation.y - textLocation.y));
416
		if (tempLocation.x + tempLocation.y < currentDistance.x
417
				+ currentDistance.y)
418
			return tempLocation;
419
		return null;
420
	}
421
422
	public static String validateText(String text) {
423
		if (text != null && (text = text.replaceAll("\\&", "")).length() > 0)
424
			return text;
425
		return null;
426
	}
427
428
	/**
429
	 * Computes the item id based on the following properties and weights. The
430
	 * threshold is set to 1.0:
431
	 * 
432
	 * <ul>
433
	 * <li> (Descriptive name of the item, 1.0) </li>
434
	 * </ul>
435
	 * 
436
	 * @param item
437
	 *            The item
438
	 * @return The weighted id
439
	 */
440
	private IUIObjectIdentifier resolveItem(Item item) {
441
		StringBuffer descriptiveText = new StringBuffer();
442
		findItemText(item, descriptiveText);
443
444
		/* Remove the ampersands */
445
		String itemText = descriptiveText.toString().replaceAll("\\&", "");
446
447
		Object[] properties = { new Object[] { itemText, "1.0" }, };
448
449
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
450
				(float) 1.0, ID);
451
	}
452
453
	/**
454
	 * Walk through the item and return a descriptive text that corresponds to
455
	 * all item selections leading to the item. (e.g. File-New-Project)
456
	 * 
457
	 * @param item
458
	 *            The item
459
	 * @param descriptiveText
460
	 *            In the end, this buffer will contain a descriptive text of all
461
	 *            items leading to the item that is passed in as argument
462
	 */
463
	private void findItemText(Item item, StringBuffer descriptiveText) {
464
		if (item == null)
465
			return;
466
467
		String descriptiveTextStr = item.getText();
468
		if (descriptiveText.length() > 0)
469
			descriptiveTextStr += "-";
470
471
		descriptiveText.insert(0, descriptiveTextStr);
472
473
		Item parentItem = null;
474
		if (item instanceof MenuItem) {
475
			Menu menu = ((MenuItem) item).getParent();
476
			parentItem = (menu == null ? null : menu.getParentItem());
477
		} else if (item instanceof TreeItem) {
478
			parentItem = ((TreeItem) item).getParentItem();
479
		}
480
481
		if (parentItem != null)
482
			findItemText(parentItem, descriptiveText);
483
	}
484
485
	private IUIObjectIdentifier resolveFileSystemElement(Widget widget) {
486
487
		FileSystemElement fileSystemElement = (FileSystemElement) widget
488
				.getData();
489
		if (fileSystemElement.isDirectory())
490
			return null;
491
492
		Object[] properties = { new Object[] {
493
				((IWorkbenchAdapter) fileSystemElement
494
						.getAdapter(IWorkbenchAdapter.class)).getLabel(null),
495
				"1.0" } };
496
497
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
498
				(float) 1.0, ID);
499
	}
500
501
	private WeightedPropertyUIObjectIdentifier resolveAgentProxy(Widget widget) {
502
		StringBuffer treeIndex = new StringBuffer();
503
		if (widget instanceof TreeItem)
504
			findTreeItemIndex((TreeItem) widget, treeIndex);
505
		else
506
			return null;
507
508
		TRCAgentProxy proxy = (TRCAgentProxy) widget.getData();
509
		Object[] properties = {
510
				new Object[] { treeIndex.toString(), "0.4" },
511
				new Object[] { proxy.getProcessProxy().getName(), "0.2" },
512
				new Object[] { proxy.getProcessProxy().getVmArguments(), "0.1" },
513
				new Object[] { proxy.getProcessProxy().getClasspath(), "0.1" },
514
				new Object[] { proxy.getProcessProxy().getLocation(), "0.1" },
515
				new Object[] { proxy.getProcessProxy().getParameters(), "0.1" },
516
				new Object[] { proxy.getProfileFile(), "0.1" },
517
				new Object[] { proxy.getName(), "0.1" },
518
				new Object[] { String.valueOf(proxy.isAttached()), "0.1" },
519
				new Object[] { String.valueOf(proxy.isMonitored()), "0.1" },
520
				new Object[] { String.valueOf(proxy.isToProfileFile()), "0.1" }, };
521
522
		return WeightedPropertyUIObjectIdentifier.constructId(properties,
523
				(float) 0.7, ID);
524
	}
525
526
	private void findTreeItemIndex(TreeItem treeItem, StringBuffer sb) {
527
		TreeItem parentItem = treeItem.getParentItem();
528
		if (parentItem != null) {
529
			int index = parentItem.indexOf(treeItem);
530
			if (index != -1)
531
				sb.append("|" + String.valueOf(index + 1));
532
533
			findTreeItemIndex(parentItem, sb);
534
		}
535
		Tree tree = treeItem.getParent();
536
		int index = tree.indexOf(treeItem);
537
		if (index != -1)
538
			sb.append("|" + String.valueOf(index));
539
540
	}
541
542
	/**
543
	 * @deprecated This can be removed the resolver does not longer depend on
544
	 *             the UIDeprecatedDeresolvingSupport to deresolve UI objects.
545
	 *             {@inheritDoc}
546
	 * @see org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.internal.uiobject.resolver.delegate.IUIObjectDeprecatedDeresolvingFacade#foundWidget(org.eclipse.swt.widgets.Widget,
547
	 *      org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier)
548
	 */
549
	public boolean foundWidget(Widget widget, IUIObjectIdentifier widgetId) {
550
		IUIObjectIdentifier objectId = null;
551
552
		// ANy: It seems that the resolving for buttons was changed. For
553
		// backwards compatibility,
554
		// the foundWidget has to accept the old button identifier format as
555
		// well.
556
		if (widget instanceof Button) {
557
			Button button = (Button) widget;
558
			objectId = resolveButtonDeprecated(button, widgetId);
559
		}
560
561
		if (objectId == null)
562
			try {
563
				objectId = UIObjectResolver.resolve(new MacroObject(
564
						new UIObject(widget)).getContext(),
565
						new UIObject(widget));
566
			} catch (Exception e) {
567
				e.printStackTrace();
568
			}
569
		if (widgetId == null || widgetId.getWidgetId() == null) {
570
			return false;
571
		} else {
572
			if (objectId == null) {
573
				return false;
574
			} else {
575
				return objectId.equals(widgetId);
576
			}
577
		}
578
	}
579
580
	/**
581
	 * Given a string representation of the id, this method will return the
582
	 * number of tokens that it contains. A token is a name, value pair in the
583
	 * format.
584
	 * 
585
	 * @param id
586
	 *            The string representation of the id
587
	 * @return The number of tokens of the id
588
	 */
589
	public static int countTokens(String id) {
590
		if (id == null)
591
			return 0;
592
593
		char[] characters = id.toCharArray();
594
		boolean braceInxHit = false;
595
		int tokenCount = 0;
596
		for (int i = 0; i < characters.length; i++) {
597
			if (characters[i] == '{') {
598
				if (braceInxHit) {
599
					tokenCount++;
600
				} else {
601
					braceInxHit = true;
602
					continue;
603
				}
604
			}
605
			braceInxHit = false;
606
		}
607
608
		return tokenCount / 2;
609
	}
610
611
	/**
612
	 * Defect #: 112668 This method is invoked to retrieve the id of a menu
613
	 * item. Here's the policy that it employs:
614
	 * <ol>
615
	 * <li> Use the contributed widget resolvers </li>
616
	 * <li> If failed, default to what was being used before </li>
617
	 * </ol>
618
	 * 
619
	 * @param item
620
	 *            The menu item
621
	 * @return The id of the passed item.
622
	 */
623
	private IUIObjectIdentifier determineItemId(Item item) {
624
		if (item instanceof ToolItem) {
625
			return getActionId((ToolItem) item);
626
		} else if (item instanceof MenuItem) {
627
			return getActionId((MenuItem) item);
628
		} else if (item instanceof IContributionItem) {
629
			return getActionId((IContributionItem) item);
630
		}
631
		return null;
632
	}
633
634
	/**
635
	 * @param widget
636
	 * @return
637
	 */
638
	public static IUIObjectIdentifier getActionId(Widget widget) {
639
		Object data = widget.getData();
640
		PrimitiveUIObjectIdentifier widgetId = null;
641
		if (data != null && (data instanceof IContributionItem)) {
642
			widgetId = getActionId((IContributionItem) data);
643
			if (widgetId != null
644
					&& !widgetId.toString().equals(MacroConstants.EMPTY_STRING)) {
645
				if (widget instanceof MenuItem) {
646
					String menuInx = findMenuItemIndex((MenuItem) widget, "");
647
					widgetId = new PrimitiveUIObjectIdentifier(widgetId
648
							.toString()
649
							+ menuInx, ID);
650
				}
651
			}
652
		} else {
653
			widgetId = new PrimitiveUIObjectIdentifier(
654
					"readablename/" + ((widget instanceof MenuItem) ? getDisplayName((MenuItem) widget) : getDisplayName((ToolItem) widget)), ID); //$NON-NLS-1$
655
		}
656
657
		return widgetId;
658
	}
659
660
	public static PrimitiveUIObjectIdentifier getActionId(
661
			IContributionItem contrib) {
662
		String id = null;
663
		PrimitiveUIObjectIdentifier widgetId = null;
664
665
		if (contrib instanceof IPluginContribution) {
666
			id = ((IPluginContribution) contrib).getLocalId();
667
		}
668
		id = id == null ? contrib.getId() : id;
669
		if (id != null) {
670
			widgetId = new PrimitiveUIObjectIdentifier("contribid/" + id, ID); //$NON-NLS-1$
671
		} else {
672
			if (contrib instanceof ActionContributionItem) {
673
				ActionContributionItem actionItem = (ActionContributionItem) contrib;
674
				id = actionItem.getId();
675
				if (id != null) {
676
					widgetId = new PrimitiveUIObjectIdentifier(
677
							"actionid/" + id, ID); //$NON-NLS-1$
678
				} else {
679
					IAction action = actionItem.getAction();
680
					id = action.getActionDefinitionId();
681
					if (id != null) {
682
						widgetId = new PrimitiveUIObjectIdentifier(
683
								"defid/" + id, ID); //$NON-NLS-1$
684
					} else {
685
						widgetId = new PrimitiveUIObjectIdentifier(
686
								"actionclass/" + action.getClass().getName(), ID); //$NON-NLS-1$
687
					}
688
				}
689
			} else {
690
				widgetId = new PrimitiveUIObjectIdentifier(
691
						"contribclass/" + contrib.getClass().getName(), ID); //$NON-NLS-1$				
692
			}
693
		}
694
695
		return widgetId;
696
	}
697
698
	/**
699
	 * @deprecated Should not be done here, but in the delegators Walks through
700
	 *             all parent menus of the menuItem and returns an index of
701
	 *             format &lt;num&gt;|&lt;num&gt;|&lt;num&gt;|... For example
702
	 *             assuming menuItem is placed as follows:
703
	 * 
704
	 * item 1 |_item 2 | |_item 4 |_item 3 |_menuItem
705
	 * 
706
	 * then its respective index will be 1|2|1
707
	 * 
708
	 * @param menuItem
709
	 *            The menu item whose index will be determined
710
	 * @return The index of the menu item as described above.
711
	 */
712
	private static String findMenuItemIndex(MenuItem menuItem, String menuInx) {
713
		if (menuItem == null)
714
			return menuInx;
715
716
		if (menuInx.length() > 0)
717
			menuInx = "|" + menuInx;
718
		menuInx = menuItem.getParent().indexOf(menuItem) + menuInx;
719
		return findMenuItemIndex(menuItem.getParent().getParentItem(), menuInx);
720
	}
721
722
	/**
723
	 * Returns an identifier for the given Menu, based on its user-readable
724
	 * strings
725
	 * 
726
	 * @param menu
727
	 * @return
728
	 */
729
	private static String getDisplayName(Menu menu) {
730
731
		MenuItem parentItem = menu.getParentItem();
732
733
		if (parentItem == null) {
734
			return MacroConstants.EMPTY_STRING;
735
		}
736
737
		return getDisplayName(parentItem);
738
	}
739
740
	/**
741
	 * Returns an identifier for the given MenuItem, based on its user-readable
742
	 * strings
743
	 * 
744
	 * @param menuItem
745
	 * @return
746
	 */
747
	private static String getDisplayName(MenuItem menuItem) {
748
		if (menuItem.getParent() == null
749
				|| menuItem.getParent().getParentItem() == null) {
750
			return MacroUtil.removeChar(menuItem.getText(), '&');
751
		}
752
753
		return getDisplayName(menuItem.getParent()) + "/" //$NON-NLS-1$
754
				+ MacroUtil.removeChar(menuItem.getText(), '&');
755
	}
756
757
	/**
758
	 * @param toolItem
759
	 * @return
760
	 */
761
	private static String getDisplayName(ToolItem toolItem) {
762
		String name = toolItem.getText();
763
764
		if (name != null && !name.equals(MacroConstants.EMPTY_STRING)) {
765
			return name;
766
		}
767
768
		name = toolItem.getToolTipText();
769
770
		if (name != null) {
771
			return name;
772
		}
773
774
		return "unknown"; //$NON-NLS-1$
775
	}
776
777
	/**
778
	 * @deprecated Use resolveUIObject instead (move implementation there)
779
	 * @param context
780
	 * @param parent
781
	 * @param skip
782
	 * @param control
783
	 * @return
784
	 */
785
	public static IUIObjectIdentifier computeRelativePath(Composite parent,
786
			Composite skip, Control control) {
787
		int[] counter = MacroUtil.newCounter();
788
		Vector indices = new Vector();
789
		boolean result = computeControlIndex(parent, skip, control, counter,
790
				indices);
791
		if (!result && skip == null)
792
			return null;
793
794
		int index = result ? ((Integer) indices.get(0)).intValue() : 0;
795
		return computeDefaultControlId(control, index);
796
	}
797
798
	/**
799
	 * Determines the index of the desiredControl relative to the parent control
800
	 * sent in. The Index is stored in index[0].
801
	 * 
802
	 * @param parent
803
	 *            The parent control
804
	 * @param skip
805
	 *            Indicates whether a composite should be skipped
806
	 * @param desiredControl
807
	 *            The desired control
808
	 * @param index
809
	 *            The current index calculated thus far (stored in index[0]. The
810
	 *            type of this parameter is an int array because its value needs
811
	 *            to be preserved between recursive calls.
812
	 * 
813
	 * @return true if the index was found; false otherwise.
814
	 */
815
	private static boolean computeControlIndex(Composite parent,
816
			Composite skip, Control desiredControl, int[] index, Vector indices) {
817
		return UIObjectDeprecatedDeresolvingSupport.recursiveSearch(parent,
818
				skip, desiredControl, null, null, index, new Vector(), indices) != null;
819
	}
820
821
	public static IUIObjectIdentifier computeDefaultControlId(Control control,
822
			int controlIndex) {
823
		PrimitiveUIObjectIdentifier primitiveWidgetId = new PrimitiveUIObjectIdentifier(
824
				control.getClass().getName() + "#" + controlIndex, ID);
825
		return primitiveWidgetId;
826
	}
827
828
	/**
829
	 * Moved here from ChoiceCommand
830
	 * 
831
	 * @param widget
832
	 * @param item
833
	 * @return
834
	 */
835
	private IUIObjectIdentifier computeDefaultChoiceId(Widget widget,
836
			Object item) {
837
		int index = -1;
838
		boolean isCombo = widget instanceof Combo;
839
		boolean isCCombo = isCombo ? false : widget instanceof CCombo;
840
		if (isCombo || isCCombo) {
841
			Combo combo = isCombo ? ((Combo) widget) : null;
842
			CCombo ccombo = isCCombo ? ((CCombo) widget) : null;
843
844
			index = isCombo ? combo.indexOf((String) item) : ccombo
845
					.indexOf((String) item);
846
		} else {
847
			boolean isTabFolder = widget instanceof TabFolder;
848
			boolean isCTabFolder = isTabFolder ? false
849
					: widget instanceof CTabFolder;
850
			if (isTabFolder || isCTabFolder) {
851
				index = isTabFolder ? ((TabFolder) widget)
852
						.indexOf((TabItem) item) : ((CTabFolder) widget)
853
						.indexOf((CTabItem) item);
854
			}
855
		}
856
857
		if (index != -1)
858
			return new PrimitiveUIObjectIdentifier("item#" + index, ID);
859
		return null;
860
	}
861
862
	private static IUIObjectIdentifier getShellId(Shell shell) {
863
		return getDefaultShellId(shell);
864
	}
865
866
	private static IUIObjectIdentifier getDefaultShellId(Shell shell) {
867
		Object data = shell.getData();
868
		String id = "";
869
		if (data instanceof WizardDialog) {
870
			id = data.getClass().getName().toString();
871
		} else if (data instanceof Window) {
872
			id = data.getClass().getName().toString();
873
		}
874
875
		PrimitiveUIObjectIdentifier widgetId = new PrimitiveUIObjectIdentifier(
876
				id, ID);
877
		return widgetId;
878
	}
879
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactory.java (+619 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.commands.factory;
13
14
import java.util.ArrayList;
15
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.jface.dialogs.MessageDialog;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.custom.CCombo;
21
import org.eclipse.swt.custom.CTabFolder;
22
import org.eclipse.swt.custom.StyledText;
23
import org.eclipse.swt.widgets.Button;
24
import org.eclipse.swt.widgets.Combo;
25
import org.eclipse.swt.widgets.Control;
26
import org.eclipse.swt.widgets.Event;
27
import org.eclipse.swt.widgets.List;
28
import org.eclipse.swt.widgets.MenuItem;
29
import org.eclipse.swt.widgets.TabFolder;
30
import org.eclipse.swt.widgets.Table;
31
import org.eclipse.swt.widgets.Text;
32
import org.eclipse.swt.widgets.ToolItem;
33
import org.eclipse.swt.widgets.Tree;
34
import org.eclipse.swt.widgets.TreeItem;
35
import org.eclipse.swt.widgets.Widget;
36
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
37
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
38
import org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand;
39
import org.eclipse.tptp.test.auto.gui.internal.commands.BooleanSelectionCommand;
40
import org.eclipse.tptp.test.auto.gui.internal.commands.CheckCommand;
41
import org.eclipse.tptp.test.auto.gui.internal.commands.ChoiceSelectionCommand;
42
import org.eclipse.tptp.test.auto.gui.internal.commands.CloseWorkbenchPartCommand;
43
import org.eclipse.tptp.test.auto.gui.internal.commands.ExpansionCommand;
44
import org.eclipse.tptp.test.auto.gui.internal.commands.FocusCommand;
45
import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand;
46
import org.eclipse.tptp.test.auto.gui.internal.commands.KeyEventCommand;
47
import org.eclipse.tptp.test.auto.gui.internal.commands.ModifyCommand;
48
import org.eclipse.tptp.test.auto.gui.internal.commands.MouseEventCommand;
49
import org.eclipse.tptp.test.auto.gui.internal.commands.ObjectBasedCommand;
50
import org.eclipse.tptp.test.auto.gui.internal.commands.StructuredSelectionCommand;
51
import org.eclipse.tptp.test.auto.gui.internal.commands.VerificationCommand;
52
import org.eclipse.tptp.test.auto.gui.internal.commands.WaitCommand;
53
import org.eclipse.tptp.test.auto.gui.internal.macro.EventConstants;
54
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
55
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
56
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
57
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
58
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
59
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
60
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
61
62
/**
63
 * @author Alexander Nyssen
64
 * 
65
 */
66
public class MacroCommandFactory implements IMacroCommandFactory {
67
68
	/* The last event received */
69
	protected transient Event lastEvent;
70
71
	/* Indicates user interaction -- Set when a key up event is received */
72
	protected transient boolean isKeyPressed;
73
74
	/* Indicates user interaction -- Set when a mouse up event is received */
75
	protected transient boolean isMousePressed;
76
77
	/* Stores an event that is only acknowledged followed by user interaction. */
78
	protected transient Event toBeAckEvent;
79
80
	/* Set when the stored event in toBeAckEvent is acknowledged */
81
	protected transient boolean ackEvent;
82
83
	/* Stores the time for which a command was last created in */
84
	protected long lastCommandCreationTime;
85
86
	public IMacroCommand createCommand(MacroCommandShell commandShell,
87
			ArrayList commands, Event event) throws CoreException {
88
89
		// see if we can merge the event with the last created command
90
		AbstractMacroCommand lastCommand = getLastCommand(commands);
91
		if (lastEvent != null
92
				&& (lastEvent.detail == EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT || (lastEvent.widget != null
93
						&& lastEvent.widget.equals(event.widget) && (lastEvent.type == event.type || (lastEvent.type == SWT.Selection && event.type == SWT.DefaultSelection))))) {
94
			try {
95
				if (lastCommand != null && lastCommand.mergeEvent(event)) {
96
					return null;
97
				}
98
			} catch (Exception e) {
99
				// simply continue (the last command could not merge the
100
				// event)
101
			}
102
		}
103
104
		AbstractMacroCommand command = null;
105
		if (event.detail == EventConstants.EVENT_DETAIL__POSITION_BASED_EVENT)
106
			command = createPositionBasedCommand(commandShell, event);
107
		else if (event.detail == EventConstants.EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT) {
108
			command = createVerificationHookInsertionCommand(commandShell,
109
					event);
110
		} else {
111
			command = createObjectBasedCommand(commandShell, commands, event);
112
		}
113
114
		if (command != null) {
115
			/*
116
			 * Take out the last command if it is a focus command and the
117
			 * command just passed in implicitly does a focus
118
			 */
119
			if (lastCommand != null
120
					&& (lastCommand instanceof ObjectBasedCommand
121
							&& command instanceof ObjectBasedCommand
122
							&& ((ObjectBasedCommand) lastCommand)
123
									.getMacroObjectIdentifier()
124
									.equals(
125
											((ObjectBasedCommand) command)
126
													.getMacroObjectIdentifier())
127
							&& lastCommand.getType().equals(FocusCommand.TYPE) && isFocusCommand(command
128
							.getType()))) {
129
				// focus followed by select or modify - focus implied
130
				commands.remove(lastCommand);
131
			}
132
133
			/* Modify the last event accordinggly */
134
			if (ackEvent) {
135
				ackEvent = false;
136
				lastEvent = toBeAckEvent;
137
				toBeAckEvent = null;
138
			} else {
139
				lastEvent = event;
140
			}
141
142
			/* Add the artificial wait time if required */
143
			if (MacroManager.getInstance().isArtificialWaitOn()
144
					&& lastCommandCreationTime > 0) {
145
				long currentTime = System.currentTimeMillis();
146
				long difference = currentTime - lastCommandCreationTime;
147
				command.setTimeDifference(difference);
148
			}
149
150
			lastCommandCreationTime = System.currentTimeMillis();
151
152
			/*
153
			 * Ali M.: The following block of code provides a workaround for a
154
			 * limitation that exists for CloseWorkbenchPartCommand. We are only
155
			 * able to capture this event after the entire part has been
156
			 * disposed. Things would be ideal if this event could be captured
157
			 * right after the user clicks on the close button of the part
158
			 */
159
			if (command instanceof CloseWorkbenchPartCommand) {
160
				int commandSize = commands.size();
161
				if (commandSize > 0) {
162
					/*
163
					 * If the last command corresponds to the message dialog
164
					 * that prompts the user to save an editor, then store it
165
					 * after the close command
166
					 * 
167
					 * ANy: Since Eclipse 3.4 this does not seem to be a
168
					 * MessageDialog any more, but a private anonymous Dialog
169
					 * implementation in org.eclipse.ui.internal.SaveablesList,
170
					 * so I adopted this here.
171
					 */
172
					/* If the last stored command is a shell */
173
					Object lastCommandStored = commands.get(commandSize - 1);
174
					if (lastCommandStored instanceof MacroCommandShell
175
							&&
176
							/*
177
							 * If the part is an editor
178
							 */
179
							((CloseWorkbenchPartCommand) command)
180
									.getMacroObjectIdentifier()
181
									.getContextIdentifier().equals(
182
											MacroConstants.EDITOR_VALUE)
183
							&&
184
							/*
185
							 * If the shell is a MessageDialog or it is a
186
							 * private dialog inside the SaveablesList (Eclipse
187
							 * 3.4)
188
							 */
189
							(((MacroCommandShell) lastCommandStored)
190
									.getMacroObjectIdentifier()
191
									.getObjectIdentifier().getWidgetId()
192
									.startsWith("org.eclipse.ui.internal.SaveablesList"))
193
							|| ((MacroCommandShell) lastCommandStored)
194
									.getMacroObjectIdentifier()
195
									.getObjectIdentifier().getWidgetId()
196
									.equals(MessageDialog.class.getName()))
197
198
					{
199
						commands.add(commandSize - 1, command);
200
					}
201
202
				}
203
204
			} else {
205
				/*
206
				 * Added for defect 164197 in order to add an item-expansion to
207
				 * the parent whenever the child is selected in a case where the
208
				 * parent has been pre-expanded. Liz D.
209
				 */
210
				if (command instanceof StructuredSelectionCommand
211
						&& event.widget instanceof Tree) {
212
					StructuredSelectionCommand s = (StructuredSelectionCommand) command;
213
214
					TreeItem[] items = (TreeItem[]) s.getItemsForEvent(event);
215
					for (int i = 0; i < items.length; i++) {
216
						TreeItem selectedItem = (TreeItem) items[i];
217
218
						while (selectedItem.getParentItem() != null) {
219
							TreeItem parent = selectedItem.getParentItem();
220
							if (parent.getExpanded() == true) {// necessary so
221
								// that
222
								// we only apply
223
								// this in the case
224
								// where the parent
225
								// is already
226
								// expanded
227
								Event expansionEvent = new Event();
228
								expansionEvent.widget = parent;
229
								expansionEvent.item = parent;
230
								ExpansionCommand parentExpand = new ExpansionCommand(
231
										commandShell, s
232
												.getMacroObjectIdentifier());
233
								parentExpand.doProcessEvent(expansionEvent,
234
										true);
235
								commands.add(parentExpand);
236
							}
237
							selectedItem = parent;
238
						}// end while
239
					}
240
				}
241
242
				// add the command at the end of the list
243
				commands.add(command);
244
			}
245
		}
246
		return command;
247
	}
248
249
	/**
250
	 * Handles object-based events
251
	 */
252
	protected AbstractMacroCommand createObjectBasedCommand(
253
			MacroCommandShell commandShell, ArrayList commands, Event event) {
254
		/*
255
		 * A quick way to get out if we're only getting key up or mouse events
256
		 * that have been detected before
257
		 */
258
		if ((isKeyPressed && event.type == SWT.KeyUp)
259
				|| (isMousePressed && event.type == SWT.MouseUp))
260
			return null;
261
262
		ObjectBasedCommand command = null;
263
264
		/* Check to see if we are a drop-down menu selection */
265
		AbstractMacroCommand lastCommand = getLastCommand(commands);
266
		if (lastCommand != null
267
				&& lastCommand.getType() == BooleanSelectionCommand.TYPE
268
				&& ((BooleanSelectionCommand) lastCommand).getDetail() == SWT.DROP_DOWN) {
269
			((BooleanSelectionCommand) lastCommand).setItemSelected(event);
270
			return null;
271
		}
272
273
		if (event.type == EventConstants.EVENT_TYPE__WORKBENCH_PART_CLOSED) {
274
			/*
275
			 * 110810 -- Create the close workbench command only if there is
276
			 * only one frame in our shell stack
277
			 */
278
			if (MacroManager.getInstance().getCurrentMacro()
279
					.getShellStackSize() == 1) {
280
				command = new CloseWorkbenchPartCommand(commandShell);
281
			}
282
		} else {
283
			// process standard SWT event types
284
			switch (event.type) {
285
			case SWT.Modify:
286
				if (!isEditable(event.widget))
287
					return null;
288
289
				/*
290
				 * This block of code is used to avoid displaying the browse
291
				 * native dialog when the user clicks a browse button - it
292
				 * doesn't cover all cases
293
				 */
294
				// ANy: Added check that button is not disposed
295
				if (lastEvent != null && lastEvent.type == SWT.Selection
296
						&& lastEvent.widget instanceof Button
297
						&& !lastEvent.widget.isDisposed()) {
298
					String text = ((Button) lastEvent.widget).getText();
299
					if (text != null) {
300
						text = text.replaceAll("\\&", "");
301
						text = text.toLowerCase();
302
						if (text
303
								.indexOf(AutoGUIMessages.AUTO_GUI_CONTROL_STATUS_BROWSE) != -1) {
304
							int size = 0;
305
							if (commands != null
306
									&& (size = commands.size()) > 0) {
307
								commands.remove(size - 1);
308
								command = new ModifyCommand(commandShell);
309
								break;
310
							}
311
						}
312
					}
313
				}
314
315
				/* Only acknowledge modifies that are followed by a key up event */
316
				toBeAckEvent = event;
317
				break;
318
319
			case SWT.Selection:
320
			case SWT.DefaultSelection:
321
				command = createSelectionCommand(commandShell, event);
322
				break;
323
324
			case SWT.FocusIn:
325
				/**
326
				 * Ali M.: While recording, the SWT display listener has the
327
				 * tendency to report focus events on controls that are actually
328
				 * not visible to the user. When the macro is played back, the
329
				 * control cannot be located. To avoid this problem we only
330
				 * acknowledge focus events that are followed by a mouse up or
331
				 * key up event (i.e. The user explicitly focuses on the
332
				 * control).
333
				 */
334
				toBeAckEvent = event;
335
				break;
336
337
			case SWT.Expand:
338
			case SWT.Collapse:
339
				command = new ExpansionCommand(commandShell);
340
				break;
341
342
			case SWT.KeyUp:
343
				isKeyPressed = true;
344
				if (toBeAckEvent != null && toBeAckEvent.type == SWT.Modify) {
345
					command = new ModifyCommand(commandShell);
346
					ackEvent = true;
347
				} else if (toBeAckEvent != null
348
						&& toBeAckEvent.type == SWT.FocusIn) {
349
					command = new FocusCommand(commandShell);
350
					ackEvent = true;
351
				}
352
				break;
353
354
			case SWT.MouseUp:
355
				isMousePressed = true;
356
				if (toBeAckEvent != null && toBeAckEvent.type == SWT.FocusIn) {
357
					command = new FocusCommand(commandShell);
358
					ackEvent = true;
359
				}
360
				break;
361
			}
362
		}
363
364
		if (event.type != SWT.KeyUp)
365
			isKeyPressed = false;
366
		if (event.type != SWT.MouseUp)
367
			isMousePressed = false;
368
369
		if (command != null) {
370
			try {
371
				if (ackEvent) {
372
					command.processEvent(toBeAckEvent);
373
				} else {
374
					command.processEvent(event);
375
				}
376
			} catch (Exception e) {
377
				e.printStackTrace();
378
				command = null;
379
			}
380
		}
381
382
		/* Ensure that redundant commands are not created */
383
		if (lastCommand != null && command != null
384
				&& command.isRepeatRedundant() && command.equals(lastCommand)) {
385
			return null;
386
		}
387
		return command;
388
	}
389
390
	/**
391
	 * Handles position-based events
392
	 */
393
	protected AbstractMacroCommand createPositionBasedCommand(
394
			MacroCommandShell commandShell, Event event) {
395
		AbstractMacroCommand command = null;
396
397
		switch (event.type) {
398
		case SWT.MouseUp:
399
		case SWT.MouseDown:
400
		case SWT.MouseMove:
401
		case SWT.MouseDoubleClick:
402
			command = new MouseEventCommand(commandShell);
403
			break;
404
405
		case SWT.KeyUp:
406
		case SWT.KeyDown:
407
			command = new KeyEventCommand(commandShell);
408
			break;
409
410
		}
411
412
		if (command != null)
413
			try {
414
				command.processEvent(event);
415
			} catch (Exception e) {
416
				command = null;
417
			}
418
		return command;
419
	}
420
421
	protected ObjectBasedCommand createSelectionCommand(
422
			MacroCommandShell commandShell, Event event) {
423
		if (event.widget instanceof MenuItem
424
				|| event.widget instanceof ToolItem
425
				|| (event.widget instanceof Button
426
				/*
427
				 * A CCombo will cause a button selection followed by a combo
428
				 * selection. We need to ignore the button selection
429
				 */
430
				&& !(event.widget instanceof Control && ((Control) event.widget)
431
						.getParent() instanceof CCombo))) {
432
			ObjectBasedCommand selectionCommand = new BooleanSelectionCommand(
433
					commandShell);
434
			return selectionCommand;
435
		}
436
437
		if (event.widget instanceof Tree || event.widget instanceof Table
438
				|| event.widget instanceof List) {
439
			if (event.detail == SWT.CHECK) {
440
				ObjectBasedCommand selectionCommand = new CheckCommand(
441
						commandShell);
442
				return selectionCommand;
443
			} else {
444
				String type = event.type == SWT.DefaultSelection ? StructuredSelectionCommand.DEFAULT_SELECT
445
						: StructuredSelectionCommand.ITEM_SELECT;
446
				ObjectBasedCommand selectionCommand = new StructuredSelectionCommand(
447
						commandShell, type);
448
				return selectionCommand;
449
			}
450
		}
451
452
		if (event.widget instanceof TabFolder
453
				|| event.widget instanceof CTabFolder) {
454
			ObjectBasedCommand selectionCommand = new ChoiceSelectionCommand(
455
					commandShell);
456
			return selectionCommand;
457
		}
458
		if (event.widget instanceof Combo || event.widget instanceof CCombo) {
459
			ObjectBasedCommand selectionCommand = new ChoiceSelectionCommand(
460
					commandShell);
461
			return selectionCommand;
462
		}
463
		return null;
464
	}
465
466
	/**
467
	 * @param event
468
	 * @return
469
	 */
470
	protected AbstractMacroCommand createVerificationHookInsertionCommand(
471
			MacroCommandShell commandShell, Event event) throws CoreException {
472
473
		VerificationCommand command = null;
474
475
		String error = "";
476
477
		try {
478
			/* Ignore all command except for a focus in command */
479
			switch (event.type) {
480
			case SWT.Activate:
481
			case SWT.Selection:
482
			case SWT.FocusIn:
483
484
				IMacroObjectIdentifier widgetID = MacroObjectResolver.resolve(
485
						commandShell.getShell(), new MacroObject(new UIObject(
486
								event.widget)));
487
				String path = (widgetID == null ? "" : new Path(widgetID
488
						.getContextIdentifier() == null ? "" : widgetID
489
						.getContextIdentifier())
490
						.append(
491
								new Path(widgetID.getObjectIdentifier()
492
										.getWidgetId() == null ? "" : widgetID
493
										.getObjectIdentifier().getWidgetId()))
494
						.toString());
495
496
				if (VerificationCommand.findFocusType(path) == -1) {
497
					error = AutoGUIMessages.AUTO_GUI_ERROR_VER_NOT_SUPP_CON;
498
					break;
499
				}
500
501
				/* We only acknowledge after there is a mouse up event */
502
				toBeAckEvent = event;
503
				break;
504
505
			case SWT.MouseUp:
506
507
				if (toBeAckEvent == null)
508
					break;
509
510
				/* Create the verification command instance */
511
				command = new VerificationCommand(commandShell);
512
				command.processEvent(toBeAckEvent);
513
514
				ackEvent = true;
515
				break;
516
517
			default:
518
				toBeAckEvent = null;
519
				error = AutoGUIMessages.AUTO_GUI_ERROR_VER_WRONG_EVENT;
520
			}
521
		} catch (Exception e) {
522
			error = e.getMessage();
523
			e.printStackTrace();
524
		}
525
526
		if (error != null && !(error.equals(""))) {
527
			AutoGUIUtil.throwCoreException(error);
528
		}
529
		return command;
530
	}
531
532
	AbstractMacroCommand getLastCommand(ArrayList commands) {
533
		if (commands.size() > 0) {
534
			Object item = commands.get(commands.size() - 1);
535
			if (item instanceof AbstractMacroCommand)
536
				return (AbstractMacroCommand) item;
537
		}
538
		return null;
539
	}
540
541
	boolean isFocusCommand(String type) {
542
		return type.equals(BooleanSelectionCommand.TYPE)
543
				|| type.equals(StructuredSelectionCommand.ITEM_SELECT)
544
				|| type.equals(StructuredSelectionCommand.DEFAULT_SELECT)
545
				|| type.equals(ExpansionCommand.TYPE)
546
				|| type.equals(CheckCommand.TYPE)
547
				|| type.equals(ModifyCommand.TYPE);
548
	}
549
550
	private boolean isEditable(Widget widget) {
551
		if (widget instanceof Control) {
552
			Control control = (Control) widget;
553
			if (!control.isEnabled())
554
				return false;
555
			if (control instanceof Text)
556
				return ((Text) control).getEditable();
557
			if (control instanceof Combo || control instanceof CCombo)
558
				return ((control.getStyle() & SWT.READ_ONLY) == 0);
559
			if (control instanceof StyledText)
560
				return ((StyledText) control).getEditable();
561
		}
562
		return true;
563
	}
564
565
	public IMacroCommand createCommand(MacroCommandShell commandShell,
566
			String type) throws CoreException {
567
		// construct a new command dependent on the type
568
		AbstractMacroCommand command = null;
569
570
		if (type.equals(ModifyCommand.TYPE))
571
			command = new ModifyCommand(commandShell);
572
573
		else if (type.equals(BooleanSelectionCommand.TYPE))
574
			command = new BooleanSelectionCommand(commandShell);
575
576
		else if (type.equals(StructuredSelectionCommand.ITEM_SELECT)
577
				|| type.equals(StructuredSelectionCommand.DEFAULT_SELECT))
578
			command = new StructuredSelectionCommand(commandShell, type);
579
580
		else if (type.equals(ExpansionCommand.TYPE))
581
			command = new ExpansionCommand(commandShell);
582
583
		else if (type.equals(CheckCommand.TYPE))
584
			command = new CheckCommand(commandShell);
585
586
		else if (type.equals(FocusCommand.TYPE))
587
			command = new FocusCommand(commandShell);
588
589
		else if (type.equals(ChoiceSelectionCommand.TYPE))
590
			command = new ChoiceSelectionCommand(commandShell);
591
592
		else if (type.equals(WaitCommand.TYPE))
593
			command = new WaitCommand(commandShell);
594
595
		/* The verification command */
596
		else if (type.equals(VerificationCommand.TYPE))
597
			command = new VerificationCommand(commandShell);
598
599
		/* The close workbench part command */
600
		else if (type.equals(CloseWorkbenchPartCommand.TYPE))
601
			command = new CloseWorkbenchPartCommand(commandShell);
602
603
		/* Mouse events */
604
		else if (type.equals(MouseEventCommand.MOUSE_UP)
605
				|| type.equals(MouseEventCommand.MOUSE_DOWN)
606
				|| type.equals(MouseEventCommand.MOUSE_MOVE)
607
				|| type.equals(MouseEventCommand.MOUSE_CLICK))
608
			command = new MouseEventCommand(commandShell);
609
610
		/* Key events */
611
		else if (type.equals(KeyEventCommand.KEY_UP)
612
				|| type.equals(KeyEventCommand.KEY_DOWN)
613
				|| type.equals(KeyEventCommand.KEY_PRESS))
614
			command = new KeyEventCommand(commandShell);
615
616
		return command;
617
	}
618
619
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/IPersistable.java (+72 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macro;
12
13
import java.util.Hashtable;
14
15
import org.eclipse.core.runtime.CoreException;
16
import org.w3c.dom.Node;
17
18
19
20
/**
21
 * A writable object is capable of serializing itself to string and writing the string
22
 * version to a PrintWriter that is passed to parameters to the methods that are described
23
 * below. It is also capable of loading itself from a given node.
24
 * <br/>
25
 * The ideal order of the method invocations are:
26
 * <ul>
27
 * 	<li> writeStart(String indent, gPrintWriter writer) </li>
28
 * 	<li> write(String indent, PrintWriter writer) </li>
29
 * 	<li> writeFinish(String indent, PrintWriter writer) </li>
30
 * </ul>
31
 */
32
public interface IPersistable 
33
{
34
	/**
35
	 * Invoked at start of the write of a writable object
36
	 * 
37
	 * @param indent The indents
38
	 * @param sb The buffer that the string serialization should be written to
39
	 */
40
	public void writeStart(int indent, StringBuffer sb);
41
	
42
	
43
	/**
44
	 * Invoked after writeStart
45
	 * 
46
	 * @param indent The indents
47
	 * @param sb The buffer that the string serialization should be written to
48
	 */
49
	public void write(int indent, StringBuffer sb);
50
	
51
	
52
	/**
53
	 * Invoked in the end of the write of a writable object
54
	 * 
55
	 * @param indent The indents
56
	 * @param sb The buffer that the string serialization should be written to
57
	 */
58
	public void writeFinish(int indent, StringBuffer sb);
59
	
60
	/**
61
	 * Invoked to load the macro instruction based on its corresponding XML node.
62
	 * 
63
	 * @param node
64
	 *            The XML node representing this macro instruction
65
	 * @param lineTable
66
	 *            Contains line level information
67
	 * 
68
	 * @throws CoreException
69
	 *             In case of an unexpected error
70
	 */
71
	public void load(Node node, Hashtable lineTable) throws CoreException;
72
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMine.java (+616 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine;
12
13
import java.util.ArrayList;
14
import java.util.Hashtable;
15
import java.util.LinkedList;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
20
import org.eclipse.osgi.util.NLS;
21
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
22
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
23
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
25
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
26
import org.w3c.dom.NamedNodeMap;
27
import org.w3c.dom.Node;
28
29
/**
30
 * 
31
 * @author Ali Mehregani
32
 */
33
public class MacroObjectDescriptorMine {
34
	/** The root node of the tree structure that contains the objects */
35
	private MacroObjectDescriptor root;
36
37
	/** Included object mines */
38
	private ArrayList includes;
39
40
	/** The test suite that owns this object mine */
41
	private ITestSuite owner;
42
43
	/** The output object mine */
44
	private MacroObjectDescriptorMine outputObjectMine;
45
46
	/** The active object */
47
	private MacroObjectDescriptor activeObject;
48
49
	/**
50
	 * Keeps track of the maximum reference id in use. This is used to generate
51
	 * a unique reference id when requested
52
	 */
53
	private int maximumRefId;
54
55
	/** The xml handler used to parse the object mine */
56
	private XMLDefaultHandler defaultXMLHandler;
57
58
	public MacroObjectDescriptorMine(ITestSuite testSuite,
59
			XMLDefaultHandler defaultXMLHandler) {
60
		owner = testSuite;
61
		root = new MacroObjectDescriptor(null);
62
		includes = new ArrayList();
63
		this.defaultXMLHandler = defaultXMLHandler;
64
	}
65
66
	public void addInclude(MacroObjectDescriptorMine objectMine) {
67
		includes.add(objectMine);
68
		if (outputObjectMine != null) {
69
			MacroObjectDescriptorMine foundObjectMine = findIncludedObjectMine(outputObjectMine);
70
			outputObjectMine = foundObjectMine == null ? outputObjectMine
71
					: foundObjectMine;
72
		}
73
	}
74
75
	public MacroObjectDescriptor lookupMacroObjectDescriptor(
76
			MacroObjectDescriptor parent, String referenceId) {
77
		MacroObjectDescriptor uiObject = lookupIncludes(parent, referenceId);
78
		if (uiObject != null)
79
			return uiObject;
80
81
		uiObject = lookupMacroObjectDescriptor(parent);
82
		if (uiObject == null)
83
			return null;
84
85
		uiObject = uiObject.findChild(referenceId);
86
		return uiObject;
87
	}
88
89
	private MacroObjectDescriptor lookupMacroObjectDescriptor(
90
			MacroObjectDescriptor object, boolean requiresPresence)
91
			throws UIObjectNotFound {
92
		if (object == null) {
93
			return root;
94
		}
95
96
		LinkedList relationship = object.getHierarchicalRelation();
97
		MacroObjectDescriptor currentNode = root;
98
		for (int i = 0, height = relationship.size(); currentNode != null
99
				&& i < height; i++) {
100
			currentNode = currentNode
101
					.findChild(((MacroObjectDescriptor) relationship.get(i))
102
							.getReferenceId());
103
		}
104
105
		if (currentNode == null && requiresPresence)
106
			throw new UIObjectNotFound(NLS.bind(
107
					AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF, object
108
							.getReferenceId()));
109
110
		return currentNode;
111
	}
112
113
	public MacroObjectDescriptor lookupMacroObjectDescriptor(
114
			MacroObjectDescriptor parent, String contextId, String widgetId,
115
			String objectId) {
116
		MacroObjectDescriptor uiObject = lookupIncludes(parent, contextId,
117
				widgetId, objectId);
118
		if (uiObject != null)
119
			return uiObject;
120
121
		MacroObjectDescriptor parentNode = lookupMacroObjectDescriptor(parent);
122
		if (parentNode == null)
123
			return null;
124
125
		MacroObjectDescriptor[] children = parentNode.getChildren();
126
		for (int i = 0; i < children.length; i++) {
127
			if (((contextId == null && children[i].getContextId() == null) || (contextId != null && contextId
128
					.equals(children[i].getContextId())))
129
					&& widgetId.equals(children[i].getWidgetId())
130
					&& ((objectId == null && children[i].getObjectId() == null) || (objectId != null && objectId
131
							.equals(children[i].getObjectId())))) {
132
				return children[i];
133
			}
134
135
		}
136
		return null;
137
	}
138
139
	public MacroObjectDescriptor[] getChildren() {
140
		return root.getChildren();
141
	}
142
143
	private MacroObjectDescriptor lookupMacroObjectDescriptor(
144
			MacroObjectDescriptor parent) {
145
		try {
146
			return lookupMacroObjectDescriptor(parent, false);
147
		} catch (UIObjectNotFound e) {
148
			return null;
149
		}
150
	}
151
152
	/**
153
	 * Looks up the included object mine to determine if they have a
154
	 * corresponding object with the reference id passed in.
155
	 * 
156
	 * @param parent
157
	 *            The parent of the object
158
	 * @param referenceId
159
	 *            The reference id of the object
160
	 * 
161
	 * @return The object with the reference id passed in; null if none is
162
	 *         found.
163
	 * @throws UIObjectNotFound
164
	 *             In case the parent can't be found.
165
	 */
166
	private MacroObjectDescriptor lookupIncludes(MacroObjectDescriptor parent,
167
			String referenceId) {
168
		MacroObjectDescriptor[] uiObject = lookupIncludes(parent, referenceId,
169
				null, null, null);
170
		return uiObject != null && uiObject.length > 0 ? uiObject[0] : null;
171
	}
172
173
	/**
174
	 * Looks up the included object mine to determine if they have a
175
	 * corresponding object with the contextId id and object id passed in.
176
	 * 
177
	 * @param parent
178
	 *            The parent of the object
179
	 * @param contextId
180
	 *            The context id of the object
181
	 * @param widgetId
182
	 *            The id of the object
183
	 * 
184
	 * @return The object with the matching context and object id passed in;
185
	 *         null if none is found.
186
	 * @throws UIObjectNotFound
187
	 *             In case the parent can't be found.
188
	 */
189
	private MacroObjectDescriptor lookupIncludes(MacroObjectDescriptor parent,
190
			String contextId, String widgetId, String objectId) {
191
		MacroObjectDescriptor[] uiObject = lookupIncludes(parent, null,
192
				contextId, widgetId, objectId);
193
		return uiObject != null && uiObject.length > 0 ? uiObject[0] : null;
194
	}
195
196
	/**
197
	 * Looks up the included object mines to find an object that has been
198
	 * requested. If reference id happens to be null, then context/object id are
199
	 * used.
200
	 * 
201
	 * @param parent
202
	 *            The parent of the object
203
	 * @param referenceId
204
	 *            The reference id of the object.
205
	 * @param contextId
206
	 *            The context id of the object
207
	 * @param widgetId
208
	 *            The id of the object
209
	 * 
210
	 * @return The objects to look for
211
	 */
212
	private MacroObjectDescriptor[] lookupIncludes(
213
			MacroObjectDescriptor parent, String referenceId, String contextId,
214
			String widgetId, String objectId) {
215
		boolean useReferenceId = referenceId != null;
216
		boolean useObjectId = widgetId != null;
217
218
		MacroObjectDescriptor objectRequested = null;
219
		MacroObjectDescriptor[] children = null;
220
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++) {
221
			MacroObjectDescriptorMine objectMine = (MacroObjectDescriptorMine) includes
222
					.get(i);
223
			if (useReferenceId) {
224
				objectRequested = objectMine.lookupMacroObjectDescriptor(
225
						parent, referenceId);
226
			} else if (useObjectId) {
227
				objectRequested = objectMine.lookupMacroObjectDescriptor(
228
						parent, contextId, widgetId, objectId);
229
			}
230
231
			children = objectRequested == null ? children
232
					: new MacroObjectDescriptor[] { objectRequested };
233
			if (children != null) {
234
				return children;
235
			}
236
		}
237
238
		return null;
239
	}
240
241
	public MacroObjectDescriptor getRoot() {
242
		return root;
243
	}
244
245
	public MacroObjectDescriptor registerObject(MacroObjectDescriptor parent,
246
			Node objectNode) throws IDCollisionException, UIObjectNotFound,
247
			CoreException {
248
		NamedNodeMap attributes = objectNode.getAttributes();
249
		MacroObjectDescriptor macroObjectDescriptor = new MacroObjectDescriptor(
250
				parent);
251
252
		MacroObjectDescriptor node = lookupMacroObjectDescriptor(parent, true);
253
254
		/* Set the attributes of the object */
255
		String referenceIdStr = getAttribute(attributes,
256
				MacroConstants.REFERENCE_ID_ATTRIBUTE);
257
		updateMaxReferenceId(referenceIdStr);
258
259
		Hashtable lineLevelDetail = null;
260
		if (defaultXMLHandler != null)
261
			lineLevelDetail = defaultXMLHandler.getLineTable();
262
		macroObjectDescriptor.setReferenceId(referenceIdStr);
263
		macroObjectDescriptor.setContextId(getAttribute(attributes,
264
				MacroConstants.CONTEXT_ID_ATTRIBUTE));
265
		// for backwards compatibility, also search for an ID attribute (old
266
		// format). Otherwise read the widget and object id
267
		if (getAttribute(attributes, MacroConstants.ID_ATTRIBUTE) != null) {
268
			macroObjectDescriptor.setWidgetId(getAttribute(attributes,
269
					MacroConstants.ID_ATTRIBUTE));
270
		} else {
271
			macroObjectDescriptor.setWidgetId(getAttribute(attributes,
272
					MacroConstants.WIDGET_ID_ATTRIBUTE));
273
			macroObjectDescriptor.setObjectId(getAttribute(attributes,
274
					MacroConstants.OBJECT_ID_ATTRIBUTE));
275
		}
276
		macroObjectDescriptor.setDescriptive(getAttribute(attributes,
277
				MacroConstants.DESCRIPTIVE_ATTRIBUTE));
278
		macroObjectDescriptor.setResolver(getAttribute(attributes,
279
				MacroConstants.RESOLVER_ID_ATTRIBUTE));
280
		if (lineLevelDetail != null)
281
			macroObjectDescriptor.setData(((Integer[]) lineLevelDetail
282
					.get(objectNode)));
283
		node.addChild(macroObjectDescriptor);
284
285
		return macroObjectDescriptor;
286
	}
287
288
	public MacroObjectDescriptor registerObject(MacroObjectDescriptor uiObject)
289
			throws IDCollisionException, UIObjectNotFound, CoreException {
290
		// assign a new unique id to the MacroObjectDescriptor
291
		String uniqueId = getUniqueReferenceId();
292
		updateMaxReferenceId(uniqueId);
293
		uiObject.setReferenceId(uniqueId);
294
295
		MacroObjectDescriptor parentObject = uiObject.getParent();
296
297
		/*
298
		 * If the object that is about to be registered happens to be at the
299
		 * first level (i.e. it is an infant), then it needs to be registered
300
		 * with the output destination of this object mine
301
		 */
302
		if (parentObject == null && outputObjectMine != null) {
303
			outputObjectMine.registerObject(uiObject);
304
			includes.contains(outputObjectMine);
305
			return uiObject;
306
		}
307
308
		if (parentObject == null) {
309
			root.addChild(uiObject);
310
		} else {
311
			parentObject.addChild(uiObject);
312
		}
313
314
		return uiObject;
315
	}
316
317
	private void updateMaxReferenceId(String referenceIdStr) {
318
		try {
319
			int referenceId = Integer.parseInt(referenceIdStr);
320
			int maximumIncludedRefId = findMaximumIncludedRefId();
321
			maximumRefId = Math.max(
322
					Math.max(referenceId, maximumIncludedRefId), maximumRefId);
323
324
			if (referenceId == maximumRefId)
325
				maximumRefId++;
326
		} catch (NumberFormatException nfe) {
327
			/* Doesn't need to be handled */
328
		}
329
	}
330
331
	/**
332
	 * Walks through the included object mines of this object mine to determine
333
	 * the unique reference id.
334
	 * 
335
	 * @return A unique reference id that is global to all included object
336
	 *         mines.
337
	 */
338
	private int findMaximumIncludedRefId() {
339
		int uniqueRefId = 0;
340
341
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++) {
342
			MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes
343
					.get(i);
344
			try {
345
				uniqueRefId = Math.max(Integer.parseInt(currentObjectMine
346
						.getUniqueReferenceId()), uniqueRefId);
347
			} catch (NumberFormatException nfe) {
348
				/* Ignore the exception */
349
			}
350
		}
351
		return uniqueRefId;
352
	}
353
354
	private String getAttribute(NamedNodeMap attributes, String attributeName) {
355
		Node attr = attributes.getNamedItem(attributeName);
356
		return attr == null ? null : attr.getNodeValue();
357
	}
358
359
	public void setOutputSource(MacroObjectDescriptorMine objectMine) {
360
		outputObjectMine = objectMine == null ? null
361
				: findIncludedObjectMine(objectMine);
362
		if (outputObjectMine == null)
363
			outputObjectMine = objectMine;
364
	}
365
366
	public MacroObjectDescriptorMine getOutputSource() {
367
		return outputObjectMine;
368
	}
369
370
	private MacroObjectDescriptorMine findIncludedObjectMine(
371
			MacroObjectDescriptorMine objectMine) {
372
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++) {
373
			MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes
374
					.get(i);
375
			if (currentObjectMine.equals(objectMine))
376
				return currentObjectMine;
377
		}
378
379
		return null;
380
	}
381
382
	public ITestSuite getOwner() {
383
		return owner;
384
	}
385
386
	public static class UIObjectNotFound extends Exception {
387
		static final long serialVersionUID = 4699726279267599112L;
388
389
		public UIObjectNotFound(String message) {
390
			super(message);
391
		}
392
	}
393
394
	public static class IDCollisionException extends Exception {
395
		static final long serialVersionUID = -6526030843455792891L;
396
397
		public IDCollisionException(String message) {
398
			super(message);
399
		}
400
	}
401
402
	public String serializeToString() {
403
		StringBuffer objectMineSerialized = new StringBuffer();
404
		int indent = 0;
405
406
		/* <object-mine> */
407
		MacroUtil.addElement(objectMineSerialized, indent,
408
				MacroConstants.OBJECT_MINE_ELEMENT, false, true);
409
410
		serializeHeader(objectMineSerialized, indent + 1, true);
411
		serializeObjects(objectMineSerialized, indent + 1, true);
412
413
		/* </object-mine> */
414
		MacroUtil.addElement(objectMineSerialized, indent,
415
				MacroConstants.OBJECT_MINE_ELEMENT, true, true);
416
417
		return objectMineSerialized.toString();
418
	}
419
420
	private void serializeHeader(StringBuffer objectMineSerialized, int indent,
421
			boolean includeHeader) {
422
		/* Don't write anything if the header is empty */
423
		if (outputObjectMine == null
424
				&& (includes == null || includes.size() <= 0))
425
			return;
426
427
		boolean outputElement = outputObjectMine != null;
428
429
		/* <header output="..."/> */
430
		if (includeHeader) {
431
			MacroUtil.addElement(objectMineSerialized, indent,
432
					MacroConstants.HEADER_ELEMENT, false, !outputElement);
433
			if (outputElement)
434
				MacroUtil.addAttribute(objectMineSerialized,
435
						new String[] { MacroConstants.OUTPUT_ATTRIBUTE },
436
						new String[] { AutoGUIUtil
437
								.resolveTestSuitePath(outputObjectMine
438
										.getOwner()) }, false, true);
439
		}
440
441
		/* Add the <include .../> elements */
442
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++) {
443
			MacroObjectDescriptorMine currentInclude = (MacroObjectDescriptorMine) includes
444
					.get(i);
445
			ITestSuite testSuite = currentInclude.getOwner();
446
			String path = AutoGUIUtil.resolveTestSuitePath(testSuite);
447
448
			if (path != null) {
449
				MacroUtil.addElement(objectMineSerialized, indent + 1,
450
						MacroConstants.INCLUDE_ELEMENT, false, false);
451
				MacroUtil.addAttribute(objectMineSerialized,
452
						new String[] { MacroConstants.PATH_ATTRIBUTE },
453
						new String[] { path }, true, true);
454
			}
455
		}
456
457
		if (includeHeader) {
458
			MacroUtil.addElement(objectMineSerialized, indent,
459
					MacroConstants.HEADER_ELEMENT, true, true);
460
		}
461
	}
462
463
	private void serializeObjects(StringBuffer objectMineSerialized,
464
			int indent, boolean includeHeader) {
465
		MacroObjectDescriptor[] rootChildren = root.getChildren();
466
		if (rootChildren == null || rootChildren.length <= 0)
467
			return;
468
469
		/* Add the objects */
470
		if (includeHeader) {
471
			MacroUtil.addElement(objectMineSerialized, indent,
472
					MacroConstants.OBJECTS_ELEMENT, false, true);
473
			addObject(objectMineSerialized, indent + 1, rootChildren);
474
			MacroUtil.addElement(objectMineSerialized, indent,
475
					MacroConstants.OBJECTS_ELEMENT, true, true);
476
			return;
477
		}
478
479
		addObject(objectMineSerialized, indent + 1, rootChildren);
480
	}
481
482
	/**
483
	 * @see org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptorMine#serializeHeaderToString()
484
	 */
485
	public String serializeHeaderToString() {
486
		StringBuffer sb = new StringBuffer();
487
		serializeHeader(sb, 0, false);
488
		return sb.toString();
489
	}
490
491
	/**
492
	 * @see org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptorMine#serializeObjetsToString()
493
	 */
494
	public String serializeObjetsToString() {
495
		StringBuffer sb = new StringBuffer();
496
		serializeObjects(sb, 0, false);
497
		return sb.toString();
498
	}
499
500
	private void addObject(StringBuffer objectMapSerialized, int indent,
501
			MacroObjectDescriptor[] rootChildren) {
502
		if (rootChildren == null)
503
			return;
504
505
		for (int i = 0; i < rootChildren.length; i++) {
506
			MacroObjectDescriptor currentMacroObjectDescriptor = rootChildren[i];
507
			MacroObjectDescriptor[] children = rootChildren[i].getChildren();
508
509
			/* If the object is a shell without any children, then skip it */
510
			if (currentMacroObjectDescriptor.getParent() == null
511
					&& (children == null || children.length <= 0))
512
				continue;
513
514
			boolean hasChildren = children != null && children.length > 0;
515
			MacroUtil.addElement(objectMapSerialized, indent,
516
					MacroConstants.OBJECT_ELEMENT, false, false);
517
			MacroUtil.addAttribute(objectMapSerialized, new String[] {
518
					MacroConstants.DESCRIPTIVE_ATTRIBUTE,
519
					MacroConstants.REFERENCE_ID_ATTRIBUTE,
520
					MacroConstants.CONTEXT_ID_ATTRIBUTE,
521
					MacroConstants.RESOLVER_ID_ATTRIBUTE,
522
					MacroConstants.WIDGET_ID_ATTRIBUTE,
523
					MacroConstants.OBJECT_ID_ATTRIBUTE }, new String[] {
524
					currentMacroObjectDescriptor.getDescriptive(),
525
					currentMacroObjectDescriptor.getReferenceId(),
526
					currentMacroObjectDescriptor.getContextId(),
527
					currentMacroObjectDescriptor.getResolverId(),
528
					currentMacroObjectDescriptor.getWidgetId(),
529
					currentMacroObjectDescriptor.getObjectId() }, !hasChildren,
530
					true);
531
			if (hasChildren) {
532
				addObject(objectMapSerialized, indent + 1, rootChildren[i]
533
						.getChildren());
534
				MacroUtil.addElement(objectMapSerialized, indent,
535
						MacroConstants.OBJECT_ELEMENT, true, true);
536
			}
537
		}
538
539
	}
540
541
	public MacroObjectDescriptor getActiveObject() {
542
		return activeObject;
543
	}
544
545
	public void setActiveObject(MacroObjectDescriptor activeObject) {
546
		this.activeObject = activeObject;
547
	}
548
549
	private String getUniqueReferenceId() {
550
		int maximumIncludedRefId = findMaximumIncludedRefId();
551
		maximumRefId = Math.max(maximumIncludedRefId, maximumRefId);
552
553
		/* Restart the reference id */
554
		if (maximumRefId >= Integer.MAX_VALUE - 10) {
555
			maximumRefId = 0;
556
		}
557
		return String.valueOf(maximumRefId);
558
	}
559
560
	public List getIncludes() {
561
		return includes;
562
	}
563
564
	public boolean equals(Object o) {
565
		return o instanceof MacroObjectDescriptorMine ? getOwner().getId()
566
				.equals(((MacroObjectDescriptorMine) o).getOwner().getId())
567
				: false;
568
	}
569
570
	public void setOwner(ITestSuite testSuite) {
571
		this.owner = testSuite;
572
	}
573
574
	/**
575
	 * If the node passed in has a reference id, then this method looks up the
576
	 * id in the object mine and attempts to find the object that is referenced.
577
	 * 
578
	 * @param node
579
	 *            Represents the XML node
580
	 * @param lineTable
581
	 *            Contains line level information
582
	 * 
583
	 * @return A String[] of length 2, where String[0] = context id and
584
	 *         String[1] = object id. If the node does not have a reference id,
585
	 *         then null is returned.
586
	 * 
587
	 * @throws CoreException
588
	 *             If the node contains a reference id attribute but the
589
	 *             corresponding object mine does not have any such object.
590
	 */
591
	public MacroObjectDescriptor lookupReferenceId(
592
			MacroObjectDescriptor parent, Node node, Hashtable lineTable)
593
			throws CoreException {
594
		String referenceId = MacroUtil.getAttribute(node,
595
				MacroConstants.REFERENCE_ID_ATTRIBUTE);
596
		if (referenceId == null)
597
			return null;
598
599
		MacroObjectDescriptor correspondingObject = lookupMacroObjectDescriptor(
600
				parent, referenceId);
601
		if (correspondingObject == null) {
602
			Integer[] lineLevelDetail = (Integer[]) lineTable.get(node);
603
			AutoGUIUtil
604
					.throwCoreException(NLS.bind(
605
							AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_NF,
606
							referenceId), lineLevelDetail == null ? 0
607
							: lineLevelDetail[0].intValue());
608
		} else {
609
			return correspondingObject;
610
		}
611
612
		/* Code not reached beyond this point */
613
		return null;
614
	}
615
616
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/ObjectBasedCommand.java (+321 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.commands;
13
14
import java.util.Hashtable;
15
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.osgi.util.NLS;
19
import org.eclipse.swt.widgets.Display;
20
import org.eclipse.swt.widgets.Event;
21
import org.eclipse.swt.widgets.Shell;
22
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
23
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
24
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
25
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
26
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
27
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
28
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject;
29
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
30
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
31
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
32
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptor;
33
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine;
34
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException;
35
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound;
36
import org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver.MacroObjectResolver;
37
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
38
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
39
import org.w3c.dom.Node;
40
41
/**
42
 * @author Alexander Nyssen
43
 * 
44
 */
45
public abstract class ObjectBasedCommand extends AbstractMacroCommand {
46
47
	/** The macro object of interest to the command */
48
	protected IMacroObject macroObject;
49
50
	/** The macro object id associated with this command */
51
	protected IMacroObjectIdentifier macroObjectIdentifier;
52
53
	/** The corresponding macro object for this object-based macro command */
54
	protected MacroObjectDescriptor macroObjectDescriptor;
55
56
	// used to detect wether a descriptive field has to be detected
57
	boolean needsDescriptiveField = false;
58
59
	/**
60
	 * @param parent
61
	 * @param widgetId
62
	 */
63
	public ObjectBasedCommand(MacroCommandShell parent) {
64
		super(parent);
65
	}
66
67
	protected void preProcessEvent(Event event) throws CoreException {
68
		macroObject = locateMacroObject(event);
69
70
		// retrieve the macro object identifier
71
		IMacroObjectIdentifier identifier = MacroObjectResolver.resolve(
72
				getParent().getShell(), macroObject);
73
		if (identifier == null) {
74
			AutoGUIUtil
75
					.throwCoreException(NLS.bind(AutoGUIMessages.AUTO_GUI_ERROR_MACRO_OBJECT_RESOLVE, macroObject.getUIObject().getWidget()));
76
		}
77
		setMacroObjectIdentifier(identifier);
78
79
		// register with object mine if in use and not already done
80
		MacroObjectDescriptor uiObject = null;
81
		if (useObjectMine()) {
82
			/*
83
			 * Lookup the widget of this command. If it already exists in our
84
			 * object mine, then have it referenced by setting the reference id
85
			 * of the command.
86
			 */
87
			MacroObjectDescriptorMine objectMine = MacroManager.getInstance()
88
					.getObjectMine();
89
90
			try {
91
				MacroObjectDescriptor activeObject = objectMine
92
						.getActiveObject();
93
				uiObject = objectMine.lookupMacroObjectDescriptor(activeObject,
94
						identifier.getContextIdentifier() == null ? null
95
								: identifier.getContextIdentifier(), identifier
96
								.getObjectIdentifier().getWidgetId(), identifier.getObjectIdentifier().getObjectId());
97
98
				/*
99
				 * The object is not registered with the object mine - register
100
				 * it
101
				 */
102
				if (uiObject == null) {
103
					needsDescriptiveField = true;
104
					uiObject = MacroObjectDescriptor.createInstance(this,
105
							activeObject);
106
					objectMine.registerObject((MacroObjectDescriptor) uiObject);
107
				}
108
				setCorrespondingMacroObjectDescriptor(uiObject);
109
			}
110
111
			/*
112
			 * We can't afford to show an error message in case of an unexpected
113
			 * error during registeration. We'll ignore the error and not make
114
			 * use of the object mine.
115
			 */
116
			catch (UIObjectNotFound e) {
117
				/* Should not happen */
118
			} catch (IDCollisionException e) {
119
				/* Should not happen */
120
			} catch (CoreException e) {
121
				/* Should not happen */
122
				e.printStackTrace();
123
			}
124
		}
125
	}
126
127
	protected void doProcessEvent(Event event) throws CoreException {
128
		// nothing to do by default
129
	}
130
131
	protected final void postProcessEvent(Event event) throws CoreException {
132
		// initialize the descriptive field of the associated macro object
133
		// descriptor
134
		if (useObjectMine() && needsDescriptiveField
135
				&& getCorrespondingMacroObjectDescriptor() != null) {
136
			// may safely cast into MacroObjectDescriptor here, as
137
			// needsDescriptiveField is only true if we have created a new one.
138
			((MacroObjectDescriptor) getCorrespondingMacroObjectDescriptor())
139
					.setDescriptive(getObjectClassName(event.widget)
140
							+ (getDescriptiveField() == null ? MacroConstants.EMPTY_STRING
141
									: ": " + getDescriptiveField()));
142
		}
143
	}
144
145
	/**
146
	 * {@inheritDoc}
147
	 * 
148
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand#processEvent(org.eclipse.swt.widgets.Event)
149
	 */
150
	public final void processEvent(Event event) throws CoreException {
151
		preProcessEvent(event);
152
153
		// let the original implementation do its job (detect the descriptive
154
		// field, for example)
155
		doProcessEvent(event);
156
157
		postProcessEvent(event);
158
	}
159
160
	/**
161
	 * This can be changed by subclasses, if for example a String entry of a
162
	 * combo box has to be checked...
163
	 * 
164
	 * @param event
165
	 * @return
166
	 */
167
	protected IMacroObject locateMacroObject(Event event) {
168
		return new MacroObject(new UIObject(event.widget));
169
	}
170
171
	/**
172
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getCorrespondingMacroObjectDescriptor()
173
	 */
174
	public MacroObjectDescriptor getCorrespondingMacroObjectDescriptor() {
175
		return macroObjectDescriptor;
176
	}
177
178
	/**
179
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#setCorrespondingMacroObjectDescriptor(org.eclipse.tptp.test.auto.gui.internal.util.MacroObjectDescriptor)
180
	 */
181
	protected void setCorrespondingMacroObjectDescriptor(
182
			MacroObjectDescriptor uiObject) {
183
		this.macroObjectDescriptor = uiObject;
184
	}
185
186
	/**
187
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#getMacroObjectIdentifier()
188
	 */
189
	public IMacroObjectIdentifier getMacroObjectIdentifier() {
190
		return macroObjectIdentifier;
191
	}
192
193
	/**
194
	 * @see org.eclipse.tptp.test.auto.gui.internal.macro.IMacroInstruction#setMacroObjectIdentifier(IMacroObjectIdentifier)
195
	 */
196
	protected void setMacroObjectIdentifier(
197
			IMacroObjectIdentifier objectIdentifier) {
198
		this.macroObjectIdentifier = objectIdentifier;
199
	}
200
201
	public void load(Node node, Hashtable lineTable) throws CoreException {
202
		super.load(node, lineTable);
203
204
		loadMacroObjectIdentifier(node, lineTable);
205
	}
206
207
	protected void loadMacroObjectIdentifier(Node node, Hashtable lineTable)
208
			throws CoreException {
209
		MacroObjectDescriptor commandObject = null;
210
		if (MacroManager.getInstance().getObjectMine() != null) {
211
			commandObject = MacroManager.getInstance().getObjectMine().lookupReferenceId(
212
					getParent().getCorrespondingMacroObjectDescriptor(), node,
213
					lineTable);
214
		}
215
		boolean isObjectFound = commandObject != null;
216
		if (isObjectFound) {
217
			setCorrespondingMacroObjectDescriptor(commandObject);
218
		}
219
		
220
		String cid = isObjectFound ? commandObject.getContextId() : MacroUtil
221
				.getAttribute(node, MacroConstants.CONTEXT_ID_ATTRIBUTE);
222
		String wid = isObjectFound ? commandObject.getWidgetId() : MacroUtil
223
				.getAttribute(node, MacroConstants.WIDGET_ID_ATTRIBUTE);
224
		String obj = isObjectFound ? commandObject.getObjectId() : MacroUtil
225
				.getAttribute(node, MacroConstants.OBJECT_ID_ATTRIBUTE);
226
		String rid = isObjectFound ? commandObject.getResolverId() : MacroUtil
227
				.getAttribute(node, MacroConstants.RESOLVER_ID_ATTRIBUTE);
228
229
		if (cid != null && wid != null) {
230
			PrimitiveUIObjectIdentifier objectIdentifier = null;
231
			if (wid == null) {
232
				objectIdentifier = new PrimitiveUIObjectIdentifier(
233
						MacroConstants.EMPTY_STRING, rid);
234
			} else {
235
				objectIdentifier = new PrimitiveUIObjectIdentifier(wid,
236
						obj, rid);
237
			}
238
			setMacroObjectIdentifier(new MacroObjectIdentifier(
239
					cid == null ? MacroConstants.EMPTY_STRING : cid,
240
					objectIdentifier));
241
		}
242
	}
243
244
	public void write(int indent, StringBuffer sb, boolean close, boolean end) {
245
		// let the super implementation write the element, we will just add our
246
		// attributes
247
		super.write(indent, sb, false, false);
248
249
		writeMacroObjectIdentifier(indent, sb, close, end);
250
	}
251
252
	protected void writeMacroObjectIdentifier(int indent, StringBuffer sb,
253
			boolean close, boolean end) {
254
		boolean noWidgetId = getMacroObjectIdentifier() == null;
255
		boolean objectMineInUse = useObjectMine();
256
		MacroUtil
257
				.addAttribute(
258
						sb,
259
						new String[] { MacroConstants.RESOLVER_ID_ATTRIBUTE,
260
								MacroConstants.CONTEXT_ID_ATTRIBUTE,
261
								MacroConstants.WIDGET_ID_ATTRIBUTE,
262
								MacroConstants.OBJECT_ID_ATTRIBUTE,
263
								MacroConstants.REFERENCE_ID_ATTRIBUTE },
264
						new String[] {
265
								objectMineInUse || noWidgetId ? null
266
										: getMacroObjectIdentifier()
267
												.getObjectIdentifier()
268
												.getResolverId(),
269
								objectMineInUse || noWidgetId ? null
270
										: getMacroObjectIdentifier()
271
												.getContextIdentifier(),
272
								objectMineInUse || noWidgetId ? null
273
										: getMacroObjectIdentifier()
274
												.getObjectIdentifier()
275
												.getWidgetId(),
276
								objectMineInUse || noWidgetId ? null
277
										: getMacroObjectIdentifier()
278
												.getObjectIdentifier()
279
												.getObjectId(),
280
								objectMineInUse ? getCorrespondingMacroObjectDescriptor()
281
										.getReferenceId()
282
										: null }, close, end);
283
	}
284
285
	protected boolean useObjectMine() {
286
		return MacroManager.getInstance().isObjectMineOn();
287
	}
288
289
	public boolean playback(Display display, Shell parent,
290
			IProgressMonitor monitor) throws CoreException {
291
		if (getMacroObjectIdentifier() != null) {
292
			macroObject = MacroObjectResolver.deresolve(parent,
293
						getMacroObjectIdentifier());
294
		}
295
		return doPlayback(display, parent, monitor);
296
	}
297
298
	public boolean doPlayback(Display display, Shell parent,
299
			IProgressMonitor monitor) throws CoreException{
300
		// nothing to do by default
301
		return false;
302
	}
303
304
	/**
305
	 * {@inheritDoc}
306
	 * 
307
	 * @see org.eclipse.tptp.test.auto.gui.internal.commands.AbstractMacroCommand#equals(java.lang.Object)
308
	 */
309
	public boolean equals(Object obj) {
310
		if (!super.equals(obj)) {
311
			return false;
312
		}
313
		if (!(obj instanceof ObjectBasedCommand)) {
314
			return false;
315
		}
316
		ObjectBasedCommand compareWithObj = (ObjectBasedCommand) obj;
317
		return compareWithObj.getMacroObjectIdentifier() != null
318
				&& compareWithObj.getMacroObjectIdentifier().equals(
319
						getMacroObjectIdentifier());
320
	}
321
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/deresolvingsupport/UIObjectDeprecatedDeresolvingSupport.java (+667 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport;
13
14
import java.util.Enumeration;
15
import java.util.Hashtable;
16
import java.util.Vector;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.jface.action.IContributionItem;
20
import org.eclipse.jface.action.ICoolBarManager;
21
import org.eclipse.jface.action.IToolBarManager;
22
import org.eclipse.jface.action.ToolBarContributionItem;
23
import org.eclipse.jface.action.ToolBarManager;
24
import org.eclipse.jface.wizard.IWizardPage;
25
import org.eclipse.jface.wizard.WizardDialog;
26
import org.eclipse.osgi.util.NLS;
27
import org.eclipse.swt.custom.CCombo;
28
import org.eclipse.swt.custom.CTabFolder;
29
import org.eclipse.swt.custom.CTabItem;
30
import org.eclipse.swt.widgets.Combo;
31
import org.eclipse.swt.widgets.Composite;
32
import org.eclipse.swt.widgets.Control;
33
import org.eclipse.swt.widgets.Item;
34
import org.eclipse.swt.widgets.Menu;
35
import org.eclipse.swt.widgets.MenuItem;
36
import org.eclipse.swt.widgets.Shell;
37
import org.eclipse.swt.widgets.TabFolder;
38
import org.eclipse.swt.widgets.TabItem;
39
import org.eclipse.swt.widgets.ToolBar;
40
import org.eclipse.swt.widgets.ToolItem;
41
import org.eclipse.swt.widgets.Widget;
42
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
43
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
44
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
45
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
46
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
47
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
48
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
49
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
50
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.DeresolvingAmbiguityException;
51
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate;
52
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate;
53
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateRegistry;
54
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader;
55
import org.eclipse.ui.IEditorPart;
56
import org.eclipse.ui.IViewPart;
57
58
/**
59
 * This class was merely introduced to be able to migrate the already existing
60
 * WidgetResolvers to the newly introduced IUIObjectResolverDelegate interface
61
 * while preserving the old implementation to deresolve UI objects (via the
62
 * foundWidget method). New IUIObjectResolverDelegates should not build on this
63
 * class and this class should possibly be removed by implementing proper
64
 * deresolving mechanisms in the existing IUIObjectResolverDelegate
65
 * implementations in the future.
66
 * 
67
 * @author Alexander Nyssen
68
 * 
69
 */
70
public class UIObjectDeprecatedDeresolvingSupport {
71
72
	/**
73
	 * Preserves the deprecated algorithm for widget resolving that was used
74
	 * before. Both, the AdaptiveUIObjectResolverDelegate as well as the
75
	 * NonTrivialUIObjectResolverDelegate refer to this implementation of
76
	 * deresolving. All newly introduced resolvers should not reside on this.
77
	 */
78
	public static IUIObject deresolve(Object context,
79
			IUIObjectIdentifier identifier) throws CoreException {
80
81
		IUIObject uiObject = null;
82
		String errorMessage = null;
83
		Throwable cause = null;
84
85
		try {
86
			if (context instanceof Menu) {
87
				// normal menus and popup menus (in the latter case we have to
88
				// ensure the menu is visible
89
				Menu menuBar = (Menu) context;
90
				MacroUtil.forceMenuOpen(menuBar);
91
				uiObject = locateMenuItem(menuBar, identifier);
92
				MacroUtil.forceMenuClosed(menuBar);
93
				if (uiObject == null) {
94
					errorMessage = NLS.bind(
95
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU,
96
							identifier.getWidgetId());
97
				}
98
			} else if (context instanceof ToolBar) {
99
				// deresolve tool item
100
				ToolBar toolbar = (ToolBar) context;
101
				uiObject = locateToolItem(toolbar, identifier);
102
				if (uiObject == null) {
103
					errorMessage = NLS.bind(
104
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR,
105
							identifier.getWidgetId());
106
				}
107
			} else if (context instanceof ToolBarManager
108
					|| context instanceof ICoolBarManager) {
109
				if (context instanceof ToolBarManager) {
110
					// Only ToolBarManager can be deresolved, not any
111
					// IToolBarManager implementation,
112
					// as the interface IToolBarManager interface does not allow
113
					// to obtain the control
114
					ToolBarManager toolBarManager = (ToolBarManager) context;
115
					uiObject = locateToolItem(toolBarManager, identifier);
116
				} else {
117
					ICoolBarManager coolBarManager = (ICoolBarManager) context;
118
					uiObject = locateToolItem(coolBarManager, identifier);
119
				}
120
				if (uiObject == null) {
121
					errorMessage = NLS.bind(
122
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL,
123
							identifier.getWidgetId());
124
				}
125
			} else if (context instanceof TabFolder
126
					|| context instanceof CTabFolder) {
127
				if (context instanceof TabFolder) {
128
					TabFolder tabFolder = (TabFolder) context;
129
					uiObject = locateTabItem(tabFolder, identifier);
130
				} else {
131
					CTabFolder tabFolder = (CTabFolder) context;
132
					uiObject = locateCTabItem(tabFolder, identifier);
133
				}
134
				if (uiObject == null) {
135
					errorMessage = NLS.bind(
136
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TAB,
137
							identifier.getWidgetId());
138
				}
139
			} else if (context instanceof WizardDialog) {
140
				WizardDialog wd = (WizardDialog) context;
141
142
				IWizardPage page = wd.getCurrentPage();
143
				Composite pparent = (Composite) page.getControl();
144
				uiObject = UIObjectDeprecatedDeresolvingSupport
145
						.locateVisibleChild(wd.getShell(), pparent, identifier);
146
147
				if (uiObject == null) {
148
					errorMessage = NLS.bind(
149
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD,
150
							identifier.getWidgetId());
151
				}
152
			} else if (context instanceof IWizardPage) {
153
				IWizardPage page = (IWizardPage) context;
154
155
				Composite pparent = (Composite) page.getControl();
156
				uiObject = UIObjectDeprecatedDeresolvingSupport
157
						.locateVisibleChild(pparent, null, identifier);
158
159
				if (uiObject == null) {
160
					errorMessage = NLS.bind(
161
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_WIZARD_CON,
162
							identifier.getWidgetId());
163
				}
164
			} else if (context instanceof IEditorPart) {
165
				IEditorPart editor = (IEditorPart) context;
166
167
				Composite c = MacroUtil.getWorkbenchPartControl(editor);
168
				uiObject = UIObjectDeprecatedDeresolvingSupport
169
						.locateVisibleChild(c, null, identifier);
170
171
				if (uiObject == null) {
172
					errorMessage = NLS.bind(
173
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_EDITOR_CON,
174
							identifier.getWidgetId());
175
				}
176
			} else if (context instanceof IViewPart) {
177
				IViewPart view = (IViewPart) context;
178
179
				Composite c = MacroUtil.getWorkbenchPartControl(view);
180
				uiObject = UIObjectDeprecatedDeresolvingSupport
181
						.locateVisibleChild((Composite) c, null, identifier);
182
183
				if (uiObject == null) {
184
					errorMessage = NLS.bind(
185
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_VIEW_CON,
186
							identifier.getWidgetId());
187
				}
188
			} else if (context instanceof Shell) {
189
				// locate a shell control
190
				Shell shell = (Shell) context;
191
192
				uiObject = UIObjectDeprecatedDeresolvingSupport
193
						.locateVisibleChild(shell, null, identifier);
194
195
				if (uiObject == null) {
196
					errorMessage = NLS.bind(
197
							AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL,
198
							identifier.getWidgetId());
199
				}
200
			}
201
202
		} catch (Throwable t) {
203
			t.printStackTrace();
204
			if (t.getCause() != null) {
205
				cause = t.getCause();
206
			} else {
207
				cause = t;
208
			}
209
			errorMessage = t.getMessage();
210
		}
211
212
		if (uiObject != null) {
213
			return uiObject;
214
		} else {
215
			AutoGUIUtil.throwCoreException(errorMessage, cause);
216
			return null;
217
		}
218
	}
219
220
	private static IUIObject locateCTabItem(CTabFolder tabFolder,
221
			IUIObjectIdentifier identifier) {
222
		CTabItem tabItem = null;
223
		for (int i = 0; i < tabFolder.getItemCount() && tabItem == null; i++) {
224
			CTabItem currentItem = tabFolder.getItem(i);
225
			String validatedCurrentItemText = NonTrivialUIObjectResolverDelegate
226
					.validateText(currentItem.getText());
227
			if (validatedCurrentItemText != null
228
					&& validatedCurrentItemText
229
							.equals(identifier.getWidgetId())) {
230
				tabItem = currentItem;
231
			}
232
		}
233
		return new UIObject(tabItem);
234
	}
235
236
	private static IUIObject locateTabItem(TabFolder tabFolder,
237
			IUIObjectIdentifier identifier) {
238
		TabItem tabItem = null;
239
		for (int i = 0; i < tabFolder.getItemCount() && tabItem == null; i++) {
240
			TabItem currentItem = tabFolder.getItem(i);
241
			String validatedCurrentItemText = NonTrivialUIObjectResolverDelegate
242
					.validateText(currentItem.getText());
243
			if (validatedCurrentItemText != null
244
					&& validatedCurrentItemText
245
							.equals(identifier.getWidgetId())) {
246
				tabItem = currentItem;
247
			}
248
		}
249
		return new UIObject(tabItem);
250
	}
251
252
	/**
253
	 * @deprecated This method should only be used internally Returns true iff
254
	 *             the widget matches the id passed in.
255
	 * 
256
	 * @param widget
257
	 *            The widget
258
	 * @param objectId
259
	 *            The resolver id -- can be null
260
	 * @return true iff the widget matches the id passed in.
261
	 */
262
	public static boolean foundWidget(Widget widget,
263
			IUIObjectIdentifier widgetId) {
264
		Hashtable widgetResolvers = UIObjectResolverDelegateRegistry
265
				.getDelegateResolverLoaders();
266
267
		if (widgetId != null && widgetId.getResolverId() != null) {
268
			UIObjectResolverDelegateLoader loader = (UIObjectResolverDelegateLoader) widgetResolvers
269
					.get(widgetId.getResolverId());
270
			if (loader != null
271
					&& loader.getUIObjectResolverDelegate() instanceof IUIObjectDeprecatedDeresolvingFacade)
272
				return ((IUIObjectDeprecatedDeresolvingFacade) loader
273
						.getUIObjectResolverDelegate()).foundWidget(widget,
274
						widgetId);
275
			return false;
276
		}
277
278
		Enumeration keys = widgetResolvers.keys();
279
		while (keys.hasMoreElements()) {
280
			IUIObjectResolverDelegate delegateResolver = ((UIObjectResolverDelegateLoader) widgetResolvers
281
					.get(keys.nextElement())).getUIObjectResolverDelegate();
282
			if (delegateResolver instanceof IUIObjectDeprecatedDeresolvingFacade) {
283
				if (((IUIObjectDeprecatedDeresolvingFacade) delegateResolver)
284
						.foundWidget(widget, widgetId)) {
285
					return true;
286
				}
287
			}
288
		}
289
		return false;
290
	}
291
292
	/**
293
	 * @deprecated This method should only be used internally. Returns true if
294
	 *             the id computed for 'item' matches 'id'
295
	 * 
296
	 * @param item
297
	 *            The tool item
298
	 * @param resolverId
299
	 *            The resolver id -- can be null
300
	 * @param id
301
	 *            The id that should be matched against
302
	 * @return true if there is a match, and false otherwise
303
	 */
304
	public static boolean foundItem(Item item, IUIObjectIdentifier objectId) {
305
		/* Try the widget resolvers first */
306
		if (foundWidget(item, objectId))
307
			return true;
308
309
		/* Give the old policy a try */
310
		String toolItemIdStr = NonTrivialUIObjectResolverDelegate.getActionId(
311
				item).toString();
312
		if (toolItemIdStr != null
313
				&& toolItemIdStr.equals(objectId.getWidgetId()))
314
			return true;
315
316
		return false;
317
	}
318
319
	public static Control recursiveSearch(Composite parent, Composite skip,
320
			Control desiredControl, IUIObjectIdentifier id,
321
			String widgetClassName, int[] index, Vector matches, Vector indices) {
322
		boolean searchForControl = id == null;
323
		Control[] children = parent.getChildren();
324
		boolean[] checkTypeAndEquality;
325
		Control searchResult;
326
		// boolean isTabFolder, isCTabFolder;
327
328
		for (int i = 0; i < children.length; i++) {
329
			Control child = children[i];
330
331
			if (!child.isVisible()) {
332
				/*
333
				 * If the control is of the same type, then we'll need to
334
				 * increment the index
335
				 */
336
				if ((widgetClassName != null && child.getClass().getName()
337
						.equals(widgetClassName))
338
						|| (desiredControl != null && desiredControl.getClass()
339
								.getName().equals(child.getClass().getName())))
340
					index[0]++;
341
342
				continue;
343
			}
344
345
			checkTypeAndEquality = searchForControl ? checkTypeAndEqual(
346
					desiredControl, child, index) : checkTypeAndId(child, id,
347
					widgetClassName, index);
348
			if (checkTypeAndEquality[0]) {
349
				if (checkTypeAndEquality[1]) {
350
					addMatch(matches, indices, child, index[0]);
351
				}
352
353
				// ANy: This code is now obsolete, as we have a new deresolving
354
				// policy for
355
				// TabItems and CTabItems (own context info) and the respective
356
				// choice command
357
				// converts existing macro entries to the new format.
358
				// /* Defect 111371 -- We need to step through the items of a
359
				// tab */
360
				// isTabFolder = child instanceof TabFolder;
361
				// isCTabFolder = child instanceof CTabFolder;
362
				// if (isTabFolder || isCTabFolder) {
363
				// Object[] tabItems = isTabFolder ? (Object[]) ((TabFolder)
364
				// child)
365
				// .getItems()
366
				// : ((CTabFolder) child).getItems();
367
				// if (tabItems != null) {
368
				// for (int j = 0; j < tabItems.length; j++) {
369
				// Control tabItemControl = isTabFolder ? ((TabItem)
370
				// tabItems[j])
371
				// .getControl()
372
				// : ((CTabItem) tabItems[j]).getControl();
373
				//
374
				// if (tabItemControl == null)
375
				// continue;
376
				//
377
				// checkTypeAndEquality = searchForControl ? checkTypeAndEqual(
378
				// tabItemControl, desiredControl, index)
379
				// : checkTypeAndId(tabItemControl, id,
380
				// widgetClassName, index);
381
				// if (checkTypeAndEquality[0]
382
				// && checkTypeAndEquality[1]) {
383
				// addMatch(matches, indices, tabItemControl,
384
				// index[0]);
385
				// }
386
				// if ((searchResult = recursiveSearch(tabItemControl,
387
				// skip, desiredControl, id, widgetClassName,
388
				// index, matches, indices)) != null) {
389
				// addMatch(matches, indices, searchResult,
390
				// index[0]);
391
				// }
392
				// }
393
				// }
394
				// }
395
				//
396
			}
397
398
			if ((searchResult = recursiveSearch(child, skip, desiredControl,
399
					id, widgetClassName, index, matches, indices)) != null) {
400
				addMatch(matches, indices, searchResult, index[0]);
401
			}
402
		}
403
404
		if (matches.size() > 0) {
405
			return (Control) matches.get(0);
406
		} else {
407
			return null;
408
		}
409
	}
410
411
	/**
412
	 * A helper method used to indicate whether expected is of the same type as
413
	 * actual. The return value also indicates if expected == actual.
414
	 * 
415
	 * @param expected
416
	 *            The expected control
417
	 * @param actual
418
	 *            The actual control that 'expected' is checked against
419
	 * @param counter
420
	 *            A counter that is used for indexing.
421
	 * 
422
	 * @return This method has the side affect of incrementing counter if the
423
	 *         class types of the two controls are the same. The return value
424
	 *         indicates type and whether expected == actual.
425
	 */
426
	private static boolean[] checkTypeAndEqual(Control expected,
427
			Control actual, int[] counter) {
428
		boolean[] typeAndEqualCheck = new boolean[2];
429
		if (expected.getClass().equals(actual.getClass())) {
430
			typeAndEqualCheck[0] = true;
431
432
			// same type - increment counter
433
			counter[0]++;
434
			if (expected.equals(actual)) {
435
				// bingo
436
				typeAndEqualCheck[1] = true;
437
			}
438
		}
439
440
		return typeAndEqualCheck;
441
	}
442
443
	private static Control recursiveSearch(Control currentSearchPoint,
444
			Composite skip, Control desiredControl,
445
			IUIObjectIdentifier desiredId, String desiredWidgetClassName,
446
			int[] index, Vector matches, Vector indices) {
447
		Control searchResult = null;
448
		if (currentSearchPoint instanceof Composite
449
				&& !(skip != null && currentSearchPoint.equals(skip))
450
				&& currentSearchPoint.isVisible()) {
451
			searchResult = recursiveSearch((Composite) currentSearchPoint,
452
					skip, desiredControl, desiredId, desiredWidgetClassName,
453
					index, matches, indices);
454
		}
455
456
		return searchResult;
457
	}
458
459
	private static void addMatch(Vector container, Vector indices, Object item,
460
			int index) {
461
		if (!container.contains(item)) {
462
			container.add(item);
463
			indices.add(new Integer(index));
464
		}
465
	}
466
467
	private static boolean[] checkTypeAndId(Control presentControl,
468
			IUIObjectIdentifier desiredId, String desiredWidgetClassName,
469
			int[] counter) {
470
		boolean[] checkTypeAndEqualId = new boolean[2];
471
472
		if (desiredWidgetClassName == null
473
				|| presentControl.getClass().getName().equals(
474
						desiredWidgetClassName)) {
475
			// same type - increment counter
476
			if (!presentControl.isVisible())
477
				return checkTypeAndEqualId;
478
479
			checkTypeAndEqualId[0] = true;
480
			counter[0]++;
481
			if (foundWidget(presentControl, desiredId)
482
					|| NonTrivialUIObjectResolverDelegate
483
							.computeDefaultControlId(presentControl, counter[0])
484
							.equals(desiredId.getWidgetId())) {
485
				checkTypeAndEqualId[1] = true;
486
			}
487
		}
488
489
		return checkTypeAndEqualId;
490
	}
491
492
	private static UIObject locateVisibleChild(Composite parent,
493
			Composite skip, IUIObjectIdentifier uiObjectIdentifier)
494
			throws CoreException {
495
		int[] counter = new int[1];
496
		counter[0] = 0;
497
498
		// see if an uniqueness identifier was added by the UIObjectResolver
499
		// because the identifier
500
		// that was computed is not unique (workaround for defect #147766)
501
		String widgetIdentifier = uiObjectIdentifier.getWidgetId();
502
		IUIObjectIdentifier adjustedUIObjectIdentifier = uiObjectIdentifier;
503
		int matchIndex = -1;
504
		if (widgetIdentifier
505
				.indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR) > 0) {
506
			adjustedUIObjectIdentifier = new PrimitiveUIObjectIdentifier(
507
					widgetIdentifier
508
							.substring(
509
									0,
510
									widgetIdentifier
511
											.indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR)),
512
					uiObjectIdentifier.getObjectId(), uiObjectIdentifier
513
							.getResolverId());
514
			matchIndex = new Integer(
515
					widgetIdentifier
516
							.substring(widgetIdentifier
517
									.indexOf(MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR) + 3))
518
					.intValue();
519
		}
520
521
		int sloc = widgetIdentifier.indexOf('#');
522
		String wclassName = null;
523
		if (sloc != -1)
524
			wclassName = widgetIdentifier.substring(0, sloc);
525
526
		/*
527
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=147766: We need to
528
		 * return all possible matches -> ANy: this does not seem to be an
529
		 * adequate solution. It seems as if the resolving mechanism should
530
		 * compute a more appropriate identifier in such a case. We will
531
		 * therefore not tolerate such an anambiguity.
532
		 */
533
		Vector matches = new Vector();
534
		Vector indices = new Vector();
535
		// do not use the extended widget identifier but only the prefix to find
536
		// the widget
537
		locateVisibleChild(parent, skip, adjustedUIObjectIdentifier,
538
				wclassName, counter, matches, indices);
539
540
		// see if we have properly deresolved a control
541
		Control control = null;
542
		if (matches.size() > 0) {
543
			if (matches.size() > 1) {
544
				if (matchIndex != -1) {
545
					control = (Control) matches.get(matchIndex);
546
				} else {
547
					// we have found several matches and no uniqueness
548
					// identifier was added,
549
					// so we cannt unambiguously identify which one was
550
					// selected.
551
					AutoGUIUtil
552
							.throwCoreException(
553
									NLS
554
											.bind(
555
													AutoGUIMessages.AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS,
556
													uiObjectIdentifier
557
															.getWidgetId(),
558
													uiObjectIdentifier
559
															.getObjectId()),
560
									new DeresolvingAmbiguityException(matches
561
											.size()));
562
					return null;
563
				}
564
			} else {
565
				control = (Control) matches.get(0);
566
			}
567
		}
568
569
		// we have located a control, see if we have to further deresolve a
570
		// nested object
571
		if (control != null) {
572
			// added by ANy to resolve beyond the widget level for combo and
573
			// ccombo controls (needed in choice command)
574
			if (adjustedUIObjectIdentifier.getObjectId() != null) {
575
				// find object located at the sub widget level
576
				if (control instanceof Combo || control instanceof CCombo) {
577
					String indexString = adjustedUIObjectIdentifier
578
							.getObjectId().substring(
579
									new String("item#").length());
580
					int index = new Integer(indexString).intValue();
581
					// find the item at the specified index
582
					if (control instanceof Combo) {
583
						String[] items = ((Combo) control).getItems();
584
						return new UIObject(control, items[index]);
585
					} else if (control instanceof CCombo) {
586
						String[] items = ((CCombo) control).getItems();
587
						return new UIObject(control, items[index]);
588
					}
589
					return null;
590
				} else {
591
					// anything else is ignored up to now
592
					return new UIObject(control);
593
				}
594
			} else {
595
				return new UIObject(control);
596
			}
597
		} else {
598
			return null;
599
		}
600
	}
601
602
	private static Control locateVisibleChild(Composite parent, Composite skip,
603
			IUIObjectIdentifier id, String wclassName, int[] index,
604
			Vector matches, Vector indices) {
605
		return recursiveSearch(parent, skip, null, id, wclassName, index,
606
				matches, indices);
607
	}
608
609
	private static IUIObject locateToolItem(ICoolBarManager coolMng,
610
			IUIObjectIdentifier wid) {
611
		IContributionItem[] items = coolMng.getItems();
612
		for (int i = 0; i < items.length; i++) {
613
			if (items[i] instanceof ToolBarContributionItem) {
614
				ToolBarContributionItem item = (ToolBarContributionItem) items[i];
615
				IToolBarManager toolMng = item.getToolBarManager();
616
				IUIObject target = locateToolItem((ToolBarManager) toolMng, wid);
617
				if (target != null)
618
					return target;
619
			}
620
		}
621
		return null;
622
	}
623
624
	private static IUIObject locateToolItem(ToolBarManager toolMng,
625
			IUIObjectIdentifier wid) {
626
		return locateToolItem(toolMng.getControl(), wid);
627
	}
628
629
	private static UIObject locateMenuItem(Menu menu,
630
			IUIObjectIdentifier widgetId) {
631
		MenuItem[] items = menu.getItems();
632
633
		for (int i = 0; i < items.length; i++) {
634
			MenuItem item = items[i];
635
636
			Menu submenu = item.getMenu();
637
			if (submenu != null) {
638
				/*
639
				 * Ali M.: We have to force the menu to open, since its items
640
				 * may not have already been created
641
				 */
642
				MacroUtil.forceMenuOpen(submenu);
643
				UIObject hit = locateMenuItem(submenu, widgetId);
644
				if (hit != null)
645
					return hit;
646
			} else {
647
				if (UIObjectDeprecatedDeresolvingSupport.foundItem(item,
648
						widgetId))
649
					return new UIObject(item);
650
			}
651
		}
652
		return null;
653
	}
654
655
	private static IUIObject locateToolItem(ToolBar toolBar,
656
			IUIObjectIdentifier wid) {
657
		if (toolBar == null)
658
			return null;
659
		ToolItem[] items = toolBar.getItems();
660
		for (int i = 0; i < items.length; i++) {
661
			ToolItem item = items[i];
662
			if (UIObjectDeprecatedDeresolvingSupport.foundItem(item, wid))
663
				return new UIObject(item);
664
		}
665
		return null;
666
	}
667
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/WeightedPropertyUIObjectIdentifier.java (+211 lines)
Added Link Here
1
/********************************************************************** 
2
 * Copyright (c) 2005, 2006 IBM Corporation and others. 
3
 * All rights reserved.   This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0 
5
 * which accompanies this distribution, and is available at 
6
 * http://www.eclipse.org/legal/epl-v10.html         
7
 * $Id: WeightedPropertyUIObjectIdentifier.java,v 1.3 2006/12/04 02:55:08 amehregani Exp $ 
8
 * 
9
 * Contributors: 
10
 * IBM - Initial API and implementation 
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject;
13
14
import java.util.regex.Matcher;
15
import java.util.regex.Pattern;
16
17
import org.eclipse.hyades.test.common.util.XMLUtil;
18
19
/**
20
 * 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
21
 * threshold, then the widget is identified as a match
22
 * 
23
 * @author Ali Mehregani
24
 */
25
public class WeightedPropertyUIObjectIdentifier implements IUIObjectIdentifier {
26
27
	private WeightedPropertyUIObjectIdentifier() {
28
	}
29
30
	public WeightedPropertyUIObjectIdentifier(Object[] propertyWeightPair, float threshold, String resolverId) {
31
		this.propertyWeightPair = propertyWeightPair;
32
		this.threshold = threshold;
33
		this.resolverId = resolverId;
34
	}
35
36
	private String resolverId;
37
38
	/*
39
	 * 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
40
	 * value is the weight associated with that property.
41
	 */
42
	private Object[] propertyWeightPair;
43
	private float threshold;
44
45
	private final static Pattern pairPattern = Pattern.compile(".*?\\{\\{([^\\}]+)\\}\\}-\\{\\{([^\\}]+)\\}\\}.*");
46
47
	public boolean equals(Object obj) {
48
		String stringToCompare = null;
49
		boolean compare = false;
50
51
		/* The object is of our own kind */
52
		if (obj instanceof WeightedPropertyUIObjectIdentifier) {
53
			WeightedPropertyUIObjectIdentifier idToCompareWith = (WeightedPropertyUIObjectIdentifier) obj;
54
55
			if (this == idToCompareWith)
56
				return true;
57
58
			compare = true;
59
			stringToCompare = idToCompareWith.toString();
60
		}
61
62
		/* The object is a string (most likely coming from a macro) */
63
		else if (obj instanceof String) {
64
			compare = true;
65
			stringToCompare = (String) obj;
66
		}
67
		// ANy: equals has to be done on strings only, as a weigthed property id becomes a primitive one after loading (during playback)
68
		else if( obj instanceof IUIObjectIdentifier){
69
			compare = true;
70
			stringToCompare = ((IUIObjectIdentifier)obj).getWidgetId();
71
		}
72
73
		if (!compare)
74
			return false;
75
76
		/*
77
		 * Use regular expression to distinguish the returned value of each method from the weight
78
		 */
79
		float accumMatchRate = 0;
80
		int loopIterationNo = -1;
81
82
		while (stringToCompare.length() > 0 && (loopIterationNo + 1) < propertyWeightPair.length) {
83
			loopIterationNo++;
84
			Matcher pairTokenMatcher = pairPattern.matcher(stringToCompare);
85
86
			/* Discontinue if there is no match */
87
			if (!pairTokenMatcher.matches() || pairTokenMatcher.groupCount() != 2)
88
				break;
89
90
			/* Otherwise walk through each token */
91
			String originalProperty = pairTokenMatcher.group(1);
92
			String prop = originalProperty;
93
			if (prop.length() > 0)
94
				prop = XMLUtil.removeXMLSymbols(prop);
95
			float weight = Float.parseFloat(pairTokenMatcher.group(2));
96
97
			/* The ordering of the tokens for the IDs being compared must be the same. */
98
			Object[] propertyWeightPair = (Object[]) this.propertyWeightPair[loopIterationNo];
99
			if (!prop.equals("null") && (prop.length() > 0
100
				? prop.charAt(0) == ((String) propertyWeightPair[0]).charAt(0) || prop.charAt(0) == '&'
101
				: true) && (prop.equals(propertyWeightPair[0]) || prop.replaceAll("\\&",
102
				"").equals(propertyWeightPair[0]) || prop.replace('/',
103
				'\\').equals(propertyWeightPair[0])))
104
				accumMatchRate += Float.parseFloat((String) propertyWeightPair[1]);
105
106
			String currentToken = "{{" + originalProperty + "}}-{{" + weight + "}}";
107
			if (currentToken.equals(stringToCompare))
108
				break;
109
110
			int inx = stringToCompare.indexOf(currentToken);
111
			if (inx != -1)
112
				stringToCompare = stringToCompare.substring(inx + currentToken.length(),
113
					stringToCompare.length());
114
115
			else
116
				break; /* The control flow should never reach this block */
117
118
		}
119
120
		if (accumMatchRate >= threshold)
121
			return true;
122
		return false;
123
	}
124
125
	/**
126
	 * Return a string representation of this identifier. The property, weight information is organized in this format:
127
	 * {{property-value1}}-{{weight1}}{{property-value2}}:{{weight2}}
128
	 */
129
	public String getWidgetId() {
130
		String retValue = "";
131
		for (int i = 0; i < this.propertyWeightPair.length; i++)
132
			retValue += "{{" + ((Object[]) this.propertyWeightPair[i])[0] + "}}-{{" + ((Object[]) this.propertyWeightPair[i])[1] + "}}";
133
134
		return XMLUtil.useXMLSymbols(retValue);
135
	}
136
137
	public String toString() {
138
		return getWidgetId();
139
	}
140
141
	public float getThreshold() {
142
		return threshold;
143
	}
144
145
	// public void setThreshold(float threshold) {
146
	// this.threshold = threshold;
147
	// }
148
149
	public Object[] getPropertyWeightPair() {
150
		return propertyWeightPair;
151
	}
152
153
	// public void setPropertyWeightPair(Object[] propertyWeightPair) {
154
	// this.propertyWeightPair = propertyWeightPair;
155
	// }
156
157
	/**
158
	 * Walk through the properties and return true for as long as one of them is not null.
159
	 * 
160
	 * @return true if at least one property is not null; false otherwise
161
	 */
162
	public boolean noValidProperties() {
163
		if (propertyWeightPair == null)
164
			return true;
165
166
		for (int i = 0; i < propertyWeightPair.length; i++) {
167
			String property = (String) ((Object[]) propertyWeightPair[i])[0];
168
			if (property != null && !property.equals("null"))
169
				return false;
170
		}
171
		return true;
172
	}
173
174
	/**
175
	 * Convenient method available for clients to use in order to construct a weighted property id
176
	 * 
177
	 * @param properties
178
	 *            The (properties, weight) pairs of the item (weights should be a value between (0, 1])
179
	 * @param threshold
180
	 *            The threshold that this property should meet (should be a value between (0-1])
181
	 * @return Returns an instance of this class with the appropriate fields set.
182
	 */
183
	public static WeightedPropertyUIObjectIdentifier constructId(Object[] properties, float threshold, String resolverId) {
184
		/* Step through the properties and replace null values with the literal string null */
185
		for (int i = 0; i < properties.length; i++) {
186
			String property = (String) ((Object[]) properties[i])[0];
187
			if (property == null || property.length() <= 0)
188
				((Object[]) properties[i])[0] = "null";
189
190
		}
191
192
		WeightedPropertyUIObjectIdentifier widgetId = new WeightedPropertyUIObjectIdentifier(properties, threshold, resolverId);
193
194
		if (widgetId.noValidProperties())
195
			return null;
196
		return widgetId;
197
	}
198
199
	public String getResolverId() {
200
		return resolverId;
201
	}
202
	
203
	public String getObjectId(){
204
		// nested objects not supported by this resolver
205
		return null;
206
	}
207
208
	// public void setResolverId(String resolverId) {
209
	// this.resolverId = resolverId;
210
	// }
211
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObject.java (+216 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macroobject;
13
14
import org.eclipse.jface.action.ContributionManager;
15
import org.eclipse.jface.action.IMenuManager;
16
import org.eclipse.jface.action.MenuManager;
17
import org.eclipse.jface.wizard.IWizardPage;
18
import org.eclipse.jface.wizard.WizardDialog;
19
import org.eclipse.swt.custom.CTabItem;
20
import org.eclipse.swt.widgets.Button;
21
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.swt.widgets.Decorations;
23
import org.eclipse.swt.widgets.Menu;
24
import org.eclipse.swt.widgets.MenuItem;
25
import org.eclipse.swt.widgets.Shell;
26
import org.eclipse.swt.widgets.TabItem;
27
import org.eclipse.swt.widgets.ToolItem;
28
import org.eclipse.swt.widgets.Widget;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
30
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
31
import org.eclipse.ui.IEditorPart;
32
import org.eclipse.ui.IViewPart;
33
import org.eclipse.ui.IWorkbenchPage;
34
import org.eclipse.ui.IWorkbenchPart;
35
import org.eclipse.ui.IWorkbenchWindow;
36
37
/**
38
 * 
39
 * @author Alexander Nyssen
40
 * 
41
 */
42
public class MacroObject implements IMacroObject {
43
44
	private Object context;
45
	private IUIObject uiObject;
46
47
	/**
48
	 * Constructor is used by MacroObjectResolver to instantiate a new
49
	 * MacroObject during deresolving of an IMacroObjectIdentifier
50
	 * 
51
	 * @param context
52
	 * @param uiObject
53
	 */
54
	public MacroObject(Object context, IUIObject uiObject) {
55
		this.uiObject = uiObject;
56
		this.context = context;
57
	}
58
59
	/**
60
	 * Constructor is used by clients when constructing a new MacroObject to
61
	 * pass it to the MacroObjectResolver to retrieve an IMacroObjectIdentifier.
62
	 * The context of the MacroObject is automatically detected based on the
63
	 * IUIObject passed in.
64
	 * 
65
	 * 
66
	 * @param uiObject
67
	 */
68
	public MacroObject(IUIObject uiObject) {
69
		this.uiObject = uiObject;
70
		this.context = retrieveContext(uiObject);
71
	}
72
73
	private Object retrieveContext(IUIObject uiObject) {
74
		Widget widget = uiObject.getWidget();
75
		if (widget instanceof MenuItem) {
76
			MenuItem menuItem = (MenuItem) widget;
77
			IViewPart view = null;
78
			if (MacroUtil.onMenubar(menuItem)) {
79
				// return the menu containing the item
80
				return menuItem.getParent().getShell().getMenuBar();
81
			} else if ((view = MacroUtil.onWorkbenchPartToolbar(menuItem)) != null) {
82
				// return the menu located on the action bar of the view
83
				// Note: formerly, the ToolBarManager was returned here,
84
				// however, this
85
				// was never used during resolving -> instead the MenuManager of
86
				// the action bar was used to find the menu.
87
				IMenuManager menuManager = view.getViewSite().getActionBars()
88
						.getMenuManager();
89
				if (menuManager != null && menuManager instanceof MenuManager) {
90
					Menu menu = ((MenuManager) menuManager).getMenu();
91
					if (menu == null) {
92
						// try to create menu
93
						((MenuManager) menuManager)
94
								.createMenuBar((Decorations) view.getSite()
95
										.getShell());
96
					}
97
					return menu;
98
				} else {
99
					return null;
100
				}
101
			} else {
102
				// popup menu item
103
				return widget.getDisplay().getFocusControl();
104
			}
105
		} else if (widget instanceof ToolItem) {
106
			ToolItem toolItem = (ToolItem) widget;
107
			ContributionManager contributionManager = null;
108
			if ((contributionManager = MacroUtil.onToolbar(toolItem)) != null) {
109
				// global toolbar
110
				return contributionManager;
111
			} else {
112
				// local toolbar
113
				return toolItem.getParent();
114
			}
115
		} else if (widget instanceof TabItem) {
116
			// ANy: Added to allow proper resolving of TabItems
117
			return ((TabItem) widget).getParent();
118
		} else if (widget instanceof CTabItem) {
119
			// ANy: Added to allow proper resolving of CTabItems
120
			return ((CTabItem) widget).getParent();
121
		}
122
		// else if (widget instanceof Shell) {
123
		// return ((Shell)widget).getData();
124
		// }
125
		else if (widget instanceof Control) {
126
			return retrieveControlContext(uiObject);
127
		}
128
		// ANy: it seems that Menus are actually never used as macro objects,
129
		// as the deresolver only has capability to deresolve menu items and not
130
		// menus,
131
		// so we will ignore this case here as well (the MacroObjectResolver
132
		// throws a CoreException if called with a MacroObject denoting a menu)
133
134
		// else if (widget instanceof Menu) {
135
		// return null;
136
		// }
137
		return null;
138
	}
139
140
	/**
141
	 * @param uiObject
142
	 */
143
	private Object retrieveControlContext(IUIObject uiObject) {
144
		if (uiObject.getWidget() instanceof Control) {
145
			Control control = (Control) uiObject.getWidget();
146
			Shell shell = control.getShell();
147
			Object data = shell.getData();
148
			if (data instanceof WizardDialog) {
149
				// in wizard
150
				WizardDialog wd = (WizardDialog) data;
151
				IWizardPage page = wd.getCurrentPage();
152
				if (page == null)
153
					return null;
154
				// check for wizard buttons
155
				if (control instanceof Button
156
						&& MacroUtil.onWizardDialog(wd, (Button) control)) {
157
					return wd;
158
				}
159
				// wizard page related
160
				else {
161
					return page;
162
				}
163
			} else if (data instanceof IWorkbenchWindow) {
164
				IWorkbenchWindow window = (IWorkbenchWindow) data;
165
				IWorkbenchPage page = window.getActivePage();
166
167
				/**
168
				 * Ali M.: Under some situations, the part that is returned by
169
				 * the 'getActivePart' method is the old active part. Although
170
				 * the control object is coming from the newly active part, the
171
				 * part that is retrieved below will be from the old active
172
				 * part. This will cause MacroUtil.getControlIdentifier to
173
				 * return null when attempting to retrieve the widget id in the
174
				 * wrong context. One situation that this fails under is when: -
175
				 * Macro recorder start while the test suite editor is active -
176
				 * A hook is inserted - The package view is focused (not
177
				 * activated and focused but just focused)
178
				 * 
179
				 * To resolve this issue, I have registered a part listener when
180
				 * the client starts recording. When there is a new active part
181
				 * detected, an event is created and fired to the usual onEvent
182
				 * handler in MacroManager. See MacroManager.hookPartListener.
183
				 */
184
				IWorkbenchPart part = page.getActivePart();
185
				if (part instanceof IViewPart || part instanceof IEditorPart) {
186
					return part;
187
				} else {
188
					return null;
189
				}
190
			} else {
191
				// an arbitrary control on a shell
192
				return shell;
193
			}
194
		}
195
		return null;
196
	}
197
198
	/**
199
	 * {@inheritDoc}
200
	 * 
201
	 * @see org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject#getUIObject()
202
	 */
203
	public IUIObject getUIObject() {
204
		return uiObject;
205
	}
206
207
	/**
208
	 * {@inheritDoc}
209
	 * 
210
	 * @see org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject#getContext()
211
	 */
212
	public Object getContext() {
213
		return context;
214
	}
215
216
}
(-)CHANGES.txt (+59 lines)
Added Link Here
1
1) Total refactoring of the widget resolving mechanism:
2
   	   	
3
   - 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.
4
   	 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 
5
   	 resolved into a IUIObjectIdentifier (by a newly introduced UIObjectResolver), which contains the info formerly captured in a WidgetIdentifier (widgetId, resolverId, optional objectId). 
6
   	 During playback the deresolving of IMacroObjectIdentifiers is done in the same two step process. The MacroObjectResolver locates (deresolves) the context, and the UIObjectResolver
7
   	 than locates the UIObject (under the given context). He delegates the resolving/deresolving of UIObjects/UIObjectIdentifiers to so called IUIObjectResolverDelegates, which are 
8
   	 loaded via a newly introduced extension point (which is a replacement of the former WigetResolver extension point).
9
   	
10
   - Different to the old WidgetResolvers, the newly introduced IUIObjectResolverDelegates are responsible not only to resolve a respective IUIObjectIdentifier
11
     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
12
     WidgetResolvers were migrated to the new IUIObjectResolverDelegate interface. A DeprecatedDeresolvingSupport class was introduced to preserve the old implementation that
13
     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
14
     UIObjectResolverDelegate interface by using DeprecatedDeresolvingSupport
15
     
16
   - 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. 
17
     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
18
     (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 
19
     implementation would select the respectively named item in the BinaryBuild-Tree, as it plays the command for the first match. 
20
     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 
21
     can be identified unambiguously. 
22
     
23
   - All commands that relied on resolving/deresolving widgets (and nested objects) where migrated to have a common superclass ObjectBasedCommand. All those object-based commands
24
   	 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 
25
   	 a widget (e.g. a String item on a ComboBox). 
26
     
27
   - 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
28
     is now side-effect free.
29
     
30
2) Refactored ObjectMining. Renamed UIObject to MacroObjectDescriptor and ObjectMine into MacroObjectMine, UIObjectMineManager into MacroObjectManager to reflect what is actually stored in it. 
31
   - Refactored the identifier providing mechanism; a new MacroObjectDescriptor is now equipped with a unique id internally by the object mine when registering the object
32
   - 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.
33
34
4) Refactored VerficationCommand to be handled as all other object-based commands 
35
   - moved static construction method out changed constructor signature of Verification command to be in line with other object-based commands
36
   - refactored loading/writing to rely on super implemenation where possible
37
   - Removed VerficationMetaData which is now not needed any more (as in case of other commands that do not have something like this as well)
38
   - 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
39
   	 mode, verification does not rely on the context but also on a selected UIObject (i.e. widget and possibly nested object). 
40
   	 
41
5) Introduced a command factory that encapsulates creation of commands (factored respective code out of MacroCommandShell). Introduced a respective extension point
42
   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,
43
   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).
44
45
6) Refactored MacroManager
46
   - moved event constants into EventConstants interface, which defines the custom event types and details
47
   - moved mode constants into own ModeConstants interface
48
49
7) Removed unneeded IRecorderListener interface (never used)
50
 
51
8) Fixed that in Eclispe Ganymede, when closing an unsaved editor, the workbench close command was created after the message dialog selection command.
52
53
9) Introduced mouse move commands to explitly capture mouse move events, as needed to test GEF-applications.
54
55
10) Several minor fixes and cleanups.
56
57
TODO:
58
 - Migrate BooleanSelectionCommand and AbstractStructuredCommand to fully use the new resolving/deresolving mechanisms for macro objects (they are still based on parts
59
   of the old resolving mechanism, respectively do resolving/deresolving on their own), which should be taken care of.
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/ModeConstants.java (+28 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macro;
13
14
15
/**
16
 * @author Alexander Nyssen
17
 */
18
public interface ModeConstants {
19
20
	/* Global states */
21
	public static final byte RECORDING_MODE = 0x00; /* Recording mode */
22
	public static final byte VERIFICATION_MODE = 0x01; /* Verification mode */
23
	public static final byte SUSPEND_MODE = 0x02; /* Suspend mode */
24
	public static final byte QUICK_RUN_MODE = 0x03; /* Quick run mode (when current workbench is used as the context) */
25
	public static final byte EXECUTION_RUN_MODE = 0x04; /* Execution run mode (when proper launch configuration is used) */
26
	public static final byte IDLE_MODE = 0x05; /* Idle mode */
27
	public static final byte POSITION_BASED_REC_MODE = 0x06; /* Position based recording */
28
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/MacroCommandFactoryLoader.java (+72 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.commands.factory;
13
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.core.runtime.IConfigurationElement;
16
import org.eclipse.core.runtime.Platform;
17
18
/**
19
 * Helper class to load a IMacroCommandFactory via the respective extension
20
 * point. Only the factory with the highest priority is used. All other
21
 * factories are disregarded.
22
 * 
23
 * @author Alexander Nyssen
24
 * 
25
 */
26
public class MacroCommandFactoryLoader {
27
28
	private static final String EXTENSION_POINT_NAME = "macroCommandFactory";
29
	private static final String EXTENSION_POINT_ID = "org.eclipse.tptp.test.auto.gui."
30
			+ EXTENSION_POINT_NAME;
31
32
	private static IMacroCommandFactory factory = null;
33
34
	/**
35
	 * Retrieves the factory with the highest priority, meaning the lowest
36
	 * priority number, i.e. a priority of 1 is greater than one of 2.
37
	 * 
38
	 * @return
39
	 */
40
	public static IMacroCommandFactory getHighestPriorityFactory() {
41
		if (factory == null) {
42
			factory = retrieveFactoryWithHighestPriority();
43
		}
44
		return factory;
45
	}
46
47
	private static IMacroCommandFactory retrieveFactoryWithHighestPriority() {
48
		IConfigurationElement[] elements = Platform.getExtensionRegistry()
49
				.getConfigurationElementsFor(EXTENSION_POINT_ID);
50
51
		IMacroCommandFactory factory = null;
52
		int priority = Integer.MAX_VALUE;
53
		for (int i = 0; i < elements.length; i++) {
54
			if (EXTENSION_POINT_NAME.equals(elements[i].getName())) {
55
				try {
56
					IMacroCommandFactory currentFactory = (IMacroCommandFactory) elements[i]
57
							.createExecutableExtension("class");
58
					int currentPriority = Integer.parseInt(elements[i]
59
							.getAttribute("priority"));
60
61
					if (currentFactory != null && currentPriority < priority) {
62
						factory = currentFactory;
63
						priority = currentPriority;
64
					}
65
				} catch (CoreException e) {
66
					e.printStackTrace();
67
				}
68
			}
69
		}
70
		return factory;
71
	}
72
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/util/XMLDefaultHandler.java (+166 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2003, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.util;
12
13
import java.util.Hashtable;
14
import java.util.Stack;
15
16
import javax.xml.parsers.DocumentBuilderFactory;
17
import javax.xml.parsers.ParserConfigurationException;
18
19
import org.w3c.dom.Element;
20
import org.w3c.dom.Node;
21
import org.w3c.dom.Text;
22
import org.xml.sax.Attributes;
23
import org.xml.sax.Locator;
24
import org.xml.sax.helpers.DefaultHandler;
25
26
public class XMLDefaultHandler extends DefaultHandler
27
{
28
29
	private org.w3c.dom.Document fDocument;
30
31
	private Locator fLocator;
32
33
	private Hashtable fLineTable;
34
35
	private Element fRootElement;
36
37
	private Stack fElementStack = new Stack();
38
	
39
	/* Indicates whether a CDATA section is reached */
40
	private boolean cdataStarted;
41
42
	public XMLDefaultHandler()
43
	{
44
		fLineTable = new Hashtable();
45
	}
46
47
	public void startElement(String uri, String localName, String qName, Attributes attributes)
48
	{
49
		Element element = fDocument.createElement(qName);
50
		for (int i = 0; i < attributes.getLength(); i++)
51
		{
52
			element.setAttribute(attributes.getQName(i), attributes.getValue(i));
53
		}
54
55
		Integer lineNumber = new Integer(fLocator.getLineNumber());
56
		Integer[] range = new Integer[] { lineNumber, new Integer(-1) };
57
		fLineTable.put(element, range);
58
		if (fRootElement == null)
59
			fRootElement = element;
60
		else
61
			((Element) fElementStack.peek()).appendChild(element);
62
		fElementStack.push(element);
63
	}
64
65
	public void endElement(String uri, String localName, String qName)
66
	{
67
		Integer[] range = (Integer[]) fLineTable.get(fElementStack.pop());
68
		range[1] = new Integer(fLocator.getLineNumber());
69
	}
70
71
	/*
72
	 * (non-Javadoc)
73
	 * 
74
	 * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
75
	 */
76
	public void setDocumentLocator(Locator locator)
77
	{
78
		fLocator = locator;
79
	}
80
81
	/*
82
	 * (non-Javadoc)
83
	 * 
84
	 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
85
	 */
86
	public void startDocument()
87
	{
88
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
89
		try
90
		{
91
			fDocument = factory.newDocumentBuilder().newDocument();
92
		}
93
		catch (ParserConfigurationException e)
94
		{
95
		}
96
	}
97
98
	/*
99
	 * (non-Javadoc)
100
	 * 
101
	 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
102
	 */
103
	public void endDocument()
104
	{
105
		fDocument.appendChild(fRootElement);
106
	}
107
108
	/*
109
	 * (non-Javadoc)
110
	 * 
111
	 * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String,
112
	 *      java.lang.String)
113
	 */
114
	public void processingInstruction(String target, String data)
115
	{
116
		fDocument.appendChild(fDocument.createProcessingInstruction(target, data));
117
	}
118
119
	/*
120
	 * (non-Javadoc)
121
	 * 
122
	 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
123
	 */
124
	public void characters(char[] characters, int start, int length)
125
	{
126
		StringBuffer buff = new StringBuffer();
127
		for (int i = 0; i < length; i++)
128
		{
129
			buff.append(characters[start + i]);
130
		}
131
132
		String buffValue = buff.toString();	
133
		boolean isBufferJustWhiteSpace = buffValue.trim().equals("");
134
		boolean isBufferEmpty = buffValue.length() <= 0;
135
		
136
		if ((cdataStarted && isBufferEmpty) || (!cdataStarted && isBufferJustWhiteSpace))
137
		{
138
			cdataStarted = false;
139
			return;
140
		}
141
				
142
		Text text = fDocument.createTextNode(buffValue);
143
		cdataStarted = true;
144
		if (fRootElement == null)
145
			fDocument.appendChild(text);
146
		else
147
			((Element) fElementStack.peek()).appendChild(text);
148
	}
149
	
150
	public Node getDocumentElement()
151
	{
152
		fDocument.getDocumentElement().normalize();
153
		return fDocument.getDocumentElement();
154
	}
155
156
	public org.w3c.dom.Document getDocument()
157
	{
158
		fDocument.getDocumentElement().normalize();
159
		return fDocument;
160
	}
161
162
	public Hashtable getLineTable()
163
	{
164
		return fLineTable;
165
	}
166
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/UIObject.java (+47 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject;
13
14
import org.eclipse.swt.widgets.Widget;
15
16
17
/**
18
 * Represents a widget or a nested object on a widget (e.g. a String item on a ComboBox)
19
 * 
20
 * @author ANy
21
 * @version $Revision$
22
 *
23
 */
24
public class UIObject implements IUIObject {
25
26
	private Widget widget = null;
27
	private Object object = null;
28
	
29
	public UIObject(Widget widget, Object object) {
30
		super();
31
		this.widget = widget;
32
		this.object = object;
33
	}
34
	
35
	public UIObject(Widget widget) {
36
		super();
37
		this.widget = widget;
38
	}
39
40
	public Object getObject() {
41
		return object;
42
	}
43
	
44
	public Widget getWidget() {
45
		return widget;
46
	}	
47
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/IMacroObject.java (+25 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macroobject;
13
14
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
15
16
/**
17
 * @author Alexander Nyssen
18
 */
19
public interface IMacroObject {
20
21
	public abstract Object getContext();
22
23
	public abstract IUIObject getUIObject();
24
25
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macro/EventConstants.java (+28 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macro;
13
14
15
/**
16
 * @author Alexander Nyssen
17
 */
18
public interface EventConstants {
19
20
	/* Custom event types */
21
	/* Indicates that a workbnech part has been closed */
22
	public static final int EVENT_TYPE__WORKBENCH_PART_CLOSED = -1;
23
	
24
	/* Custom event details */
25
	public static final int EVENT_DETAIL__POSITION_BASED_EVENT = Integer.MIN_VALUE;
26
	
27
	public static final int EVENT_DETAIL__VERIFICATION_HOOK_INSERTION_EVENT = Integer.MIN_VALUE + 1;
28
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/commands/factory/IMacroCommandFactory.java (+56 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.commands.factory;
13
14
import java.util.ArrayList;
15
16
import org.eclipse.core.runtime.CoreException;
17
import org.eclipse.swt.widgets.Event;
18
import org.eclipse.tptp.test.auto.gui.internal.commands.IMacroCommand;
19
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroCommandShell;
20
21
/**
22
 * Factory to create commands to record certain events or to create respective commands during playback
23
 * 
24
 * @author Alexander Nyssen
25
 * 
26
 */
27
public interface IMacroCommandFactory {
28
29
	/**
30
	 * Factory method to create a new IMacroCommand during recording. This
31
	 * method is called by the command shell for every event it processes.
32
	 * Multiple calls to this method for succeeding events may be necessary,
33
	 * before an event is actually created and returned).
34
	 * 
35
	 * @param commandShell
36
	 * @param commands
37
	 * @param event
38
	 * @return
39
	 * @throws CoreException
40
	 */
41
	public IMacroCommand createCommand(MacroCommandShell commandShell,
42
			ArrayList commands, Event event) throws CoreException;
43
	
44
	
45
	/**
46
	 * Factory method to create a command instance for a certain command type. This
47
	 * method is called during playback to obtain a command that can then be played-back.
48
	 * 
49
	 * @param commandShell 
50
	 * @param type
51
	 * @return
52
	 * @throws CoreException
53
	 */
54
	public IMacroCommand createCommand(MacroCommandShell commandShell, String type) throws CoreException;
55
56
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/UIObjectResolverDelegateRegistry.java (+203 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
13
14
import java.util.Hashtable;
15
import java.util.Vector;
16
17
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.IConfigurationElement;
19
import org.eclipse.core.runtime.Platform;
20
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoader;
21
import org.eclipse.tptp.test.auto.gui.internal.core.WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter;
22
23
/**
24
 * This class delivers utility methods to load UIObjectResolverDelegates via the
25
 * uiObjectResolverDelegate extension point. It also loads all extensions to the
26
 * deprecated widgetResolver extension point and adapts them to the new
27
 * interface.
28
 * 
29
 * @author Alexander Nyssen
30
 * 
31
 */
32
public class UIObjectResolverDelegateRegistry {
33
34
	private static final String EXTENSION_POINT_NAME = "uiObjectResolverDelegate";
35
	private static final String EXTENSION_POINT_ID = "org.eclipse.tptp.test.auto.gui." 
36
			+ EXTENSION_POINT_NAME;
37
38
	/* Keeps an ordered list of the primitive resolver ids */
39
	private static String[] resolverIds;
40
41
	/*
42
	 * The widget resolver: KEY = resolver id VALUE = A class of type
43
	 * UIObjectResolverDelegateLoader
44
	 */
45
	private static Hashtable uiObjectDelegateResolverLoaders = new Hashtable();
46
47
	/**
48
	 * Load the registered widget resolvers. The widget resolvers are ordered in
49
	 * the descending order of their priority
50
	 */
51
	private static void loadDelegateResolvers() {
52
		IConfigurationElement[] elements = Platform.getExtensionRegistry()
53
				.getConfigurationElementsFor(EXTENSION_POINT_ID);
54
		Vector tempContainer = new Vector(elements.length);
55
56
		for (int i = 0; i < elements.length; i++) {
57
			UIObjectResolverDelegateLoader uiObjectResolverDelegateLoader = constructUIObjectResolverLoaderInstance(elements[i]);
58
			if (uiObjectResolverDelegateLoader != null) {
59
				tempContainer.add(findIndex(uiObjectResolverDelegateLoader
60
						.getPriority(), tempContainer),
61
						uiObjectResolverDelegateLoader);
62
				uiObjectDelegateResolverLoaders.put(
63
						uiObjectResolverDelegateLoader.getId(),
64
						uiObjectResolverDelegateLoader);
65
			}
66
		}
67
68
		// Also add the implementors of the old widgetResolver extension point.
69
		// They are adapted to the new extension point using respective adapters
70
		WidgetResolverLoader[] widgetResolverLoaders = WidgetResolverLoader
71
				.getWidgetResolverLoaders();
72
		for (int i = 0; i < widgetResolverLoaders.length; i++) {
73
			UIObjectResolverDelegateLoader uiObjectResolverDelegateLoader = new WidgetResolverLoaderToUIObjectResolverDelegateLoaderAdapter(
74
					widgetResolverLoaders[i]);
75
			tempContainer.add(findIndex(widgetResolverLoaders[i].getPriority(),
76
					tempContainer), uiObjectResolverDelegateLoader);
77
78
			uiObjectDelegateResolverLoaders.put(uiObjectResolverDelegateLoader
79
					.getId(), uiObjectResolverDelegateLoader);
80
		}
81
82
		resolverIds = new String[tempContainer.size()];
83
		for (int i = 0; i < resolverIds.length; i++) {
84
			resolverIds[i] = ((UIObjectResolverDelegateLoader) tempContainer
85
					.get(i)).getId();
86
		}
87
	}
88
89
	private static int findIndex(int desiredPriority, Vector container,
90
			int startIntervalInx, int endIntervalInx, int length) {
91
		if (startIntervalInx == endIntervalInx
92
				|| startIntervalInx == endIntervalInx - 1) {
93
			if (length > 0) {
94
				UIObjectResolverDelegateLoader widgetResolverReg = (UIObjectResolverDelegateLoader) container
95
						.get(startIntervalInx);
96
				int priority = widgetResolverReg.getPriority();
97
				if (desiredPriority < priority)
98
					return startIntervalInx;
99
			}
100
			return endIntervalInx;
101
		}
102
103
		/* What's in the middle? */
104
		int middleInx = startIntervalInx
105
				+ (int) Math.ceil((endIntervalInx - startIntervalInx) / 2);
106
		UIObjectResolverDelegateLoader widgetResolverReg = (UIObjectResolverDelegateLoader) container
107
				.get(middleInx);
108
		int middleElementPriority = widgetResolverReg.getPriority();
109
110
		if (middleElementPriority > desiredPriority)
111
			endIntervalInx = middleInx;
112
		else if (middleElementPriority < desiredPriority)
113
			startIntervalInx = middleInx;
114
		else
115
			return middleInx;
116
		return findIndex(desiredPriority, container, startIntervalInx,
117
				endIntervalInx, length);
118
	}
119
120
	private static int findIndex(int priority, Vector container) {
121
		int length = container.size();
122
		return findIndex(priority, container, 0, length, length);
123
	}
124
125
	/**
126
	 * This method should not be called by clients. It is only used from 
127
	 * UIObjectDeprecatedDeresolvingSupport 
128
	 * 
129
	 * @return
130
	 */
131
	public static Hashtable getDelegateResolverLoaders() {
132
		if (resolverIds == null) {
133
			UIObjectResolverDelegateRegistry.loadDelegateResolvers();
134
		}
135
		return uiObjectDelegateResolverLoaders;
136
	}
137
138
	/**
139
	 * Returns the list of resolver delegates, sorted by priority
140
	 * 
141
	 * @return
142
	 */
143
	public static IUIObjectResolverDelegate[] getDelegateResolvers() {
144
		if (resolverIds == null) {
145
			UIObjectResolverDelegateRegistry.loadDelegateResolvers();
146
		}
147
148
		IUIObjectResolverDelegate[] resolvers = new IUIObjectResolverDelegate[resolverIds.length];
149
		for (int i = 0; i < resolverIds.length; i++) {
150
			resolvers[i] = ((UIObjectResolverDelegateLoader) uiObjectDelegateResolverLoaders
151
					.get(resolverIds[i])).getUIObjectResolverDelegate();
152
		}
153
		return resolvers;
154
	}
155
156
	public static final IUIObjectResolverDelegate getDelegateResolver(
157
			String resolverId) {
158
		if (resolverIds == null) {
159
			UIObjectResolverDelegateRegistry.loadDelegateResolvers();
160
		}
161
162
		UIObjectResolverDelegateLoader widgetResolverLoader = (UIObjectResolverDelegateLoader) uiObjectDelegateResolverLoaders
163
				.get(resolverId);
164
		return widgetResolverLoader.getUIObjectResolverDelegate();
165
	}
166
167
	/**
168
	 * Constructs an instance of this class based on the configuration element
169
	 * passed in
170
	 * 
171
	 * @param confiugrationElement
172
	 *            The configuration element to be loaded
173
	 * @return An instance of this class based on the configuration element
174
	 *         passed in. null will be returned if there is an error loading the
175
	 *         configuration element.
176
	 */
177
	private static UIObjectResolverDelegateLoader constructUIObjectResolverLoaderInstance(
178
			IConfigurationElement configurationElement) {
179
		String name = configurationElement.getName();
180
		if (!EXTENSION_POINT_NAME.equals(configurationElement.getName()))
181
			return null;
182
183
		try {
184
			String id = configurationElement.getAttribute("id");
185
			IUIObjectResolverDelegate uiObjectResolverDelegate = (IUIObjectResolverDelegate) configurationElement
186
					.createExecutableExtension("class");
187
			int priority = Integer.parseInt(configurationElement
188
					.getAttribute("priority"));
189
190
			if (id == null || uiObjectResolverDelegate == null)
191
				return null;
192
193
			return new UIObjectResolverDelegateLoader(id,
194
					uiObjectResolverDelegate, priority);
195
196
		} catch (CoreException e) {
197
			e.printStackTrace();
198
		}
199
200
		return null;
201
	}
202
203
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/mine/MacroObjectDescriptorMineManager.java (+403 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macroobject.mine;
12
13
import java.io.ByteArrayInputStream;
14
import java.io.IOException;
15
import java.util.Hashtable;
16
import java.util.List;
17
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IPath;
20
import org.eclipse.core.runtime.Path;
21
import org.eclipse.emf.common.util.URI;
22
import org.eclipse.emf.ecore.EObject;
23
import org.eclipse.emf.ecore.resource.Resource;
24
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite;
25
import org.eclipse.hyades.models.common.facades.behavioral.impl.HyadesUtil;
26
import org.eclipse.hyades.test.core.util.EMFUtil;
27
import org.eclipse.hyades.test.tools.ui.common.internal.util.FormUtil;
28
import org.eclipse.osgi.util.NLS;
29
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
30
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
31
import org.eclipse.tptp.test.auto.gui.internal.GlobalConstants;
32
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
33
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
34
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.IDCollisionException;
35
import org.eclipse.tptp.test.auto.gui.internal.macroobject.mine.MacroObjectDescriptorMine.UIObjectNotFound;
36
import org.eclipse.tptp.test.auto.gui.internal.util.XMLDefaultHandler;
37
import org.w3c.dom.NamedNodeMap;
38
import org.w3c.dom.Node;
39
import org.w3c.dom.NodeList;
40
import org.xml.sax.SAXException;
41
42
/**
43
 * In addition to the macro of each test case, a test suite also contains an
44
 * object mine keeps a reference of all resolved objects. The purpose of the
45
 * object mine is to resolve a widget once and use it many times.
46
 * 
47
 * This is a singleton class that can be accessed via <code>getInstance()</code>
48
 * 
49
 * @author Ali Mehregani
50
 */
51
public class MacroObjectDescriptorMineManager {
52
	/** The instance of this class */
53
	private static MacroObjectDescriptorMineManager instance = new MacroObjectDescriptorMineManager();
54
55
	/**
56
	 * Cached object mines KEY = Test suite id VALUE = An object of type
57
	 * MacroObjectDescriptorMine that represents the object mine of the test
58
	 * suite
59
	 */
60
	private Hashtable cachedObjectMines;
61
62
	/**
63
	 * Indicates whether a test suite's object mine is dirty or not KEY = test
64
	 * suite id VALUE = Boolean.TRUE if object mine is dirty; Boolean.FALSE
65
	 * otherwise
66
	 */
67
	private Hashtable dirtyStateTable;
68
69
	/**
70
	 * Restrict the visibility of the constructor
71
	 */
72
	private MacroObjectDescriptorMineManager() {
73
		cachedObjectMines = new Hashtable();
74
		dirtyStateTable = new Hashtable();
75
	}
76
77
	/**
78
	 * Return the instance of this singleton class
79
	 * 
80
	 * @return The instance of this class
81
	 */
82
	public static MacroObjectDescriptorMineManager getInstance() {
83
		return instance;
84
	}
85
86
	/**
87
	 * Load the object mine of the passed in test suite
88
	 * 
89
	 * @param testSuite
90
	 *            The test suite whose object mine is requested
91
	 * @param useCache
92
	 *            Uses the cached value if this is set to true; otherwise the
93
	 *            object mine is reloaded and returned.
94
	 * 
95
	 * @return the object mine of the test suite that is passed in.
96
	 * 
97
	 * @throws UIObjectNotFound
98
	 *             In case an expected object is not found
99
	 * @throws IDCollisionException
100
	 *             In case there is a collision id
101
	 * @throws CoreException
102
	 *             In case of any unexpected error
103
	 */
104
	public MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite,
105
			boolean useCache) throws UIObjectNotFound, IDCollisionException,
106
			CoreException {
107
		/* Is the object mine in cache? */
108
		String testSuiteId = testSuite.getId();
109
		MacroObjectDescriptorMine objectMine = null;
110
		if (useCache
111
				&& (objectMine = (MacroObjectDescriptorMine) cachedObjectMines
112
						.get(testSuiteId)) != null) {
113
			objectMine.setOwner(testSuite);
114
			return objectMine;
115
		}
116
117
		/*
118
		 * Otherwise, it needs to be loaded. We need: - Get the object mine XML
119
		 * fragment - Parse it and load it
120
		 */
121
		String objectMineXML = HyadesUtil.getTestSuiteVariable(testSuite,
122
				GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE);
123
		if (objectMineXML == null || objectMineXML.length() <= 0) {
124
			/* Return a fresh object mine */
125
			objectMine = new MacroObjectDescriptorMine(testSuite, null);
126
		}
127
128
		if (objectMine == null) {
129
			objectMine = loadObjectMine(testSuite, objectMineXML);
130
		}
131
132
		if (objectMine != null) {
133
			cachedObjectMines.put(testSuiteId, objectMine);
134
		}
135
136
		return objectMine;
137
	}
138
139
	private MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite,
140
			String objectMineXML) throws UIObjectNotFound,
141
			IDCollisionException, CoreException {
142
		if (objectMineXML == null || objectMineXML.length() <= 0)
143
			return new MacroObjectDescriptorMine(testSuite, null);
144
145
		XMLDefaultHandler handler = null;
146
147
		try {
148
			handler = MacroUtil.createXMLDocument(new ByteArrayInputStream(
149
					objectMineXML.getBytes("UTF-8")));
150
		} catch (SAXException e) {
151
			AutoGUIUtil.throwCoreException(
152
					AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
153
		} catch (IOException e) {
154
			AutoGUIUtil.throwCoreException(
155
					AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE, 0, e);
156
		}
157
158
		/* Walk through the elemets and parse the document */
159
		Node rootElement = handler.getDocumentElement();
160
		NodeList children = rootElement.getChildNodes();
161
162
		MacroObjectDescriptorMine objectMine = new MacroObjectDescriptorMine(
163
				testSuite, handler);
164
		for (int i = 0, childCount = children.getLength(); i < childCount; i++) {
165
			Node currentChild = children.item(i);
166
			String nodeName = currentChild.getNodeName();
167
			if (MacroConstants.HEADER_ELEMENT.equals(nodeName)) {
168
				loadHeader(objectMine, currentChild);
169
			} else if (MacroConstants.OBJECTS_ELEMENT.equals(nodeName)) {
170
				loadObjects(objectMine, currentChild);
171
			}
172
		}
173
174
		return objectMine;
175
	}
176
177
	/**
178
	 * This method should be used if the object mine will be loaded for reading
179
	 * purposes. Contributors will not be able to use this returned object mine
180
	 * to write any objects.
181
	 * 
182
	 * @param objectMineXML
183
	 *            The XML string representing the object mine
184
	 * 
185
	 * @return the object mine of the test suite that is passed in.
186
	 * 
187
	 * @throws UIObjectNotFound
188
	 *             In case an expected object is not found
189
	 * @throws IDCollisionException
190
	 *             In case there is a collision id
191
	 * @throws CoreException
192
	 *             In case of any unexpected error
193
	 */
194
	public MacroObjectDescriptorMine loadObjectMine(String objectMineXML)
195
			throws UIObjectNotFound, IDCollisionException, CoreException {
196
		return loadObjectMine(null, objectMineXML);
197
	}
198
199
	private void loadHeader(MacroObjectDescriptorMine objectMine,
200
			Node headerNode) throws CoreException, UIObjectNotFound,
201
			IDCollisionException {
202
		/* Let's first read in the contribute attribute */
203
		NamedNodeMap attributes = headerNode.getAttributes();
204
		Node contributeAtt = attributes
205
				.getNamedItem(MacroConstants.OUTPUT_ATTRIBUTE);
206
		if (contributeAtt != null) {
207
			ITestSuite testSuite = loadTestSuite(contributeAtt.getNodeValue());
208
			if (testSuite == null) {
209
				AutoGUIUtil.openErrorWithDetail(
210
						AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
211
						AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUT_NF, null);
212
213
			} else {
214
				try {
215
					MacroObjectDescriptorMine outputObjectMine = MacroObjectDescriptorMineManager
216
							.getInstance().loadObjectMine(testSuite);
217
					objectMine.setOutputSource(outputObjectMine);
218
				} catch (Exception e) {
219
					objectMine.setOutputSource(null);
220
					AutoGUIUtil
221
							.openErrorWithDetail(
222
									AutoGUIMessages.AUTO_GUI_COMMON_ERROR,
223
									NLS
224
											.bind(
225
													AutoGUIMessages.AUTO_GUI_ERROR_OBJ_MINE_OUTPUT,
226
													testSuite.getName()), e);
227
				}
228
			}
229
		}
230
231
		/* Now load in all includes */
232
		NodeList children = headerNode.getChildNodes();
233
		for (int i = 0, childCount = children.getLength(); i < childCount; i++) {
234
			Node currentChild = children.item(i);
235
			String nodeName = currentChild.getNodeName();
236
			if (MacroConstants.INCLUDE_ELEMENT.equals(nodeName)) {
237
				Node pathAttribute = currentChild.getAttributes().getNamedItem(
238
						MacroConstants.PATH_ATTRIBUTE);
239
				if (pathAttribute != null) {
240
					ITestSuite testSuite = loadTestSuite(pathAttribute
241
							.getNodeValue());
242
					MacroObjectDescriptorMine includedObjectMine = loadObjectMine(testSuite);
243
					objectMine.addInclude(includedObjectMine);
244
				}
245
			}
246
		}
247
	}
248
249
	private void loadObjects(MacroObjectDescriptorMine objectMine,
250
			Node objectsNode) throws CoreException, UIObjectNotFound,
251
			IDCollisionException {
252
		NodeList children = objectsNode.getChildNodes();
253
		registerObjects(objectMine, null, children);
254
	}
255
256
	private void registerObjects(MacroObjectDescriptorMine objectMine,
257
			MacroObjectDescriptor parent, NodeList children)
258
			throws CoreException, UIObjectNotFound, IDCollisionException {
259
		/* For every object */
260
		for (int i = 0, childCount = children.getLength(); i < childCount; i++) {
261
			Node currentNode = children.item(i);
262
263
			NamedNodeMap attributes = currentNode.getAttributes();
264
			Node referenceIdNode = attributes
265
					.getNamedItem(MacroConstants.REFERENCE_ID_ATTRIBUTE);
266
			String referenceId = null;
267
			if (referenceIdNode == null
268
					|| (referenceId = referenceIdNode.getNodeValue()) == null) {
269
				Node widetIdAttribute = attributes
270
						.getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE);
271
				Node objectIdAttribute = attributes
272
						.getNamedItem(MacroConstants.OBJECT_ID_ATTRIBUTE);
273
				String widgetId = widetIdAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN
274
						: widetIdAttribute.getNodeValue();
275
				String objectId = objectIdAttribute == null ? AutoGUIMessages.AUTO_GUI_COMMON_UNKNOWN
276
						: objectIdAttribute.getNodeValue();
277
				AutoGUIUtil.throwCoreException(NLS.bind(
278
						AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_REF,
279
						widgetId, objectId), 0);
280
			}
281
282
			MacroObjectDescriptor guiObject = objectMine
283
					.lookupMacroObjectDescriptor(parent, referenceId);
284
285
			/* Register the object if it's not yet registered */
286
			if (guiObject == null) {
287
				guiObject = objectMine.registerObject(parent, currentNode);
288
			}
289
			/* Otherwise throw an exception if there is an id collision */
290
			else {
291
				Node contextIdNode = attributes
292
						.getNamedItem(MacroConstants.CONTEXT_ID_ATTRIBUTE);
293
				Node widgetIdNode = attributes
294
						.getNamedItem(MacroConstants.WIDGET_ID_ATTRIBUTE);
295
				Node objectIdNode = attributes
296
						.getNamedItem(MacroConstants.OBJECT_ID_ATTRIBUTE);
297
				String contextId = contextIdNode == null ? null : contextIdNode
298
						.getNodeValue();
299
				String widgetId = widgetIdNode == null ? null : widgetIdNode
300
						.getNodeValue();
301
				String objectId = objectIdNode == null ? null : objectIdNode
302
						.getNodeValue();
303
304
				if (((contextId == null && guiObject.getContextId() != null) || (contextId != null && !contextId
305
						.equals(guiObject.getContextId())))
306
						|| ((widgetId == null && guiObject.getWidgetId() != null) || (widgetId != null && !widgetId
307
								.equals(guiObject.getWidgetId())))
308
						|| ((objectId == null && guiObject.getObjectId() != null) || (objectId != null && !objectId
309
								.equals(guiObject.getObjectId())))) {
310
					throw new IDCollisionException(NLS.bind(
311
							AutoGUIMessages.AUTO_GUI_ERROR_TST_OBJ_MINE_ID,
312
							referenceId));
313
				}
314
			}
315
316
			/* Load the children of this object */
317
			if (currentNode.getChildNodes().getLength() > 0)
318
				registerObjects(objectMine, guiObject, currentNode
319
						.getChildNodes());
320
		}
321
	}
322
323
	private ITestSuite loadTestSuite(String testSuitePath) throws CoreException {
324
		if (testSuitePath == null || testSuitePath.length() <= 0)
325
			return null;
326
327
		IPath path = new Path(testSuitePath);
328
		URI uri = URI.createPlatformResourceURI(path.toString());
329
		EObject[] eObjects = EMFUtil.getEObjects(uri, true);
330
		return eObjects != null && eObjects.length > 0
331
				&& eObjects[0] instanceof ITestSuite ? (ITestSuite) eObjects[0]
332
				: null;
333
	}
334
335
	public void writeObjectMine(MacroObjectDescriptorMine objectMine) {
336
		writeObjectMine(objectMine, false);
337
	}
338
339
	private void writeObjectMine(MacroObjectDescriptorMine objectMine,
340
			boolean autoSave) {
341
		ITestSuite testSuite = objectMine.getOwner();
342
		Resource testSuiteResource = ((EObject) testSuite).eResource();
343
		autoSave = autoSave
344
				&& (testSuiteResource != null && !testSuiteResource
345
						.isModified());
346
347
		String xmlSerialization = objectMine.serializeToString();
348
		HyadesUtil.setTestSuiteVariable(testSuite,
349
				GlobalConstants.TEST_SUITE_PROPERTY_OBJECT_MINE,
350
				xmlSerialization);
351
352
		if (autoSave) {
353
			try {
354
				EMFUtil.save(testSuiteResource);
355
			} catch (Exception e) {
356
				/* Shouldn't happen */
357
				e.printStackTrace();
358
			}
359
		}
360
361
		/*
362
		 * We also need to update all object mines included by the object mine
363
		 * passed in
364
		 */
365
		List includes = objectMine.getIncludes();
366
		for (int i = 0, includeCount = includes.size(); i < includeCount; i++) {
367
			MacroObjectDescriptorMine currentObjectMine = (MacroObjectDescriptorMine) includes
368
					.get(i);
369
			writeObjectMine(currentObjectMine, true);
370
		}
371
372
		dirtyStateTable.put(testSuite.getId(), Boolean.TRUE);
373
	}
374
375
	public MacroObjectDescriptorMine loadObjectMine(ITestSuite testSuite)
376
			throws UIObjectNotFound, IDCollisionException, CoreException {
377
		Boolean dirtyState = (Boolean) dirtyStateTable.get(testSuite.getId());
378
		boolean isObjectMineDirty = dirtyState == null ? false : dirtyState
379
				.booleanValue();
380
		dirtyStateTable.put(testSuite.getId(), Boolean.FALSE);
381
		return loadObjectMine(testSuite, !isObjectMineDirty);
382
	}
383
384
	/**
385
	 * Marks the object mine of the passed in test suite as dirty
386
	 * 
387
	 * @param testSuite
388
	 *            The test suite
389
	 */
390
	public void markObjectMineDirty(ITestSuite testSuite) {
391
		if (testSuite == null)
392
			return;
393
394
		dirtyStateTable.put(testSuite.getId(), Boolean.TRUE);
395
	}
396
397
	/**
398
	 * Removes all entries in cache. This should be carefully used.
399
	 */
400
	public void clearCache() {
401
		cachedObjectMines.clear();
402
	}
403
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/UIObjectResolver.java (+81 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver;
13
14
import org.eclipse.core.runtime.CoreException;
15
import org.eclipse.osgi.util.NLS;
16
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
17
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
18
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
19
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
20
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.IUIObjectResolverDelegate;
21
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.NonTrivialUIObjectResolverDelegate;
22
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateRegistry;
23
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.UIObjectResolverDelegateLoader;
24
25
/**
26
 * This is a facade that encapsulates resolving/deresolving of UI objects. It
27
 * delegates to the respective UIObjectDelegateResolvers that can be plugged in
28
 * via the respective extension point
29
 * <code>org.eclipse.tptp.auto.gui.uiObjectResolverDelegate</code>.
30
 * 
31
 * @author Alexander Nyssen
32
 * 
33
 */
34
public class UIObjectResolver {
35
36
	public static IUIObjectIdentifier resolve(Object context, IUIObject uiObject)
37
			throws CoreException {
38
39
		IUIObjectResolverDelegate[] delegateResolvers = UIObjectResolverDelegateRegistry
40
				.getDelegateResolvers();
41
		IUIObjectIdentifier identifier = null;
42
		for (int i = 0; i < delegateResolvers.length && identifier == null; i++) {
43
			identifier = delegateResolvers[i].resolve(context, uiObject);
44
45
			if (identifier != null) {
46
				// check if the resolver delegate has set its id into the
47
				// returned
48
				// identifier
49
				if (identifier.getResolverId() == null) {
50
					AutoGUIUtil
51
							.throwCoreException(NLS
52
									.bind(
53
											AutoGUIMessages.AUTO_GUI_RESOLVER_IDENTIFIER_MISSING,
54
											delegateResolvers[i]));
55
					return null;
56
				}
57
			}
58
		}
59
60
		return identifier;
61
	}
62
63
	public static IUIObject deresolve(Object context,
64
			IUIObjectIdentifier uiObjectIdentifier) throws CoreException {
65
		// we need to obtain the resolver id to be able to delegate to the
66
		// respective UIObjectResolverDelegate
67
		String resolverId = uiObjectIdentifier.getResolverId();
68
		if (resolverId == null) {
69
			// if we do not have a resolver id, use one of the old registered
70
			// ones, as they all
71
			// have the same deprecated deresolving mechanism
72
			return UIObjectResolverDelegateRegistry.getDelegateResolver(
73
					NonTrivialUIObjectResolverDelegate.ID).deresolve(context,
74
					uiObjectIdentifier);
75
		}
76
		return UIObjectResolverDelegateRegistry.getDelegateResolver(resolverId)
77
				.deresolve(context, uiObjectIdentifier);
78
79
	}
80
81
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/PrimitiveUIObjectIdentifier.java (+78 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.uiobject;
12
13
/**
14
 * A primitive string UI object identifier. The string object must be an exact
15
 * match for the two given ids to equal. Contributors can extend this class or
16
 * provide a direct implementation of {@link IUIObjectIdentifier}
17
 * 
18
 * @author Ali Mehregani
19
 * @author Alexander Nyssen
20
 */
21
public class PrimitiveUIObjectIdentifier implements IUIObjectIdentifier {
22
23
	/** The resolver objectId */
24
	private String resolverId;
25
	
26
	private String widgetId;
27
28
	/** The string objectId of the object */
29
	private String objectId;
30
31
	public PrimitiveUIObjectIdentifier(String widgetId) {
32
		this.widgetId = widgetId;
33
	}
34
35
	public PrimitiveUIObjectIdentifier(String widgetId, String resolverId) {
36
		this.widgetId = widgetId;
37
		this.resolverId = resolverId;
38
	}
39
	
40
	public PrimitiveUIObjectIdentifier(String widgetId, String objectId, String resolverId) {
41
		this.widgetId = widgetId;
42
		this.objectId = objectId;
43
		this.resolverId = resolverId;
44
	}
45
46
	public String getResolverId() {
47
		return resolverId;
48
	}
49
50
	public void setResolverId(String resolverId) {
51
		this.resolverId = resolverId;
52
	}
53
54
	public String getWidgetId() {
55
		return widgetId;
56
	}
57
	
58
	public String getObjectId(){
59
		return objectId;
60
	}
61
62
	public boolean equals(Object obj) {
63
		if (!(obj instanceof PrimitiveUIObjectIdentifier)) {
64
			return false;
65
		} else {
66
			PrimitiveUIObjectIdentifier other = (PrimitiveUIObjectIdentifier) obj;
67
			boolean equals = (widgetId == null) ? other.widgetId == null
68
					: widgetId.equals(other.widgetId);
69
			return equals;
70
		}
71
	}
72
73
	public String toString() {
74
		return widgetId;
75
	}
76
	
77
78
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/IUIObjectIdentifier.java (+42 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject;
13
14
15
/**
16
 * @author Alexander Nyssen
17
 */
18
public interface IUIObjectIdentifier {
19
20
	/**
21
	 * Returns the id of the widget object to be identified
22
	 * 
23
	 * @return The widget id
24
	 */
25
	public String getWidgetId();
26
	
27
	/**
28
	 * Returns the id of the nested object to be identified on the respective widget,
29
	 * e.g. a String to name an item on a ComboBox.
30
	 * @return The id of the nested object
31
	 */
32
	public String getObjectId();
33
	
34
	/**
35
	 * Returns the id of the ui object resolver delegate that generated this identifier.
36
	 * 
37
	 * @return The id of the ui object resolver delegate that generated this identifier.
38
	 */
39
	public String getResolverId();
40
41
	
42
}
(-)schema/uiObjectResolverDelegate.exsd (+137 lines)
Added Link Here
1
<?xml version='1.0' encoding='UTF-8'?>
2
<!-- Schema file written by PDE -->
3
<schema targetNamespace="org.eclipse.tptp.test.auto.gui" xmlns="http://www.w3.org/2001/XMLSchema">
4
<annotation>
5
      <appinfo>
6
         <meta.schema plugin="org.eclipse.tptp.test.auto.gui" id="uiObjectResolverDelegate" name="uiObjectResolverDelegate"/>
7
      </appinfo>
8
      <documentation>
9
         Use this extension to define a class that is capable of resolving widgets and nested objects on them.
10
      </documentation>
11
   </annotation>
12
13
   <element name="extension">
14
      <annotation>
15
         <appinfo>
16
            <meta.element />
17
         </appinfo>
18
         <documentation>
19
            The following internal extension provides the mean for defining custom widget resolvers.
20
         </documentation>
21
      </annotation>
22
      <complexType>
23
         <sequence>
24
            <element ref="uiObjectResolverDelegate" minOccurs="1" maxOccurs="unbounded"/>
25
         </sequence>
26
         <attribute name="point" type="string" use="required">
27
            <annotation>
28
               <documentation>
29
                  
30
               </documentation>
31
            </annotation>
32
         </attribute>
33
         <attribute name="id" type="string">
34
            <annotation>
35
               <documentation>
36
                  
37
               </documentation>
38
            </annotation>
39
         </attribute>
40
         <attribute name="name" type="string">
41
            <annotation>
42
               <documentation>
43
                  
44
               </documentation>
45
               <appinfo>
46
                  <meta.attribute translatable="true"/>
47
               </appinfo>
48
            </annotation>
49
         </attribute>
50
      </complexType>
51
   </element>
52
53
   <element name="uiObjectResolverDelegate">
54
      <complexType>
55
         <attribute name="class" type="string" use="required">
56
            <annotation>
57
               <documentation>
58
                  The class that is invoked to resolve a widget or a nested object on a widget.
59
Must implement the following interface: org.eclipse.tptp.test.auto.gui.uiObject.resolver.delegate.IUIObjectResolverDelegate
60
               </documentation>
61
               <appinfo>
62
                  <meta.attribute kind="java" basedOn="org.eclipse.tptp.test.auto.gui.uiObject.resolver.delegate.IUIObjectResolverDelegate"/>
63
               </appinfo>
64
            </annotation>
65
         </attribute>
66
         <attribute name="priority" type="string" use="required">
67
            <annotation>
68
               <documentation>
69
                  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).
70
The value of this attribute is expected to be an integer
71
               </documentation>
72
            </annotation>
73
         </attribute>
74
         <attribute name="id" type="string" use="required">
75
            <annotation>
76
               <documentation>
77
                  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.
78
               </documentation>
79
            </annotation>
80
         </attribute>
81
      </complexType>
82
   </element>
83
84
   <annotation>
85
      <appinfo>
86
         <meta.section type="since"/>
87
      </appinfo>
88
      <documentation>
89
         Since TPTP v4.5
90
      </documentation>
91
   </annotation>
92
93
   <annotation>
94
      <appinfo>
95
         <meta.section type="examples"/>
96
      </appinfo>
97
      <documentation>
98
         &lt;!-- Define a UI object resolver delegate with priority 10 --&gt; 
99
  &lt;extension
100
  point=&quot;org.eclipse.tptp.test.auto.gui.uiObjectResolverDelegate&quot;&gt;
101
     &lt;widgetResolver 
102
      id = &quot;org.eclipse.tptp.test.auto.gui.adaptive&quot;
103
      class=&quot;org.eclipse.tptp.test.auto.gui.internal.recorder.AdaptiveWidgetResolver&quot;
104
      priority=&quot;10&quot;
105
     /&gt;
106
  &lt;/extension&gt;
107
      </documentation>
108
   </annotation>
109
110
   <annotation>
111
      <appinfo>
112
         <meta.section type="apiInfo"/>
113
      </appinfo>
114
      <documentation>
115
         [Enter API information here.]
116
      </documentation>
117
   </annotation>
118
119
   <annotation>
120
      <appinfo>
121
         <meta.section type="implementation"/>
122
      </appinfo>
123
      <documentation>
124
         [Enter information about supplied implementation of this extension point.]
125
      </documentation>
126
   </annotation>
127
128
   <annotation>
129
      <appinfo>
130
         <meta.section type="copyright"/>
131
      </appinfo>
132
      <documentation>
133
         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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
134
      </documentation>
135
   </annotation>
136
137
</schema>
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/DeresolvingAmbiguityException.java (+32 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
13
14
/**
15
 * Exception to indicate that multiple MacroObjects are found while deresolving an IMacroObjectIdentifier
16
 * @author Alexander Nyssen
17
 *
18
 */
19
public class DeresolvingAmbiguityException extends Exception {
20
21
	private static final long serialVersionUID = 6617530463057206145L;
22
23
	private int numberOfMatches = 0;
24
	
25
	public DeresolvingAmbiguityException(int numberOfMatches) {
26
		this.numberOfMatches = numberOfMatches;
27
	}
28
29
	public int getNumberOfMatches(){
30
		return numberOfMatches;
31
	}
32
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/uiobject/resolver/delegate/AdaptiveUIObjectResolverDelegate.java (+650 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * $Id: AdaptiveUIObjectResolverDelegate.java,v 1.6 2007/04/26 20:03:22 paules Exp $
8
 * 
9
 * Contributors:
10
 *     IBM Corporation - initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate;
13
14
import java.io.IOException;
15
import java.io.InputStream;
16
import java.lang.reflect.Method;
17
import java.net.URL;
18
import java.util.Hashtable;
19
import java.util.Vector;
20
21
import org.eclipse.core.runtime.CoreException;
22
import org.eclipse.hyades.test.common.util.XMLUtil;
23
import org.eclipse.jface.dialogs.MessageDialog;
24
import org.eclipse.swt.widgets.Widget;
25
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
26
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
27
import org.eclipse.tptp.test.auto.gui.internal.GuiPlugin;
28
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroManager;
29
import org.eclipse.tptp.test.auto.gui.internal.macro.ModeConstants;
30
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
31
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
32
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
33
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
34
import org.eclipse.tptp.test.auto.gui.internal.uiobject.WeightedPropertyUIObjectIdentifier;
35
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver;
36
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.IUIObjectDeprecatedDeresolvingFacade;
37
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.deresolvingsupport.UIObjectDeprecatedDeresolvingSupport;
38
import org.osgi.framework.Bundle;
39
import org.w3c.dom.Element;
40
import org.w3c.dom.NodeList;
41
42
/**
43
 * The following widget resolver attempts to resolve widgets using a static XML
44
 * file stored under the auto-gui folder under this plugin.
45
 * 
46
 * @since 4.1
47
 * @author Ali Mehregani
48
 */
49
public class AdaptiveUIObjectResolverDelegate implements
50
		IUIObjectResolverDelegate, IUIObjectDeprecatedDeresolvingFacade {
51
52
	/**
53
	 * The id of this resolver -- must be in sync with the id registered with
54
	 * the widgetResolver extension.
55
	 */
56
	private static final String ID = "org.eclipse.tptp.test.auto.gui.adaptive";
57
58
	/** The assumed file name relative to this plugin */
59
	public final static String WIDGET_REG_FILE = "auto-gui/widgetReg.xml";
60
61
	/** The widget registerations */
62
	private IWidgetRegistration widgetReg;
63
64
	public AdaptiveUIObjectResolverDelegate() {
65
		widgetReg = new WidgetRegistration(this, WIDGET_REG_FILE);
66
	}
67
68
	public IUIObjectIdentifier resolve(Object context, IUIObject object)
69
			throws CoreException {
70
		if (object.getObject() != null)
71
			return null;
72
73
		widgetReg.load();
74
		IUIObjectIdentifier widgetId = widgetReg
75
				.getWidgetId(object.getWidget());
76
		return widgetId;
77
	}
78
79
	public IUIObject deresolve(Object context,
80
			IUIObjectIdentifier uiObjectIdentifier) throws CoreException {
81
		return UIObjectDeprecatedDeresolvingSupport.deresolve(context,
82
				uiObjectIdentifier);
83
	}
84
85
	/**
86
	 * Clients have the option of overwriting this in order to be able to locate
87
	 * the widget them self in the registeration entries that exist.
88
	 */
89
	public WidgetRegValue findWidget(Hashtable registerations, Widget widget) {
90
		return null;
91
	}
92
93
	public class WidgetRegistration implements IWidgetRegistration {
94
95
		/* The file name */
96
		private String fileName;
97
98
		/* The last size of the file when it was properly read */
99
		private long lastModifiedDate;
100
101
		/*
102
		 * The file size (stored in case there was an error last time reading
103
		 * the file
104
		 */
105
		private long lastModifiedDateDetected;
106
107
		/* Indicates if there was an error in parsing the file */
108
		private boolean errorOccurred;
109
110
		/*
111
		 * The data structures holding the registered widgets. Key = class name;
112
		 * Value = WidgetRegValue
113
		 */
114
		private Hashtable regWidgets;
115
116
		/* The global match threshold */
117
		private float globalMatchThreshold;
118
119
		/* The class name used for the default entry */
120
		public static final String DEFAULT_ENTYR = "0_DEFAULT_ENTRY";
121
122
		/* The adaptive widget resolver used as the driver for resolving widgets */
123
		private AdaptiveUIObjectResolverDelegate adaptiveWidgetResolver;
124
125
		public WidgetRegistration(
126
				AdaptiveUIObjectResolverDelegate adaptiveWidgetResolver,
127
				String fileName) {
128
			this.fileName = fileName;
129
			this.lastModifiedDate = 0;
130
			this.lastModifiedDateDetected = 0;
131
			this.errorOccurred = false;
132
			this.regWidgets = new Hashtable();
133
			this.adaptiveWidgetResolver = adaptiveWidgetResolver;
134
		}
135
136
		public void load() {
137
			InputStream regXMLInputStream = null;
138
			try {
139
140
				Bundle guiBundle = GuiPlugin.getDefault().getBundle();
141
				long currentModifiedDate = guiBundle.getLastModified();// added
142
				// for
143
				// defect
144
				// 169733
145
				// Liz
146
				// Dancy
147
148
				/*
149
				 * Checking the file size doesn't guarantee to us that the file
150
				 * hasn't changed. This is the best we can do. Replace this with
151
				 * last modified date if API is available.
152
				 */
153
				if (currentModifiedDate > 0
154
						&& (currentModifiedDate == lastModifiedDate || (errorOccurred && lastModifiedDateDetected == currentModifiedDate)))
155
					return;
156
157
				URL regFileURL = GuiPlugin.getDefault().getBundle().getEntry(
158
						fileName);
159
				lastModifiedDateDetected = currentModifiedDate;
160
161
				/* Parse the XML file */
162
				regXMLInputStream = regFileURL.openStream();
163
				Element rootElement = XMLUtil.loadDom(regXMLInputStream,
164
						"widgetResolverRule");
165
				if (rootElement == null) {
166
					lastModifiedDate = 0;
167
					errorOccurred = true;
168
169
					/* Display an error message if we are recording */
170
					if (MacroManager.getInstance().getGlobalState() == ModeConstants.RECORDING_MODE) {
171
						AutoGUIUtil.showMessage(
172
								AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T,
173
								AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER,
174
								MessageDialog.WARNING);
175
					}
176
					return;
177
				}
178
				this.regWidgets.clear();
179
				parseRegFile(rootElement);
180
				lastModifiedDate = currentModifiedDate;
181
			} catch (Throwable t) {
182
				/* Set the file size to zero to invalidate this widget resolver */
183
				lastModifiedDate = 0;
184
				errorOccurred = true;
185
186
				/* Display an error message if we are recording */
187
				if (MacroManager.getInstance().getGlobalState() == ModeConstants.RECORDING_MODE) {
188
					AutoGUIUtil.showMessage(
189
							AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER_T,
190
							AutoGUIMessages.AUTO_GUI_ERROR_WID_RESOLVER,
191
							MessageDialog.WARNING);
192
				}
193
			} finally {
194
				if (regXMLInputStream != null) {
195
					try {
196
						regXMLInputStream.close();
197
					} catch (IOException e) {
198
						/* Ignore the error */
199
					}
200
				}
201
			}
202
203
		}
204
205
		public float getGlobalThreshold() {
206
			return globalMatchThreshold;
207
		}
208
209
		/**
210
		 * parse the registation file that has already been loaded
211
		 */
212
		private void parseRegFile(Element rootElement) {
213
			if (rootElement == null)
214
				return;
215
216
			NodeList classList = XMLUtil
217
					.getChildrenByName(rootElement, "class");
218
			parseClassElements(classList);
219
			globalMatchThreshold = Float.parseFloat(XMLUtil.getValue(
220
					rootElement, "globalMatchThreshold"));
221
			NodeList defaultList = XMLUtil.getChildrenByName(rootElement,
222
					"default");
223
			parseDefaultElements(defaultList);
224
		}
225
226
		private void parseDefaultElements(NodeList defaultList) {
227
			if (defaultList == null || defaultList.getLength() < 1)
228
				return;
229
230
			/* We only expect one default element */
231
			if (defaultList.item(0) instanceof Element) {
232
				Element defaultElement = (Element) defaultList.item(0);
233
				NodeList methodList = XMLUtil.getChildrenByName(defaultElement,
234
						"method");
235
				WidgetRegValue widgetReg = new WidgetRegValue();
236
237
				parseMethod(methodList, widgetReg);
238
				if (widgetReg != null)
239
					regWidgets.put(DEFAULT_ENTYR, widgetReg);
240
241
			}
242
		}
243
244
		/**
245
		 * Parse the class elements
246
		 */
247
		private void parseClassElements(NodeList classList) {
248
			if (classList == null || classList.getLength() <= 0)
249
				return;
250
251
			for (int i = 0; i < classList.getLength(); i++) {
252
				if (classList.item(i) instanceof Element) {
253
254
					Element classElement = (Element) classList.item(i);
255
					String className = XMLUtil.getValue(classElement, "name");
256
					NodeList methodList = XMLUtil.getChildrenByName(
257
							classElement, "method");
258
					WidgetRegValue widgetReg = new WidgetRegValue();
259
					String matchThreshold = XMLUtil.getValue(classElement,
260
							"matchThreshold");
261
					if (matchThreshold != null)
262
						widgetReg.setClassMatchThreshold(Float
263
								.parseFloat(matchThreshold));
264
265
					parseMethod(methodList, widgetReg);
266
					if (widgetReg != null)
267
						regWidgets.put(className, widgetReg);
268
269
				}
270
			}
271
		}
272
273
		/**
274
		 * Parse the method element and return a widget registration entry
275
		 * 
276
		 * @param methodList
277
		 *            The method list
278
		 * @param widgetReg
279
		 *            the widget registration entry that will be augmented
280
		 * @return A widget registeration entry
281
		 */
282
		private void parseMethod(NodeList methodList, WidgetRegValue widgetReg) {
283
			if (methodList == null || methodList.getLength() <= 0)
284
				return;
285
286
			for (int i = 0; i < methodList.getLength(); i++) {
287
				if (methodList.item(i) instanceof Element) {
288
					Element methodElement = (Element) methodList.item(i);
289
					String methodName = XMLUtil.getValue(methodElement, "name");
290
					float weight = Float.parseFloat(XMLUtil.getValue(
291
							methodElement, "weight"));
292
					PropertyValue propertyVal = new PropertyValue();
293
					propertyVal.setWeight(weight);
294
295
					NodeList argumentList = XMLUtil.getChildrenByName(
296
							methodElement, "argument");
297
					if (argumentList != null)
298
						parseArguments(argumentList, propertyVal);
299
300
					widgetReg.addProperty(methodName, propertyVal);
301
				}
302
			}
303
		}
304
305
		/**
306
		 * Parse the arguments
307
		 * 
308
		 * @param argumentList
309
		 *            The arugment list
310
		 * @param propertyVal
311
		 *            The property value entry that will be augmented to.
312
		 */
313
		private void parseArguments(NodeList argumentList,
314
				PropertyValue propertyVal) {
315
			if (argumentList == null || argumentList.getLength() <= 0)
316
				return;
317
318
			Vector arguments = new Vector();
319
			for (int i = 0; i < argumentList.getLength(); i++) {
320
				if (argumentList.item(i) instanceof Element) {
321
					Element argumentElement = (Element) argumentList.item(i);
322
					String argumentValue = XMLUtil.getValue(argumentElement,
323
							"value");
324
					arguments.add(argumentValue);
325
				}
326
			}
327
328
			propertyVal.setArguments(arguments);
329
		}
330
331
		public IUIObjectIdentifier getWidgetId(Widget widget) {
332
			/*
333
			 * Use this resolver if we were able to successfully resolve parse
334
			 * the XML file
335
			 */
336
			if (lastModifiedDate > 0) {
337
				/*
338
				 * First attempt the widget itself. If that fails, then try its
339
				 * data attribute
340
				 */
341
				Object data = widget;
342
343
				WidgetRegValue widgetValue = (WidgetRegValue) regWidgets
344
						.get(data.getClass().getName());
345
				if (widgetValue == null && widget.getData() != null) {
346
					data = widget.getData();
347
					widgetValue = (WidgetRegValue) regWidgets.get(data
348
							.getClass().getName());
349
350
					/*
351
					 * If that fails, then walk throught the class heirarchy
352
					 * (the interafaces and superclasses
353
					 */
354
					if (widgetValue == null) {
355
						widgetValue = walkThroughClassHeirarchy(data.getClass());
356
357
					}
358
				}
359
360
				/*
361
				 * As a final resolution, try and call the driver class to
362
				 * resolve the widget
363
				 */
364
				if (widgetValue == null)
365
					widgetValue = adaptiveWidgetResolver.findWidget(regWidgets,
366
							widget);
367
368
				Vector propertyWeightPair = new Vector(5);
369
370
				boolean specificValidEntry = false;
371
				boolean defaultValidEntry = false;
372
373
				float threshold = 0;
374
				if (widgetValue != null) {
375
					threshold = widgetValue.getClassMatchThreshold();
376
					if (threshold == 0)
377
						threshold = globalMatchThreshold;
378
379
					/* Specific properties associated with this type */
380
					specificValidEntry = appendProperties(data,
381
							propertyWeightPair, widgetValue);
382
				}
383
384
				/* Default properties */
385
				Vector defaultEntries = new Vector();
386
				defaultValidEntry = appendProperties(widget, defaultEntries,
387
						(WidgetRegValue) regWidgets.get(DEFAULT_ENTYR), true);
388
				if (defaultValidEntry)
389
					propertyWeightPair.addAll(propertyWeightPair);
390
391
				/*
392
				 * Return null if we weren't able to get any of the widgets
393
				 * properties
394
				 */
395
				if (propertyWeightPair.size() <= 0)
396
					return null;
397
398
				if (specificValidEntry || defaultValidEntry) {
399
					WeightedPropertyUIObjectIdentifier adaptiveWidgetId = new WeightedPropertyUIObjectIdentifier(
400
							propertyWeightPair.toArray(), threshold, ID);
401
					return adaptiveWidgetId;
402
				}
403
				return null;
404
			}
405
406
			return null;
407
		}
408
409
		private WidgetRegValue walkThroughClassHeirarchy(Class widgetClass) {
410
			WidgetRegValue widgetValue = null;
411
412
			widgetValue = (WidgetRegValue) regWidgets
413
					.get(widgetClass.getName());
414
			if (widgetValue != null)
415
				return widgetValue;
416
417
			Class[] interfaces = widgetClass.getInterfaces();
418
419
			/* Try the interfaces first */
420
			for (int i = 0; i < interfaces.length; i++) {
421
				widgetValue = (WidgetRegValue) regWidgets.get(interfaces[i]
422
						.getName());
423
				widgetValue = (widgetValue == null ? walkThroughClassHeirarchy(interfaces[i])
424
						: widgetValue);
425
				if (widgetValue != null)
426
					return widgetValue;
427
			}
428
429
			/* We failed with the interfaces, now try the super class */
430
			Class extendedClass = widgetClass.getSuperclass();
431
			if (extendedClass != null)
432
				widgetValue = walkThroughClassHeirarchy(extendedClass);
433
434
			return widgetValue;
435
		}
436
437
		private boolean appendProperties(Object data,
438
				Vector propertyWeightPair, WidgetRegValue widgetValue) {
439
			return appendProperties(data, propertyWeightPair, widgetValue,
440
					false);
441
		}
442
443
		private boolean appendProperties(Object data,
444
				Vector propertyWeightPair, WidgetRegValue widgetValue,
445
				boolean isDefault) {
446
			boolean validEntry = false;
447
			if (widgetValue == null)
448
				return false;
449
450
			Vector properties = widgetValue.getProperties();
451
			for (int i = 0, propertySize = properties.size(); i < propertySize; i++) {
452
				String property = (String) properties.get(i);
453
				PropertyValue propertyValue = widgetValue
454
						.getPropertyValue(property);
455
				String retValue = invokeProperty(data, property, propertyValue);
456
457
				if ((retValue == null || retValue.length() <= 0) && isDefault)
458
					retValue = invokeProperty(((Widget) data).getData(),
459
							property, propertyValue);
460
461
				/* Don't add it if the return value is null or of zero length */
462
				if (retValue == null || retValue.length() <= 0)
463
					retValue = "null"; /*
464
										 * Set the value to the literal string
465
										 * 'null'
466
										 */
467
				else
468
					validEntry = true;
469
470
				propertyWeightPair.add(new Object[] { retValue,
471
						String.valueOf(propertyValue.getWeight()) });
472
			}
473
			return validEntry;
474
		}
475
476
		/**
477
		 * Invoke the appropriate method to get the property value
478
		 * 
479
		 * @param data
480
		 *            The data corresponding to the widget or the data attribute
481
		 *            of the widget
482
		 * @param theMethod
483
		 *            The method corresponding to the property value
484
		 * @param propertyValue
485
		 *            The property information container
486
		 * 
487
		 * @return The returned value of the method corresponding to the
488
		 *         argument
489
		 */
490
		private String invokeProperty(Object data, String theMethod,
491
				PropertyValue propertyValue) {
492
			try {
493
				if (data == null) {
494
					return null;
495
				}
496
497
				Class theClass = data.getClass();
498
				int paramCount = 0;
499
				Vector args = propertyValue.getArguments();
500
				if (args != null && args.size() > 0)
501
					paramCount = args.size();
502
503
				/* We only support method with string parameters */
504
				Class[] params = new Class[paramCount];
505
				for (int i = 0; i < params.length; i++)
506
					params[i] = String.class;
507
508
				Method method = theClass.getMethod(theMethod, params);
509
510
				Object[] methodArgs = null;
511
				if (paramCount > 0)
512
					methodArgs = propertyValue.getArguments().toArray();
513
514
				Object retValue = method.invoke(data, methodArgs);
515
				if (retValue != null) {
516
					return retValue.toString();
517
				}
518
				return null;
519
			} catch (Throwable t) {
520
				/* Return null if in case we can retrieve the property value */
521
				return null;
522
			}
523
524
		}
525
526
		public WidgetRegValue getDefaultWidgetReg() {
527
			if (regWidgets == null)
528
				return null;
529
			return (WidgetRegValue) regWidgets.get(DEFAULT_ENTYR);
530
		}
531
532
	}
533
534
	/**
535
	 * Can be used to provide any alternative implementation of how the widget
536
	 * registration file is loaded and queried.
537
	 * 
538
	 * @author Ali Mehregani
539
	 */
540
	public interface IWidgetRegistration {
541
542
		/**
543
		 * Used to load the necessary file and store the data in a datastructure
544
		 * that will later be used to query the registrations.
545
		 */
546
		public void load();
547
548
		/**
549
		 * Retrieve the widget id from the registrations
550
		 * 
551
		 * @param widget
552
		 *            The widget in question
553
		 * @return The persistent identifier for the widget
554
		 */
555
		public IUIObjectIdentifier getWidgetId(Widget widget);
556
	}
557
558
	/**
559
	 * A container class for the registeration value of a widget
560
	 * 
561
	 * @author Ali Mehregani
562
	 */
563
	private class WidgetRegValue {
564
565
		/* Key = method names, value = propertyValue */
566
		private Hashtable properties;
567
568
		/* Class match treshold */
569
		private float classMatchThreshold;
570
571
		/*
572
		 * This vector is used to preserve the ordering of the properties
573
		 * inserted in the hashtable
574
		 */
575
		private Vector hashKeys;
576
577
		public WidgetRegValue() {
578
			properties = new Hashtable();
579
			classMatchThreshold = 0;
580
			hashKeys = new Vector();
581
		}
582
583
		public Vector getProperties() {
584
			return hashKeys;
585
		}
586
587
		public PropertyValue getPropertyValue(String propertyValue) {
588
			return (PropertyValue) properties.get(propertyValue);
589
		}
590
591
		public PropertyValue getPropertyValue(int inx) {
592
			if (inx >= hashKeys.size())
593
				return null;
594
			return (PropertyValue) properties.get(hashKeys.get(inx));
595
		}
596
597
		public void addProperty(String methodName, PropertyValue propertyValue) {
598
			hashKeys.add(methodName);
599
			properties.put(methodName, propertyValue);
600
		}
601
602
		public float getClassMatchThreshold() {
603
			return classMatchThreshold;
604
		}
605
606
		public void setClassMatchThreshold(float classMatchThreshold) {
607
			this.classMatchThreshold = classMatchThreshold;
608
		}
609
610
	}
611
612
	/**
613
	 * Container class for property values
614
	 * 
615
	 * @author Ali Mehregani
616
	 */
617
	private class PropertyValue {
618
619
		private Vector arguments;
620
		private float weight;
621
622
		public Vector getArguments() {
623
			return arguments;
624
		}
625
626
		public void setArguments(Vector arguments) {
627
			this.arguments = arguments;
628
		}
629
630
		public float getWeight() {
631
			return weight;
632
		}
633
634
		public void setWeight(float weight) {
635
			this.weight = weight;
636
		}
637
	}
638
639
	public boolean foundWidget(Widget widget, IUIObjectIdentifier widgetId) {
640
		try {
641
			IUIObjectIdentifier id = UIObjectResolver.resolve(new MacroObject(
642
					new UIObject(widget)).getContext(), new UIObject(widget));
643
			return id == null ? false : id == null ? false : id.getWidgetId()
644
					.equals(widgetId.getWidgetId());
645
		} catch (CoreException e) {
646
			e.printStackTrace();
647
		}
648
		return false;
649
	}
650
}
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/MacroObjectIdentifier.java (+150 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2009 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.tptp.test.auto.gui.internal.macroobject;
12
13
import org.eclipse.core.runtime.Path;
14
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
15
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
16
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
17
18
/**
19
 * Used as an identifier for Macro objects.
20
 * 
21
 * @author Alexander Nyssen
22
 */
23
public class MacroObjectIdentifier implements IMacroObjectIdentifier {
24
25
	/** The context id */
26
	private String contextId;
27
28
	/** The ui object id */
29
	private IUIObjectIdentifier uiObjectIdentifier;
30
31
	/**
32
	 * Constructor
33
	 * 
34
	 * @param contextId
35
	 *            The context id
36
	 * @param uiObjectId
37
	 *            The widget id
38
	 */
39
	public MacroObjectIdentifier(String contextId,
40
			IUIObjectIdentifier uiObjectIdentifier) {
41
		this.contextId = contextId;
42
		this.uiObjectIdentifier = uiObjectIdentifier;
43
	}
44
45
	/**
46
	 * An object in question is equalled to this object iff the object is of the
47
	 * same type and the context and the widget ids are the same.
48
	 * 
49
	 * @param object
50
	 *            The object in question
51
	 * 
52
	 * @return A boolean indicating whether object is equalled to this object or
53
	 *         not.
54
	 */
55
	public boolean equals(Object object) {
56
		if (object == null)
57
			return false;
58
		if (object == this)
59
			return true;
60
		if (object instanceof MacroObjectIdentifier) {
61
			MacroObjectIdentifier wid = (MacroObjectIdentifier) object;
62
			return wid.contextId.equals(contextId)
63
					&& uiObjectIdentifier.getWidgetId().equals(
64
							wid.getObjectIdentifier().getWidgetId());
65
		}
66
		return false;
67
	}
68
69
	/**
70
	 * Returns the context id of this identifier
71
	 * 
72
	 * @return The context id
73
	 */
74
	public String getContextIdentifier() {
75
		return contextId.toString();
76
	}
77
78
	public IUIObjectIdentifier getObjectIdentifier() {
79
		return uiObjectIdentifier;
80
	}
81
82
	public static IMacroObjectIdentifier deserializeMacroObjectIdentifier(
83
			String macroObjectIdentifierString) {
84
85
		// 1) retrieve the context, object and resolver id
86
		// first retrieve the resolver id
87
		String resolverId = null;
88
		if (macroObjectIdentifierString
89
				.indexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR) >= 0) {
90
			resolverId = macroObjectIdentifierString
91
					.substring(macroObjectIdentifierString
92
							.lastIndexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR) + 3);
93
			macroObjectIdentifierString = macroObjectIdentifierString
94
					.substring(
95
							0,
96
							macroObjectIdentifierString
97
									.lastIndexOf(MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR));
98
		}
99
100
		// now the object id separator
101
		String objectId = null;
102
		if (macroObjectIdentifierString
103
				.indexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) >= 0) {
104
			objectId = macroObjectIdentifierString
105
					.substring(macroObjectIdentifierString
106
							.lastIndexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR) + 3);
107
			macroObjectIdentifierString = macroObjectIdentifierString
108
					.substring(
109
							0,
110
							macroObjectIdentifierString
111
									.lastIndexOf(MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR));
112
		}
113
114
		// now the widget id
115
		String widgetId = macroObjectIdentifierString
116
				.substring(macroObjectIdentifierString
117
						.lastIndexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR) + 3);
118
		macroObjectIdentifierString = macroObjectIdentifierString
119
				.substring(0, macroObjectIdentifierString
120
						.lastIndexOf(MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR));
121
122
		// now the context id
123
		String contextId = new Path(macroObjectIdentifierString).removeTrailingSeparator().toString();
124
125
		// 2) construct a new identifier and return it
126
		IMacroObjectIdentifier macroObjectIdentifier = new MacroObjectIdentifier(
127
				contextId,
128
				new PrimitiveUIObjectIdentifier(widgetId, objectId, resolverId));
129
		return macroObjectIdentifier;
130
	}
131
132
	public static String serializeMacroObjectIdentifier(
133
			IMacroObjectIdentifier macroObjectIdentifier) {
134
		return macroObjectIdentifier.getContextIdentifier()
135
				// concat widet id
136
				+ MacroConstants.WIDGET_ID_SUFFIX_SEPARATOR
137
				+ macroObjectIdentifier.getObjectIdentifier().getWidgetId()
138
				// concat object id
139
				+ (macroObjectIdentifier.getObjectIdentifier().getObjectId() != null ? MacroConstants.OBJECT_ID_SUFFIX_SEPARATOR
140
						+ macroObjectIdentifier.getObjectIdentifier()
141
								.getObjectId()
142
						: "")
143
				// concat resolver id
144
				+ (macroObjectIdentifier.getObjectIdentifier().getResolverId() != null ? MacroConstants.RESOLVER_ID_SUFFIX_SEPARATOR
145
						+ macroObjectIdentifier.getObjectIdentifier()
146
								.getResolverId()
147
						: "");
148
	}
149
150
}
(-).settings/org.eclipse.jdt.core.prefs (+12 lines)
Added Link Here
1
#Tue Jan 22 16:24:58 CET 2008
2
eclipse.preferences.version=1
3
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6
org.eclipse.jdt.core.compiler.compliance=1.4
7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8
org.eclipse.jdt.core.compiler.debug.localVariable=generate
9
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
11
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
12
org.eclipse.jdt.core.compiler.source=1.3
(-)src/org/eclipse/tptp/test/auto/gui/internal/macroobject/resolver/MacroObjectResolver.java (+763 lines)
Added Link Here
1
/**********************************************************************
2
 * Copyright (c) 2009 Alexander Nyssen and others.
3
 * All rights reserved. This content is made available under 
4
 * the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html        
7
 * $Id$
8
 *
9
 * Contributors:
10
 * Alexander Nyssen - Initial contribution
11
 **********************************************************************/ 
12
package org.eclipse.tptp.test.auto.gui.internal.macroobject.resolver;
13
14
import org.eclipse.core.runtime.Assert;
15
import org.eclipse.core.runtime.CoreException;
16
import org.eclipse.core.runtime.IPath;
17
import org.eclipse.core.runtime.Path;
18
import org.eclipse.jface.action.CoolBarManager;
19
import org.eclipse.jface.action.ICoolBarManager;
20
import org.eclipse.jface.action.IMenuManager;
21
import org.eclipse.jface.action.IToolBarManager;
22
import org.eclipse.jface.action.MenuManager;
23
import org.eclipse.jface.action.ToolBarManager;
24
import org.eclipse.jface.window.ApplicationWindow;
25
import org.eclipse.jface.wizard.IWizardPage;
26
import org.eclipse.jface.wizard.WizardDialog;
27
import org.eclipse.osgi.util.NLS;
28
import org.eclipse.swt.custom.CTabFolder;
29
import org.eclipse.swt.custom.CTabItem;
30
import org.eclipse.swt.widgets.Control;
31
import org.eclipse.swt.widgets.Decorations;
32
import org.eclipse.swt.widgets.Menu;
33
import org.eclipse.swt.widgets.MenuItem;
34
import org.eclipse.swt.widgets.Shell;
35
import org.eclipse.swt.widgets.TabFolder;
36
import org.eclipse.swt.widgets.TabItem;
37
import org.eclipse.swt.widgets.ToolBar;
38
import org.eclipse.swt.widgets.ToolItem;
39
import org.eclipse.swt.widgets.Widget;
40
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIMessages;
41
import org.eclipse.tptp.test.auto.gui.internal.AutoGUIUtil;
42
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroConstants;
43
import org.eclipse.tptp.test.auto.gui.internal.macro.MacroUtil;
44
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObject;
45
import org.eclipse.tptp.test.auto.gui.internal.macroobject.IMacroObjectIdentifier;
46
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObject;
47
import org.eclipse.tptp.test.auto.gui.internal.macroobject.MacroObjectIdentifier;
48
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObject;
49
import org.eclipse.tptp.test.auto.gui.internal.uiobject.IUIObjectIdentifier;
50
import org.eclipse.tptp.test.auto.gui.internal.uiobject.PrimitiveUIObjectIdentifier;
51
import org.eclipse.tptp.test.auto.gui.internal.uiobject.UIObject;
52
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.UIObjectResolver;
53
import org.eclipse.tptp.test.auto.gui.internal.uiobject.resolver.delegate.DeresolvingAmbiguityException;
54
import org.eclipse.ui.IActionBars;
55
import org.eclipse.ui.IEditorPart;
56
import org.eclipse.ui.IViewPart;
57
import org.eclipse.ui.IViewSite;
58
import org.eclipse.ui.IWorkbenchPart;
59
60
/**
61
 * Provides functionality to resolve a IMacroObject into an
62
 * IMacroObjectIdentifier that can be persistently stored, and to deresolve an
63
 * IMacroObjectIdentifier back into an IMacroObject.
64
 * 
65
 * During resolving a context identifier for the context of the IMacroObject is
66
 * computed and the resolving of the IUIObject nested inside the IMacroObject is
67
 * delegated to the UIObjectResolver (the resulting IUIObjectIdentifier is then
68
 * be nested into the returned IMacroObjectIdentifier).
69
 * 
70
 * During deresolving the context object is first deresolved, then the IUIObject
71
 * nested inside the IMacroObject is deresolved by delegating to the
72
 * IUIObjectResolver again.
73
 * 
74
 * @author Alexander Nyssen
75
 * 
76
 */
77
public final class MacroObjectResolver {
78
79
	/**
80
	 * Resolve a IMacroObject into an IMacroObjectIdentifier representation,
81
	 * that can be persistently stored and that allows to deresolve the
82
	 * IMacroObject during playback. Delegates to UIObjectResolver's resolve()
83
	 * method to obtain the IUIObjectIdentifier part of the
84
	 * IMacroObjectIdentifier
85
	 * 
86
	 * @param macroObject
87
	 * @return
88
	 */
89
	public static IMacroObjectIdentifier resolve(Shell shell,
90
			IMacroObject macroObject) throws CoreException {
91
		// retrieve the context id of the UI object
92
93
		// compute a context identifier based on the context object of the
94
		// macroObject
95
		String contextIdentifier = resolveContextIdentifier(shell, macroObject);
96
97
		// compute the object id by delegating to the UIObjectResolver
98
		IUIObjectIdentifier uiObjectIdentifier = UIObjectResolver.resolve(
99
				macroObject.getContext(), macroObject.getUIObject());
100
101
		IMacroObjectIdentifier identifier = null;
102
		// compute the object id and build a new MacroObjectIdentifier from both
103
		if (contextIdentifier != null && uiObjectIdentifier != null) {
104
			// identifier = new MacroObjectIdentifier(contextIdentifier,
105
			// uiObjectIdentifier);
106
			identifier = checkAnfFixUnambiguousIdentifier(shell, macroObject,
107
					new MacroObjectIdentifier(contextIdentifier,
108
							uiObjectIdentifier));
109
		}
110
		return identifier;
111
	}
112
113
	/**
114
	 * This method implements a workaround for defect #147766. It checks whether
115
	 * the provided IMacroObject can be unambiguously deresolved by using the
116
	 * provided IMacroObjectIdentifier.
117
	 * 
118
	 * As detection of deresolving ambiguities is limited to Control instances,
119
	 * this method does only have an effect, if the passed in macro object
120
	 * contains a control as the widget of its nested UI object.
121
	 * 
122
	 * If the passed in IMacroObjectIdentifier is ambiguous, an index is added
123
	 * to the widget id of the nested UIObjectIdnentifier to ensure unambiguity
124
	 * during deresolving (the locateVisibleChild() method of the
125
	 * UIObjectDeprecatedDeresolvingSupport class handles this case). If the
126
	 * passed in IMacroObjectIdentifier is unambiguous or the deresolving did
127
	 * fail because of any other reason, this method does not have any effect
128
	 * and simply returns the passed in IMacroObjectIdentifier.
129
	 */
130
	private static IMacroObjectIdentifier checkAnfFixUnambiguousIdentifier(
131
			Shell shell, IMacroObject macroObject,
132
			IMacroObjectIdentifier macroObjectIdentifier) throws CoreException {
133
		try {
134
			// ANy: IMPORTANT: I observed that in case of MenuItems, deresolving
135
			// during recording causes the widget to get disposed as a
136
			// side-effect.
137
			// Also because of this, limiting the check to Control instances is
138
			// necessary.
139
			if (macroObject.getUIObject().getWidget() instanceof Control) {
140
				deresolve(shell, new MacroObjectIdentifier(
141
						macroObjectIdentifier.getContextIdentifier(),
142
						macroObjectIdentifier.getObjectIdentifier()));
143
			}
144
		} catch (Throwable t) {
145
			// ANy: IMPORTANT: In case we get a core exception we have to check
146
			// if
147
			// ambiguity of the passed in identifier was the reason.
148
			if (t instanceof CoreException
149
					&& ((CoreException) t).getCause() instanceof DeresolvingAmbiguityException) {
150
				// provide a workaround by adding a respective
151
				// identifier suffix to identify the desired match
152
				IUIObjectIdentifier unambiguousUIObjectIdentifier = computeUnambigousUIObjectIdentifier(
153
						macroObject.getContext(), macroObject.getUIObject(),
154
						macroObjectIdentifier.getObjectIdentifier(),
155
						((DeresolvingAmbiguityException) ((CoreException) t)
156
								.getCause()).getNumberOfMatches());
157
				if (unambiguousUIObjectIdentifier != null) {
158
					// if we were successful, return the new - now unambiguous -
159
					// identifier.
160
					return new MacroObjectIdentifier(macroObjectIdentifier
161
							.getContextIdentifier(),
162
							unambiguousUIObjectIdentifier);
163
				} else {
164
					// throw an exception to notify the user.
165
					AutoGUIUtil
166
							.throwCoreException(
167
									NLS
168
											.bind(
169
													AutoGUIMessages.AUTO_GUI_UI_OBJECT_IDENTIFIER_AMBIGUOUS,
170
													macroObjectIdentifier
171
															.getObjectIdentifier()
172
															.getWidgetId(),
173
													macroObjectIdentifier
174
															.getObjectIdentifier()
175
															.getObjectId()), t
176
											.getCause());
177
					return null;
178
				}
179
			} else {
180
				// All other reasons are ignored here, so return the passed in
181
				// macro object identifier.
182
				return macroObjectIdentifier;
183
			}
184
		}
185
		// if no exeption is thrown, the deresolving worked, so return the
186
		// passed in macro object identifier.
187
		return macroObjectIdentifier;
188
	}
189
190
	private static IUIObjectIdentifier computeUnambigousUIObjectIdentifier(
191
			Object context, IUIObject uiObject,
192
			IUIObjectIdentifier ambigousIdentifier, int numberOfMatches) {
193
		IUIObjectIdentifier unambigousIdentifier = null;
194
		// check each match to see which one is the desired target
195
		for (int i = 0; i < numberOfMatches && unambigousIdentifier == null; i++) {
196
			try {
197
				String uniqueWidgetId = ambigousIdentifier
198
						.getWidgetId()
199
						.concat(
200
								MacroConstants.WIDGET_ID_UNIQUENESS_INDEX_SEPARATOR
201
										+ new Integer(i).toString());
202
				IUIObjectIdentifier modifiedUIObjectIdentifier = new PrimitiveUIObjectIdentifier(
203
						uniqueWidgetId, ambigousIdentifier.getObjectId(),
204
						ambigousIdentifier.getResolverId());
205
				IUIObject deresolvedUIObject = UIObjectResolver.deresolve(
206
						context, modifiedUIObjectIdentifier);
207
				if (deresolvedUIObject != null
208
						&& deresolvedUIObject.getWidget() == uiObject
209
								.getWidget()) {
210
					unambigousIdentifier = modifiedUIObjectIdentifier;
211
				}
212
			} catch (Throwable t) {
213
			}
214
		}
215
		return unambigousIdentifier;
216
	}
217
218
	private static String resolveContextIdentifier(Shell shell,
219
			IMacroObject macroObject) throws CoreException {
220
		Widget widget = macroObject.getUIObject().getWidget();
221
		if (widget instanceof MenuItem) {
222
			if (macroObject.getContext() instanceof Menu) {
223
				IViewPart view = null;
224
				if (MacroUtil.onMenubar((MenuItem) widget)) {
225
					return new Path(MacroConstants.MENUS_VALUE).toString(); //$NON-NLS-1$
226
				} else if ((view = MacroUtil
227
						.onWorkbenchPartToolbar((MenuItem) widget)) != null) {
228
					return new Path(MacroConstants.LOCAL_TOOLBAR_MENU_VALUE)
229
							.append(
230
									new Path(MacroConstants.VIEW_VALUE)
231
											.append(view.getSite().getId()))
232
							.toString();
233
				}
234
				return null;
235
236
			} else if (macroObject.getContext() instanceof Control) {
237
				IMacroObjectIdentifier focusControlIdentifier = resolve(shell,
238
						new MacroObject(new UIObject((Control) macroObject
239
								.getContext())));
240
				if (focusControlIdentifier == null) {
241
					return null;
242
				} else {
243
					// the context id of a popup menu item is the concatenation
244
					// of the
245
					// MacroConstants.POPUP_VALUE keyword followed by the
246
					// IMacroObjectIdentifier
247
					// of the focus control
248
					return new Path(MacroConstants.POPUP_VALUE)
249
							.append(
250
									MacroObjectIdentifier
251
											.serializeMacroObjectIdentifier(focusControlIdentifier))
252
							.toString(); //$NON-NLS-1$
253
				}
254
			}
255
			return null;
256
		} else if (widget instanceof ToolItem) {
257
			/*
258
			 * Check to see if this toolbar belongs to the global toolbar of the
259
			 * workbench
260
			 */
261
			if (macroObject.getContext() instanceof IToolBarManager
262
					|| macroObject.getContext() instanceof ICoolBarManager) {
263
				// global toolbar of the workbench
264
				return new Path(MacroConstants.TOOLBAR_VALUE).toString(); //$NON-NLS-1$
265
			} else if (macroObject.getContext() instanceof ToolBar) {
266
				// Local toolbar somewhere - locate the parent first and use its
267
				// IMacroObjectIdentifier as
268
				// context, as in case of the LOCAL_TOOLBAR_MENU_VALUE
269
				ToolBar toolBar = (ToolBar) macroObject.getContext();
270
				IMacroObjectIdentifier toolBarIdentifier = resolve(shell,
271
						new MacroObject(new UIObject(toolBar)));
272
				if (toolBarIdentifier != null) {
273
					return new Path(MacroConstants.LOCAL_TOOLBAR_VALUE)
274
							.append(
275
									MacroObjectIdentifier
276
											.serializeMacroObjectIdentifier(toolBarIdentifier))
277
							.toString(); //$NON-NLS-1$
278
				} else {
279
					return null;
280
				}
281
			} else {
282
				return null;
283
			}
284
		} else if (widget instanceof TabItem || widget instanceof CTabItem) {
285
			IMacroObjectIdentifier tabFolderIdentifier = null;
286
			if (widget instanceof TabItem) {
287
				TabFolder tabFolder = (TabFolder) macroObject.getContext();
288
				tabFolderIdentifier = resolve(shell, new MacroObject(
289
						new UIObject(tabFolder)));
290
			} else {
291
				CTabFolder tabFolder = (CTabFolder) macroObject.getContext();
292
				tabFolderIdentifier = resolve(shell, new MacroObject(
293
						new UIObject(tabFolder)));
294
			}
295
			if (tabFolderIdentifier != null) {
296
				return new Path(MacroConstants.TAB_VALUE)
297
						.append(
298
								MacroObjectIdentifier
299
										.serializeMacroObjectIdentifier(tabFolderIdentifier))
300
						.toString();
301
			}
302
303
		} else if (widget instanceof Menu) {
304
			// it seems that menus are never resolved (as the deresolver does
305
			// not have any capability to deresolve them)
306
			AutoGUIUtil
307
					.throwCoreException("Menus are not suppported by current implementation");
308
			// return new Path(MacroConstants.MENUS_VALUE).toString();
309
		} else if (widget instanceof Control) {
310
			return resolveControlContextIdentifier(macroObject);
311
		}
312
		return null;
313
	}
314
315
	private static String resolveControlContextIdentifier(
316
			IMacroObject macroObject) {
317
		if (macroObject.getContext() instanceof WizardDialog) {
318
			return new Path(MacroConstants.WIZARD_VALUE).toString();
319
		} else if (macroObject.getContext() instanceof IWizardPage) {
320
			return new Path(MacroConstants.WIZARD_PAGE_VALUE).append(
321
					((IWizardPage) macroObject.getContext()).getName())
322
					.toString();
323
		} else if (macroObject.getContext() instanceof IWorkbenchPart) {
324
			IWorkbenchPart part = (IWorkbenchPart) macroObject.getContext();
325
			if (part instanceof IViewPart) {
326
				return new Path(MacroConstants.VIEW_VALUE).append(
327
						part.getSite().getId()).toString();
328
			} else if (part instanceof IEditorPart) {
329
				String inputName = ((IEditorPart) part).getEditorInput()
330
						.getName();
331
				return new Path(MacroConstants.EDITOR_VALUE).append(
332
						part.getSite().getId()).append(inputName).toString();
333
			} else {
334
				return null;
335
			}
336
		} else if (macroObject.getContext() instanceof Shell) {
337
			return new Path(MacroConstants.SHELL_VALUE).toString();
338
		} else {
339
			return null;
340
		}
341
	}
342
343
	/**
344
	 * TODO: split deresolving of context object from deresolving of UI object,
345
	 * which has to be done by UIObjectResolver....
346
	 * 
347
	 * @param shell
348
	 * @param macroObjectIdentifier
349
	 * @param parents
350
	 * @return
351
	 * @throws CoreException
352
	 */
353
	public static IMacroObject deresolve(Shell shell,
354
			IMacroObjectIdentifier macroObjectIdentifier) throws CoreException {
355
		String contextId = macroObjectIdentifier.getContextIdentifier();
356
357
		String firstToken = new Path(contextId).segment(0);
358
		String id = new Path(contextId).segment(1);
359
360
		Object context = null;
361
362
		if (MacroConstants.MENUS_VALUE.equals(firstToken)) {
363
			context = findMenuContext(shell, macroObjectIdentifier);
364
		} else if (MacroConstants.POPUP_VALUE.equals(firstToken)) {
365
			context = findPopupMenuItemContext(shell, macroObjectIdentifier);
366
		} else if (MacroConstants.TOOLBAR_VALUE.equals(firstToken)) {
367
			context = findToolItemContext(shell, macroObjectIdentifier);
368
		} else if (MacroConstants.LOCAL_TOOLBAR_VALUE.equals(firstToken)) {
369
			context = findLocalToolItemContext(shell, macroObjectIdentifier);
370
		} else if (MacroConstants.LOCAL_TOOLBAR_MENU_VALUE.equals(firstToken)) {
371
			context = findToolBarMenuItemContext(shell, macroObjectIdentifier);
372
		} else if (MacroConstants.TAB_VALUE.equals(firstToken)) {
373
			// ANy: added to properly deresolve TabItems and CTabItems (was done
374
			// locally by commands before)
375
			context = findTabItemContext(shell, macroObjectIdentifier);
376
		} else if (MacroConstants.WIZARD_VALUE.equals(firstToken)) {
377
			context = findWizardContext(shell, macroObjectIdentifier);
378
		} else if (MacroConstants.WIZARD_PAGE_VALUE.equals(firstToken)) {
379
			context = findWizardPageContext(shell, id, macroObjectIdentifier);
380
		} else if (MacroConstants.VIEW_VALUE.equals(firstToken)) {
381
			context = findViewContext(shell, id, macroObjectIdentifier);
382
		} else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) {
383
			String inputName = new Path(contextId).segment(2);
384
			context = findEditorContext(shell, id, inputName,
385
					macroObjectIdentifier);
386
		} else if (MacroConstants.SHELL_VALUE.equals(firstToken)) {
387
			context = shell;
388
		}
389
		// else if (MacroConstants.LOCAL_SHELL_VALUE.equals(firstToken)) {
390
		// context = shell.getData();
391
		// }
392
393
		if (context != null) {
394
			IUIObject uiObject = UIObjectResolver.deresolve(context,
395
					macroObjectIdentifier.getObjectIdentifier());
396
			if (uiObject != null) {
397
				return new MacroObject(context, uiObject);
398
			} else {
399
				return null;
400
			}
401
		}
402
		return null;
403
	}
404
405
	private static Object findTabItemContext(Shell shell,
406
			IMacroObjectIdentifier macroObjectIdentifier) throws CoreException {
407
		IPath contextPath = new Path(macroObjectIdentifier
408
				.getContextIdentifier()).removeFirstSegments(1);
409
410
		IMacroObjectIdentifier tabFolderIdentifier = MacroObjectIdentifier
411
				.deserializeMacroObjectIdentifier(contextPath.toString());
412
		IMacroObject tabFolder = deresolve(shell, tabFolderIdentifier);
413
414
		if (tabFolder != null) {
415
			return tabFolder.getUIObject().getWidget();
416
		}
417
		return null;
418
	}
419
420
	private static Object findEditorContext(Shell shell, String id,
421
			String inputName, IMacroObjectIdentifier wid) throws CoreException {
422
		UIObject control = null;
423
424
		try {
425
			IEditorPart editor = MacroUtil.locateEditor(shell, id, inputName);
426
			return editor;
427
		} catch (Throwable t) {
428
			t.printStackTrace();
429
		}
430
		return null;
431
	}
432
433
	private static Object findLocalToolItemContext(Shell shell,
434
			IMacroObjectIdentifier wid) throws CoreException {
435
		// construct a IMacroObjectIdentifier for the toolbar
436
		// by splitting the context id.
437
438
		// 1) truncate the leading MacroConstants.LOCAL_TOOLBAR_MENU_VALUE
439
		// segment
440
		IPath wpath = new Path(wid.getContextIdentifier())
441
				.removeFirstSegments(1);
442
443
		IMacroObjectIdentifier toolBarIdentifier = MacroObjectIdentifier
444
				.deserializeMacroObjectIdentifier(wpath.toString());
445
446
		// now try to deresolve the toolbar with the given identifier
447
		ToolBar toolbar = null;
448
		try {
449
			IMacroObject toolbarObject = deresolve(shell, toolBarIdentifier);
450
			if (toolbarObject != null) {
451
				toolbar = (ToolBar) toolbarObject.getUIObject().getWidget();
452
			}
453
		} catch (Throwable t) {
454
			t.printStackTrace();
455
		}
456
		return toolbar;
457
		// try{
458
		// String firstToken = wpath.segment(0);
459
		// IWorkbenchPart workbenchPart = null;
460
		// Composite parent = null;
461
		// IMacroObject target = null;
462
		//
463
		// if (MacroConstants.VIEW_VALUE.equals(firstToken)) {
464
		// String id = wpath.segment(1);
465
		// workbenchPart = MacroUtil.locateView(shell, id);
466
		// } else if (MacroConstants.EDITOR_VALUE.equals(firstToken)) {
467
		// String id = wpath.segment(1);
468
		// workbenchPart = MacroUtil.locateEditor(shell, id, null);
469
		// } else if (MacroConstants.SHELL_VALUE.equals(firstToken)) {
470
		// parent = shell;
471
		// }
472
		//
473
		// if (workbenchPart != null) {
474
		// Composite comp = MacroUtil
475
		// .getWorkbenchPartControl(workbenchPart);
476
		// MacroUtil.processDisplayEvents(shell.getDisplay());
477
		// parent = comp.getParent();
478
		// }
479
		//
480
		// if (parent != null) {
481
		// IMacroObjectIdentifier widgetIdentifier = new MacroObjectIdentifier(
482
		// wid.getContextIdentifier(),
483
		// new PrimitiveUIObjectIdentifier(new Path(wid
484
		// .getContextIdentifier()).lastSegment(), wid
485
		// .getObjectIdentifier().getResolverId()));
486
		// UIObject control = UIObjectDeprecatedDeresolvingSupport
487
		// .locateVisibleChild(parent, null, widgetIdentifier);
488
		//
489
		// if (control != null && control.getWidget() instanceof ToolBar) {
490
		// target = locateToolItem((ToolBar) control.getWidget(), wid);
491
		// }
492
		// }
493
		//
494
		// if (target != null)
495
		// return target;
496
		//
497
		// } catch (Throwable t) {
498
		// /* The next line will throw an exception */
499
		// t.printStackTrace();
500
		// }
501
		//
502
		// AutoGUIUtil.throwCoreException(NLS.bind(
503
		// AutoGUIMessages.AUTO_GUI_ERROR_MACRO_TOOL_BAR, wid
504
		// .getContextIdentifier()
505
		// + wid.getObjectIdentifier().getObjectId()));
506
		// return null;
507
	}
508
509
	private static Object findMenuContext(Shell shell,
510
			IMacroObjectIdentifier wid) throws CoreException {
511
		Menu menuBar = shell.getMenuBar();
512
		return menuBar;
513
	}
514
515
	// private static MenuItem locateMenuItem(MenuManager mng,
516
	// IMacroObjectIdentifier widgetId) {
517
	// IContributionItem[] items = mng.getItems();
518
	//		
519
	// String lastSegment = getLastSegment(new
520
	// Path(widgetId.getObjectIdentifier().getObjectId()));
521
	// String parentId = null;
522
	//
523
	// for (int i = 0; i < items.length; i++) {
524
	// IContributionItem citem = items[i];
525
	//
526
	// if (citem instanceof MenuManager) {
527
	// MenuManager submenu = (MenuManager) citem;
528
	// String subId = submenu.getId();
529
	//				
530
	// if (subId.equals(parentId))
531
	// {
532
	//
533
	// // show this menu to force dynamic items
534
	// // to show
535
	// Menu menu = submenu.getMenu();
536
	// forceMenuOpen(null, menu);
537
	//
538
	// MenuItem hit = locateMenuItem(submenu, widgetId);
539
	// forceMenuClosed(menu);
540
	// if (hit != null)
541
	// return hit;
542
	// }
543
	//
544
	// } else {
545
	// /*
546
	// * Ali M.: I believe that the first line and the following block
547
	// * were for optimization purposes only
548
	// */
549
	// String itemId =
550
	// NonTrivialUIObjectResolverDelegate.getActionId(citem).getObjectId();
551
	// if (itemId != null &&
552
	// widgetId.getObjectIdentifier().getObjectId().equals(itemId)) {
553
	// MenuItem hit = locateMenuItem(mng.getMenu(), widgetId);
554
	// if (hit != null)
555
	// return hit;
556
	// }
557
	// }
558
	// }
559
	// return null;
560
	// }
561
562
	private static Object findPopupMenuItemContext(Shell shell,
563
			IMacroObjectIdentifier wid) throws CoreException {
564
		// try {
565
566
		IPath contextPath = new Path(wid.getContextIdentifier())
567
				.removeFirstSegments(1);
568
569
		IMacroObjectIdentifier focusControlIdentifier = MacroObjectIdentifier
570
				.deserializeMacroObjectIdentifier(contextPath.toString());
571
		IMacroObject focusControlObject = deresolve(shell,
572
				focusControlIdentifier);
573
574
		if (focusControlObject != null) {
575
			Control control = (Control) focusControlObject.getUIObject()
576
					.getWidget();
577
			Menu popupMenu = control.getMenu();
578
			return popupMenu;
579
		} else {
580
			return null;
581
		}
582
583
		// IPath wpath = new Path(getLastSegment(contextPath));
584
		//
585
		// int widgetPathInx = contextPath.toString()
586
		// .indexOf(wpath.toString());
587
		// if (widgetPathInx > 0)
588
		// contextPath = new Path(contextPath.toString().substring(0,
589
		// widgetPathInx - 1));
590
		// IMacroObject target = deresolve(shell, new MacroObjectIdentifier(
591
		// contextPath.toString(), new PrimitiveUIObjectIdentifier(
592
		// wpath.toString(), null)));
593
		// if (target != null) {
594
		// // for (int i = 0; i < targets.length; i++) {
595
		// Control control = (Control) target.getUIObject().getWidget();
596
		// Menu popupMenu = control.getMenu();
597
		// if (popupMenu != null) {
598
		// MacroUtil.forceMenuOpen(popupMenu);
599
		// UIObject menuItem = locateMenuItem(popupMenu, wid
600
		// .getObjectIdentifier());
601
		// MacroUtil.forceMenuClosed(popupMenu);
602
		// if (menuItem != null) {
603
		// return new MacroObject(control, menuItem);
604
		// }
605
		// }
606
		// // }
607
		// }
608
		// } catch (Throwable t) {
609
		// /* The next line will throw an exception */
610
		// t.printStackTrace();
611
		// }
612
		// AutoGUIUtil.throwCoreException(NLS.bind(
613
		// AutoGUIMessages.AUTO_GUI_ERROR_MACRO_MENU, wid
614
		// .getObjectIdentifier().getObjectId()));
615
		// return null;
616
	}
617
618
	private static Object findToolBarMenuItemContext(Shell shell,
619
			IMacroObjectIdentifier wid) throws CoreException {
620
		// try {
621
		IPath contextPath = new Path(wid.getContextIdentifier())
622
				.removeFirstSegments(1);
623
624
		/* The context is a menu */
625
		IViewPart view = null;
626
		if (MacroConstants.VIEW_VALUE.equals(contextPath.segment(0))) {
627
			view = MacroUtil.locateView(shell, contextPath.segment(1));
628
		}
629
630
		IViewSite viewSite = view == null ? null : view.getViewSite();
631
		IMenuManager menuManager = null;
632
		if (viewSite != null) {
633
			IActionBars actionBar = viewSite.getActionBars();
634
			actionBar.updateActionBars();
635
			menuManager = actionBar.getMenuManager();
636
		}
637
638
		if (menuManager != null && menuManager instanceof MenuManager) {
639
			Menu menu = ((MenuManager) menuManager).getMenu();
640
			if (menu == null) {
641
				// try to create menu
642
				((MenuManager) menuManager).createMenuBar((Decorations) view
643
						.getSite().getShell());
644
			}
645
			return menu;
646
		} else {
647
			return null;
648
		}
649
	}
650
651
	private static String getLastSegment(IPath contextPath) {
652
		String[] segments = contextPath.segments();
653
		String candidate = "";
654
		for (int i = segments.length - 1; i >= 0; i--) {
655
			if (candidate.length() > 0)
656
				candidate = "/" + candidate;
657
			candidate = segments[i] + candidate;
658
			int openingBracesInx = candidate.indexOf('{');
659
			int closingBracesInx = candidate.indexOf('}');
660
			if ((openingBracesInx == -1 && closingBracesInx == -1)
661
					|| (openingBracesInx >= 0 && openingBracesInx < closingBracesInx))
662
				return candidate;
663
		}
664
665
		return "";
666
	}
667
668
	// private static IMacroObject locateShellControl(Shell shell,
669
	// IMacroObjectIdentifier wid) throws CoreException {
670
	// UIObject control = null;
671
	// Window window = null;
672
	// boolean ambiguous = false;
673
	// try {
674
	// window = (Window) shell.getData();
675
	// control = UIObjectDeprecatedDeresolvingSupport.locateVisibleChild(
676
	// shell, null, wid);
677
	// } catch (Throwable t) {
678
	// if (t instanceof CoreException) {
679
	// AutoGUIUtil.throwCoreException(NLS.bind(
680
	// AutoGUIMessages.AUTO_GUI_MACRO_UI_OBJECT_AMBIGUOUS, wid
681
	// .getObjectIdentifier(), wid
682
	// .getContextIdentifier()));
683
	// }
684
	// }
685
	// if (control == null)
686
	// AutoGUIUtil.throwCoreException(NLS.bind(
687
	// AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL, wid
688
	// .getObjectIdentifier().getObjectId()));
689
	//
690
	// // IMacroObject[] windowCommandTarget = new
691
	// // IMacroObject[controls.length];
692
	// // for (int i = 0; i < controls.length; i++) {
693
	// // if (controls[i].isDisposed())
694
	// // AutoGUIUtil.throwCoreException(NLS.bind(
695
	// // AutoGUIMessages.AUTO_GUI_ERROR_MACRO_SHELL_DIS, wid
696
	// // .getObjectIdentifier().getObjectId()));
697
	// // windowCommandTarget[i] = new MacroObject(window, new UIObject(
698
	// // controls[i]));
699
	// // }
700
	// //
701
	// // return windowCommandTarget;
702
	// return new MacroObject(window, control);
703
	// }
704
705
	private static Object findToolItemContext(Shell shell,
706
			IMacroObjectIdentifier wid) throws CoreException {
707
708
		try {
709
			Object data = shell.getData();
710
			if (data instanceof ApplicationWindow) {
711
				ApplicationWindow window = (ApplicationWindow) data;
712
				CoolBarManager coolMng = window.getCoolBarManager();
713
				if (coolMng != null) {
714
					return coolMng;
715
				}
716
				ToolBarManager toolMng = window.getToolBarManager();
717
				if (toolMng != null) {
718
					return toolMng;
719
				}
720
			}
721
		} catch (Throwable t) {
722
			t.printStackTrace();
723
		}
724
		return null;
725
	}
726
727
	private static Object findViewContext(Shell shell, String id,
728
			IMacroObjectIdentifier wid) throws CoreException {
729
		try {
730
			IViewPart view = MacroUtil.locateView(shell, id);
731
			return view;
732
		} catch (Throwable t) {
733
			t.printStackTrace();
734
		}
735
		return null;
736
	}
737
738
	private static Object findWizardContext(Shell shell,
739
			IMacroObjectIdentifier wid) throws CoreException {
740
		WizardDialog wdialog = null;
741
		if (shell.getData() instanceof WizardDialog) {
742
			wdialog = (WizardDialog) shell.getData();
743
			Assert
744
					.isLegal(
745
							wdialog.getShell() == shell,
746
							"If the current shell is not the shell of the wizard, we have a deresolving problem");
747
		}
748
		return wdialog;
749
	}
750
751
	private static Object findWizardPageContext(Shell shell, String id,
752
			IMacroObjectIdentifier wid) throws CoreException {
753
		IWizardPage page = null;
754
		Object data = shell.getData();
755
		if (data instanceof WizardDialog) {
756
			WizardDialog wdialog = (WizardDialog) data;
757
			page = wdialog.getCurrentPage();
758
		}
759
		return page;
760
761
	}
762
763
}

Return to bug 133099