001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.test.umllib;
043:
044: import java.awt.Color;
045: import java.awt.Font;
046: import java.awt.Point;
047: import java.awt.Rectangle;
048: import java.awt.event.InputEvent;
049: import java.awt.event.KeyEvent;
050: import java.util.ArrayList;
051: import java.util.Iterator;
052: import org.netbeans.jellytools.MainWindowOperator;
053: import org.netbeans.jemmy.JemmyProperties;
054: import org.netbeans.jemmy.Timeouts;
055: import org.netbeans.jemmy.Waitable;
056: import org.netbeans.jemmy.Waiter;
057: import org.netbeans.jemmy.operators.JPopupMenuOperator;
058: import org.netbeans.modules.uml.core.support.umlsupport.ETDeviceRect;
059: import org.netbeans.modules.uml.core.support.umlsupport.ETRect;
060: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
061: import org.netbeans.modules.uml.core.support.umlutils.ETList;
062: import org.netbeans.modules.uml.ui.products.ad.drawengines.ETNodeDrawEngine;
063: import org.netbeans.modules.uml.ui.products.ad.drawengines.INodeDrawEngine;
064: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ETRectEx;
065: import org.netbeans.modules.uml.ui.support.viewfactorysupport.ICompartment;
066: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IListCompartment;
067: import org.netbeans.test.umllib.actions.Actionable;
068: import org.netbeans.test.umllib.exceptions.NotFoundException;
069: import org.netbeans.test.umllib.util.JPopupByPointChooser;
070:
071: /**
072: * This is operator for "compartment". Compartment in
073: * ETI terms means subsection of some diagram element. For example:
074: * <B>Attributes compartment</B>
075: * <B>Operations compartment</B>
076: * <B>Name compartment</B>
077: */
078: public class CompartmentOperator implements Actionable {
079:
080: /**
081: * Default delay for Compartment Waiter. Real value can be changed
082: * as for the all other operators(For example via JemmyProperties)
083: */
084: public static final long WAIT_COMPARTMENT_TIMEOUT = 5000;
085:
086: static {
087: Timeouts.initDefault("CompartmentOperator.WaitCompartmentTime",
088: WAIT_COMPARTMENT_TIMEOUT);
089: }
090:
091: protected DiagramElementOperator sourceElement = null;
092: protected ICompartment sourceCompartment = null;
093:
094: /**
095: *
096: * @return
097: */
098: public ICompartment getSource() {
099: return sourceCompartment;
100: }
101:
102: /**
103: *
104: * @return
105: */
106: public DiagramElementOperator getElement() {
107: return sourceElement;
108: }
109:
110: /**
111: * Construct compartment by index
112: * @param el Instance of DiagramElementOperator to look for compartment
113: * @param index index
114: * @throws qa.uml.exceptions.NotFoundException when no suitable compartment found
115: */
116: public CompartmentOperator(DiagramElementOperator el, int index)
117: throws NotFoundException {
118: this (el, waitForCompartment(el, new AnyCompartmentChooser(),
119: index));
120: }
121:
122: /**
123: * Costruct compartment by type
124: * @param el Instance of DiagramElementOperator to look for compartment
125: * @param type Compartemnt type.
126: * @throws qa.uml.exceptions.NotFoundException when no suitable compartment found
127: * @see qa.uml.CompartmentTypes
128: */
129: public CompartmentOperator(DiagramElementOperator el,
130: CompartmentTypes type) throws NotFoundException {
131: this (el, waitForCompartment(el, new CompartmentByTypeChooser(
132: type), 0));
133: }
134:
135: /**
136: * Construct compartment by compartment class
137: * @param el Instance of DiagramElementOperator
138: * @param co Instance of ICompartment
139: */
140: public CompartmentOperator(DiagramElementOperator el,
141: ICompartment co) {
142: sourceElement = el;
143: sourceCompartment = co;
144: }
145:
146: /**
147: *method return name of comparment from compartment source
148: *@return compartmant name
149: */
150: public String getName() {
151: return sourceCompartment.getName();
152: }
153:
154: /**
155: * Wait for suitable compartment
156: * @param source DiagramElementOperator to look in
157: * @param chooser Custom chooser
158: * @param index index
159: * @throws qa.uml.exceptions.NotFoundException When now suitable compartment found
160: * @return CompartmentOperator if found
161: */
162: public static ICompartment waitForCompartment(
163: final DiagramElementOperator source,
164: final CompartmentChooser chooser, final int index)
165: throws NotFoundException {
166: try {
167: Waiter w = new Waiter(new Waitable() {
168: public Object actionProduced(Object obj) {
169: return findCompartment(source, chooser, index);
170: }
171:
172: public String getDescription() {
173: return ("Wait for " + chooser.getDescription());
174: }
175: });
176:
177: Timeouts t = JemmyProperties.getCurrentTimeouts();
178: t
179: .setTimeout(
180: "Waiter.WaitingTime",
181: t
182: .getTimeout("CompartmentOperator.WaitCompartmentTime"));
183:
184: ICompartment c = (ICompartment) w.waitAction(null);
185: if (c != null) {
186: return c;
187: }
188:
189: throw new NotFoundException(
190: "Matching compartment was not found.");
191: } catch (InterruptedException ie) {
192: throw new NotFoundException(
193: "Compartment was not found due to runtime error.");
194: }
195: }
196:
197: /**
198: * Search for suitable compartment
199: * @param source DiagramElementOperator to look in
200: * @param chooser Custom chooser
201: * @param index index
202: * @return CompartmentOperator if found
203: */
204: public static ICompartment findCompartment(
205: DiagramElementOperator source, CompartmentChooser chooser,
206: int index) {
207: if ((source == null) || (chooser == null)) {
208: return null;
209: }
210:
211: ETList<ICompartment> compartments = source.getGraphObject()
212: .getEngine().getCompartments();
213: if (compartments == null) {
214: return null;
215: }
216:
217: Iterator<ICompartment> it = compartments.iterator();
218: ArrayList<ICompartment> compartmentsFound = new ArrayList<ICompartment>();
219: while (it.hasNext()) {
220: ICompartment co = it.next();
221: if (chooser.checkCompartment(co)) {
222: compartmentsFound.add(co);
223: }
224: compartmentsFound.addAll(getCompartments(chooser, co));
225: }
226:
227: if (compartmentsFound.size() > index) {
228: return compartmentsFound.toArray(new ICompartment[1])[index];
229: }
230: return null; //Nothing suitable found
231:
232: }
233:
234: /**
235: * Return list of all sub compartmens
236: * @return list of sub compartmens
237: */
238: public ArrayList<CompartmentOperator> getCompartments() {
239: return getCompartments(new AnyCompartmentChooser());
240: }
241:
242: /**
243: * Returns all sub compartments accepted by the specified chooser
244: * @param chooser to be used for compartment selection
245: * @return list of sub compartments
246: */
247: public ArrayList<CompartmentOperator> getCompartments(
248: CompartmentChooser chooser) {
249: ArrayList<ICompartment> iComps = CompartmentOperator
250: .getCompartments(chooser, sourceCompartment);
251: ArrayList<CompartmentOperator> comps = new ArrayList<CompartmentOperator>();
252: for (int i = 0; i < iComps.size(); i++) {
253: comps.add(new CompartmentOperator(sourceElement, iComps
254: .get(i)));
255: }
256: return comps;
257: }
258:
259: /**
260: * Returns list of sub compartmens
261: * @return list of sub compartmens
262: * @param chooser Custom chooser
263: * @param parentCompartment Parent Compartment
264: */
265: private static ArrayList<ICompartment> getCompartments(
266: CompartmentChooser chooser, ICompartment parentCompartment) {
267: ArrayList<ICompartment> compartmentsFound = new ArrayList<ICompartment>();
268: if (parentCompartment instanceof IListCompartment) {
269: ETList<ICompartment> compartments = ((IListCompartment) parentCompartment)
270: .getCompartments();
271: if (compartments == null) {
272: return compartmentsFound;
273: }
274: Iterator<ICompartment> it = compartments.iterator();
275: while (it.hasNext()) {
276: ICompartment co = it.next();
277: if (chooser.checkCompartment(co)) {
278: compartmentsFound.add(co);
279: }
280: compartmentsFound.addAll(getCompartments(chooser, co));
281: }
282: return compartmentsFound;
283: } else {
284: return compartmentsFound;
285: }
286: }
287:
288: //Methods from Actionable interface
289: /**
290: * Invokes popup menu and returns JPopupMenuOperator
291: * @return JPopupMenuOperator
292: */
293: public JPopupMenuOperator getPopup() {
294: //workarround for Issue 79519
295: if (System.getProperty("os.name").toLowerCase().indexOf(
296: "windows") == -1) {
297: clickOnCenter();
298: try {
299: Thread.sleep(100);
300: } catch (Exception ex) {
301: }
302: }
303: clickForPopup();
304:
305: JPopupMenuOperator ret = new JPopupMenuOperator(
306: JPopupMenuOperator.waitJPopupMenu(
307: (java.awt.Container) (MainWindowOperator
308: .getDefault().getSource()),
309: new JPopupByPointChooser(getCenterPoint(),
310: sourceElement.getDiagram()
311: .getDrawingArea().getSource(),
312: 0)));
313: return ret;
314: }
315:
316: /**
317: * Click on this compartment
318: */
319: public void select() {
320: }
321:
322: /**
323: * Add this compartment to selection by clicking on it with
324: * CTRL pressed
325: */
326: public void addToSelection() {
327: }
328:
329: /**
330: * Returns center point of this compartment
331: * @return center point of this compartment
332: */
333: public Point getCenterPoint() {
334: Point centerPoint = new Point(
335: (int) getRectangle().getCenterX(), (int) getRectangle()
336: .getCenterY());
337: return centerPoint;
338: }
339:
340: /**
341: * Returns left horizontal, center vertical point of this compartment
342: * @param shift - shift from left border
343: * @return left horizontal, center vertical point of this compartment
344: */
345: public Point getLeftCenterPoint(int shift) {
346: Rectangle rect = getRectangle();
347: return new Point(rect.x + shift, (int) rect.getCenterY());
348: }
349:
350: /**
351: * Returns left horizontal, center vertical point of this compartment
352: * with default shift from left border
353: * @return left horizontal, center vertical point of this compartment
354: */
355: public Point getLeftCenterPoint() {
356: return getLeftCenterPoint(10);
357: }
358:
359: /**
360: *
361: * @return bounding rectangle for compartment
362: */
363: public Rectangle getRectangle() {
364: //return sourceElement.getDiagram().getDrawingAreaControl().logicalToDeviceRect(sourceCompartment.getEngine().getLogicalBoundingRect(true)).getRectangle();
365:
366: IETRect tmpRect = sourceCompartment.getBoundingRect();
367: ETDeviceRect tmpDevRect = null;
368: int x, y;
369: //transform to device coordinates
370: if (tmpRect instanceof ETRect || tmpRect instanceof ETRectEx) {
371: // This special case is for all the code that depends
372: // on the bounding rectangle in device coordinates.
373: tmpDevRect = ((ETRect) tmpRect).getAsDeviceRect();
374: } else if (tmpRect instanceof ETDeviceRect) {
375: tmpDevRect = ((ETDeviceRect) tmpRect);
376: }
377: return tmpDevRect.getBounds();
378: }
379:
380: /**
381: * Click on this compartment
382: * @param clickCount count
383: * @param mouseButton mouse button. Use constants from InputEvent
384: * @param modifiers Key modifiers. Use contants from KeyEvent
385: */
386: public void clickOnCenter(int clickCount, int mouseButton,
387: int modifiers) {
388: sourceElement.clickOn(getCenterPoint(), clickCount,
389: mouseButton, modifiers);
390: }
391:
392: /**
393: * Click on this compartment
394: * @param clickCount click count: 1,2 ..
395: * @param mouseButton Mouse button to click. Use constants from InputEvent
396: */
397: public void clickOnCenter(int clickCount, int mouseButton) {
398: clickOnCenter(clickCount, mouseButton, 0);
399: }
400:
401: /**
402: * Click on this compartmnet by left mouse button
403: */
404: public void clickOnCenter() {
405: clickOnCenter(1, InputEvent.BUTTON1_MASK);
406: }
407:
408: /**
409: * Click on this compartment by right mouse button
410: */
411: public void clickForPopup() {
412: clickOnCenter(1, InputEvent.BUTTON3_MASK);
413: }
414:
415: /**
416: * Click on this compartment
417: * @param clickCount count
418: * @param mouseButton mouse button. Use constants from InputEvent
419: * @param modifiers Key modifiers. Use contants from KeyEvent
420: */
421: public void clickOnLeftCenter(int clickCount, int mouseButton,
422: int modifiers) {
423: sourceElement.clickOn(getLeftCenterPoint(), clickCount,
424: mouseButton, modifiers);
425: }
426:
427: /**
428: * Click on this compartment
429: * @param clickCount click count: 1,2 ..
430: * @param mouseButton Mouse button to click. Use constants from InputEvent
431: */
432: public void clickOnLeftCenter(int clickCount, int mouseButton) {
433: clickOnLeftCenter(clickCount, mouseButton, 0);
434: }
435:
436: /**
437: * Click on this compartmnet by left mouse button
438: */
439: public void clickOnLeftCenter() {
440: clickOnLeftCenter(1, InputEvent.BUTTON1_MASK);
441: }
442:
443: /**
444: * Click on this compartment by right mouse button
445: */
446: public void clickleftForPopup() {
447: clickOnLeftCenter(1, InputEvent.BUTTON3_MASK);
448: }
449:
450: /**
451: * Returns Font of text in this compartment
452: * @return Font of text in this compartment
453: */
454: public Font getFont() {
455: return sourceCompartment.getCompartmentFont(sourceElement
456: .getDiagram().getDrawingAreaControl().getCurrentZoom());
457: }
458:
459: /**
460: * Returns Color of text in this compartment
461: * @return Color of text in this compartment
462: */
463: public Color getFontColor() {
464: return sourceCompartment.getCompartmentFontColor();
465: }
466:
467: /**
468: *
469: * @return
470: */
471: public Color getBorderColor() {
472: try {
473: INodeDrawEngine engine = (INodeDrawEngine) sourceCompartment
474: .getEngine();
475: return engine.getBorderColor();
476: } catch (Exception e) {
477: return null;
478: }
479: }
480:
481: /**
482: * Returns background color using standard method getFillColor provided by interface IDrawEngine
483: * <br> Problem is that this method returns FillColor variable for all elements.
484: * But 'backgroung color' changed by user is saved to different variables for different elements
485: * <br> look also at getFillColor() and getLightGradientFillColor()
486: *
487: * @return Color background color
488: */
489: public Color getBackgroundColor() {
490: try {
491: INodeDrawEngine engine = (INodeDrawEngine) sourceCompartment
492: .getEngine();
493: return engine.getFillColor();
494: } catch (Exception e) {
495: return null;
496: }
497: }
498:
499: /**
500: * Returns Fill color using method getFillColor provided by ETNodeDrawEngine.
501: *
502: * @return Color background fill color
503: */
504: public Color getFillColor() {
505: try {
506: ETNodeDrawEngine engine = (ETNodeDrawEngine) sourceCompartment
507: .getEngine();
508: return engine.getFillColor();
509: } catch (Exception e) {
510: return null;
511: }
512: }
513:
514: /**
515: * Returns Fill color using method getLightGradientFillColor provided by ETNodeDrawEngine
516: *
517: * @return Color light gradient background fill color
518: */
519: public Color getLightGradientFillColor() {
520: try {
521: ETNodeDrawEngine engine = (ETNodeDrawEngine) sourceCompartment
522: .getEngine();
523: return engine.getLightGradientFillColor();
524: } catch (Exception e) {
525: return null;
526: }
527: }
528:
529: /**
530: * Select compartmnet by type
531: */
532: public static class CompartmentByTypeChooser implements
533: CompartmentChooser {
534:
535: private Class clazz = null;
536:
537: /**
538: * Select compartment by type
539: * @param compType compartment type
540: */
541: public CompartmentByTypeChooser(CompartmentTypes compType) {
542: try {
543: this .clazz = Class.forName(compType.toString());
544: } catch (Exception e) {
545: clazz = null;
546: }
547: }
548:
549: /**
550: * Check param by it's type
551: * @param co Compartment to check
552: * @return true if suitable and false otherwise
553: */
554: public boolean checkCompartment(ICompartment co) {
555: return (clazz != null && clazz.isInstance(co));
556: }
557:
558: /**
559: * Returns description of this chooser
560: * @return description of this chooser
561: */
562: public String getDescription() {
563: return "Chooser that accepts compartments of specific type ";
564: }
565:
566: }
567:
568: /**
569: * Select compartmnet by name
570: */
571: public static class CompartmentByNameChooser implements
572: CompartmentChooser {
573:
574: private String name = null;
575:
576: /**
577: * Select compartment by name
578: * @param compname
579: */
580: public CompartmentByNameChooser(String compname) {
581: this .name = compname;
582: }
583:
584: /**
585: * Check param by it's name
586: * @param co Compartment to check
587: * @return true if suitable and false otherwise
588: */
589: public boolean checkCompartment(ICompartment co) {
590: return name.equals(co.getName());
591: }
592:
593: /**
594: * Returns description of this chooser
595: * @return description of this chooser
596: */
597: public String getDescription() {
598: return "Chooser that accepts compartments with specific name ";
599: }
600:
601: }
602:
603: /**
604: * Any compartment chooser. Used for looking by index.
605: */
606: public static class AnyCompartmentChooser implements
607: CompartmentChooser {
608:
609: /**
610: * Any Compartment chooser. Selects any compartments
611: */
612: public AnyCompartmentChooser() {
613: }
614:
615: /**
616: * Check compartment
617: * @param co Compartment to check
618: * @return Always true
619: */
620: public boolean checkCompartment(ICompartment co) {
621: return true;
622: }
623:
624: /**
625: * Returns short description
626: * @return Description
627: */
628: public String getDescription() {
629: return "Chooser that accepts any compartment ";
630: }
631:
632: }
633:
634: }
|