0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: /*
0043: * LinkOperator.java
0044: *
0045: * Created on February 15, 2005, 6:42 PM
0046: */
0047:
0048: package org.netbeans.test.umllib;
0049:
0050: import java.awt.Container;
0051: import java.awt.Point;
0052: import java.awt.event.InputEvent;
0053: import java.awt.event.KeyEvent;
0054:
0055: import java.util.ArrayList;
0056: import java.util.Comparator;
0057:
0058: import java.util.HashSet;
0059: import java.util.Iterator;
0060: import java.util.List;
0061:
0062: import java.util.TreeSet;
0063: import javax.swing.JPopupMenu;
0064: import org.netbeans.jellytools.MainWindowOperator;
0065: import org.netbeans.jemmy.EventTool;
0066:
0067: import org.netbeans.jemmy.JemmyProperties;
0068:
0069: import com.tomsawyer.drawing.geometry.TSConstPoint;
0070: import org.netbeans.jemmy.Timeout;
0071: import org.netbeans.jemmy.Timeouts;
0072: import org.netbeans.jemmy.Waitable;
0073: import org.netbeans.jemmy.Waiter;
0074: import org.netbeans.jemmy.operators.JPopupMenuOperator;
0075: import org.netbeans.jemmy.operators.Operator;
0076: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0077: import org.netbeans.modules.uml.core.metamodel.core.foundation.IPresentationElement;
0078: import org.netbeans.modules.uml.core.support.umlsupport.ETRect;
0079: import org.netbeans.modules.uml.core.support.umlsupport.IETPoint;
0080: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
0081: import org.netbeans.modules.uml.core.support.umlutils.ETList;
0082: import org.netbeans.modules.uml.ui.products.ad.graphobjects.ETEdge;
0083: import org.netbeans.modules.uml.ui.support.applicationmanager.IEdgePresentation;
0084: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETEdge;
0085: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETGraphObject;
0086: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETLabel;
0087: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IETNode;
0088: import org.netbeans.modules.uml.ui.support.viewfactorysupport.PointConversions;
0089: import org.netbeans.modules.uml.ui.support.viewfactorysupport.TSLabelKind;
0090: import org.netbeans.modules.uml.ui.support.viewfactorysupport.TypeConversions;
0091: import org.netbeans.modules.uml.ui.swing.drawingarea.ADGraphWindow;
0092: import org.netbeans.modules.uml.ui.swing.drawingarea.IDrawingAreaControl;
0093: import org.netbeans.test.umllib.actions.Actionable;
0094: import org.netbeans.test.umllib.exceptions.NotFoundException;
0095:
0096: /**
0097: * This is operator for a link beween diagram elements.
0098: * Using it you can perform various operations on link.
0099: * @author Alexei Mokeev
0100: */
0101: public class LinkOperator implements Actionable {
0102: private IETEdge edge = null;
0103: private IETGraphObject to = null;
0104: private IETGraphObject from = null;
0105: private DiagramOperator diagramOperator = null;
0106: //absolute correction for x and y for click/get point (should be removed if the nature of shift will be discovered)
0107: //for now it seems like different approximation to integer in different parts of link creation
0108: //for now shift to right bottom works with 100%,200%,400% zoom and horizontal/vertical link orientation
0109: //do not works with 50%,25% zooms but there is a problem with popup in these zooms in manual steps
0110: private int pnt_shift_x = 2;
0111: private int pnt_shift_y = 2;
0112:
0113: //private IDrawingAreaControl drawingAreaControl = null;
0114:
0115: public static final long WAIT_LINK_TIMEOUT = 30000;
0116:
0117: static {
0118: Timeouts.initDefault("LinkOperator.WaitLinkTime",
0119: WAIT_LINK_TIMEOUT);
0120: }
0121:
0122: /**
0123: *
0124: * @param diagram
0125: * @param edge
0126: */
0127: public LinkOperator(DiagramOperator diagram, IETEdge edge) {
0128: this .edge = edge;
0129: to = (IETGraphObject) edge.getToNode();//We should get class cast in case of an error
0130: from = (IETGraphObject) edge.getFromNode();
0131: diagramOperator = diagram;
0132: }
0133:
0134: /**
0135: * Creates a new instance of LinkOperator
0136: * @param source
0137: * @param destination
0138: * @param linkType
0139: * @param index
0140: * @throws qa.uml.exceptions.NotFoundException
0141: */
0142: public LinkOperator(DiagramElementOperator source,
0143: DiagramElementOperator destination, LinkTypes linkType,
0144: int index) throws NotFoundException {
0145: this (source.getDiagram(), waitForLink(source, destination,
0146: linkType, index).getSource());
0147:
0148: }
0149:
0150: /**
0151: *
0152: * @param source
0153: * @param destination
0154: * @param linkType
0155: * @throws qa.uml.exceptions.NotFoundException
0156: */
0157: public LinkOperator(DiagramElementOperator source,
0158: DiagramElementOperator destination, LinkTypes linkType)
0159: throws NotFoundException {
0160: this (source, destination, linkType, 0);
0161: }
0162:
0163: /**
0164: *
0165: * @param source
0166: * @param destination
0167: * @throws qa.uml.exceptions.NotFoundException
0168: */
0169: public LinkOperator(DiagramElementOperator source,
0170: DiagramElementOperator destination)
0171: throws NotFoundException {
0172: this (source, destination, LinkTypes.ANY, 0);
0173: }
0174:
0175: /**
0176: *
0177: * @return
0178: */
0179: public DiagramOperator getDiagramOperator() {
0180: return diagramOperator;
0181: }
0182:
0183: //Methods from Actionable interface
0184: /**
0185: *
0186: * @return
0187: */
0188: public JPopupMenuOperator getPopup() {
0189: try {
0190: Thread.sleep(100);
0191: } catch (Exception ex) {
0192: }
0193: Point p = getPointForClick();
0194: //workarround for Issue 79519
0195: if (System.getProperty("os.name").toLowerCase().indexOf(
0196: "windows") == -1) {
0197: diagramOperator.getDrawingArea().clickMouse(p.x, p.y, 1);
0198: try {
0199: Thread.sleep(100);
0200: } catch (Exception ex) {
0201: }
0202: }
0203: diagramOperator.getDrawingArea().clickForPopup(p.x, p.y);
0204:
0205: JPopupMenuOperator ret = new JPopupMenuOperator(
0206: JPopupMenuOperator
0207: .waitJPopupMenu(
0208: (Container) (MainWindowOperator
0209: .getDefault().getSource()),
0210: new org.netbeans.test.umllib.util.JPopupByPointChooser(
0211: diagramOperator
0212: .getDrawingArea()
0213: .relativeToScreenPoint(
0214: p))));
0215:
0216: return ret;
0217: }
0218:
0219: /**
0220: * gets point that belongs to a link and centers on it.
0221: * The updated device point is returned
0222: * @param point
0223: * @return
0224: */
0225: public Point makeVisible(Point point) {
0226: ADGraphWindow area = diagramOperator.getDrawingArea().getArea();
0227: IDrawingAreaControl daControl = area.getDrawingArea();
0228:
0229: IETPoint etPoint = daControl.deviceToLogicalPoint(point.x,
0230: point.y);
0231:
0232: IETRect eDeviceAreaRect = new ETRect(area.getVisibleRect());
0233: IETRect eVisibleAreaRect = daControl
0234: .deviceToLogicalRect(eDeviceAreaRect);
0235: IETRect eElementRect = edge.getEngine().getLogicalBoundingRect(
0236: true);
0237: if (!eVisibleAreaRect.contains(etPoint)) {
0238: diagramOperator.getDrawingArea().centerAtPoint(point);
0239: }
0240: return daControl.logicalToDevicePoint(etPoint).asPoint();
0241: }
0242:
0243: public void center() {
0244: center(false, false);
0245: }
0246:
0247: /**
0248: *
0249: * @param selectIt
0250: * @param deselectOthers
0251: */
0252: public void center(boolean selectIt, boolean deselectOthers) {
0253: ADGraphWindow area = diagramOperator.getDrawingArea().getArea();
0254: area.getDrawingArea()
0255: .centerPresentationElement(
0256: edge.getPresentationElement(), selectIt,
0257: deselectOthers);
0258: }
0259:
0260: public void select() {
0261: Point p = getPointForClick();
0262:
0263: diagramOperator.getDrawingArea().moveMouse(p.x, p.y);
0264: new Timeout("", 10).sleep();
0265: diagramOperator.getDrawingArea().clickMouse(p.x, p.y, 1);
0266: new Timeout("", 50).sleep();
0267:
0268: //somehow the above doesn't always work so we add a little hack
0269:
0270: if (!this .edge.isSelected()) {
0271: //dragndrop doesn't work too :(
0272: int x1 = p.x;
0273: int y1 = p.y;
0274: for (int i = 1; i < 10; i++) {
0275: x1 = p.x + i;
0276: diagramOperator.getDrawingArea().clickMouse(x1, y1, 1);
0277: new EventTool().waitNoEvent(500);
0278: if (this .edge.isSelected()) {
0279: break;
0280: }
0281: x1 = p.x - i;
0282: diagramOperator.getDrawingArea().clickMouse(x1, y1, 1);
0283: new EventTool().waitNoEvent(500);
0284: if (this .edge.isSelected()) {
0285: break;
0286: }
0287: y1 = p.y + i;
0288: diagramOperator.getDrawingArea().clickMouse(x1, y1, 1);
0289: new EventTool().waitNoEvent(500);
0290: if (this .edge.isSelected()) {
0291: break;
0292: }
0293: y1 = p.y - i;
0294: diagramOperator.getDrawingArea().clickMouse(x1, y1, 1);
0295: new EventTool().waitNoEvent(500);
0296: if (this .edge.isSelected()) {
0297: break;
0298: }
0299: }
0300: diagramOperator.getDrawingArea().moveMouse(p.x, p.y);
0301: }
0302:
0303: }
0304:
0305: public void addToSelection() {
0306: Point p = getPointForClick();
0307: new Timeout("", 10).sleep();
0308: diagramOperator.getDrawingArea().clickMouse(p.x, p.y, 1,
0309: InputEvent.BUTTON1_MASK, KeyEvent.CTRL_DOWN_MASK);
0310: new Timeout("", 50).sleep();
0311: }
0312:
0313: /**
0314: *
0315: * @return
0316: */
0317: public IETEdge getSource() {
0318: return edge;
0319: }
0320:
0321: /**
0322: *
0323: * @return
0324: */
0325: public IETGraphObject getTo() {
0326: return to;
0327: }
0328:
0329: /**
0330: *
0331: * @return
0332: */
0333: public IETGraphObject getFrom() {
0334: return from;
0335: }
0336:
0337: /**
0338: *
0339: * @return
0340: */
0341: public boolean hasBends() {
0342: return edge.hasBends();
0343: }
0344:
0345: /**
0346: *
0347: * @return
0348: */
0349: public List getBends() {
0350: return edge.bendPoints();
0351: }
0352:
0353: /**
0354: *
0355: * @return
0356: */
0357: public String getType() {
0358: if (edge.getPresentationElement().getSubjectCount() == 1) {
0359: return edge.getPresentationElement().getFirstSubject()
0360: .getElementType();
0361: } else {
0362: return null;
0363: }
0364: //Probably it a source for bugs :)
0365: }
0366:
0367: /**
0368: *
0369: * @return
0370: */
0371: public ArrayList<DiagramLabelOperator> getLabels() {
0372: Iterator<IETLabel> it = edge.getLabels().iterator();
0373: ArrayList<DiagramLabelOperator> res = new ArrayList<DiagramLabelOperator>();
0374: while (it.hasNext()) {
0375: res
0376: .add(new DiagramLabelOperator(diagramOperator, it
0377: .next()));
0378: }
0379: return res;
0380: }
0381:
0382: /**
0383: *
0384: *@return
0385: */
0386: public String[] getLabelsTexts() {
0387: Iterator<IETLabel> it = edge.getLabels().iterator();
0388: String[] res = new String[edge.getLabels().size()];
0389: int cnt = 0;
0390: while (it.hasNext()) {
0391: res[cnt++] = it.next().getLabel().getText();
0392: }
0393: return res;
0394: }
0395:
0396: /**
0397: *
0398: * @param text
0399: * @param index
0400: * @param exact
0401: * @param caseSensitive
0402: * @return
0403: */
0404: public DiagramLabelOperator getLabel(String text, int index,
0405: boolean exact, boolean caseSensitive) {
0406: ArrayList<DiagramLabelOperator> labels = getLabels();
0407: int ind_count = 0;
0408: Operator.DefaultStringComparator comp = new Operator.DefaultStringComparator(
0409: exact, caseSensitive);
0410: for (int i = 0; i < labels.size(); i++) {
0411: if (comp.equals(labels.get(i).getText(), text)) {
0412: if (index <= ind_count)
0413: return labels.get(i);
0414: else
0415: ind_count++;
0416: }
0417: }
0418: return null;
0419: }
0420:
0421: /**
0422: *
0423: * @param text
0424: * @param index
0425: * @return
0426: */
0427: public DiagramLabelOperator getLabel(String text, int index) {
0428: return getLabel(text, index, false, false);
0429: }
0430:
0431: /**
0432: *
0433: * @param text
0434: * @return
0435: */
0436: public DiagramLabelOperator getLabel(String text) {
0437: return getLabel(text, 0);
0438: }
0439:
0440: /**
0441: *
0442: * @return
0443: */
0444: private Point getPointForClick() {
0445: return getPointForClick(true);
0446: }
0447:
0448: /**
0449: * find point and avoid click on labels
0450: * @return
0451: */
0452: private Point getPointForClick(boolean findEmptyPoint) {
0453: TSConstPoint fromPoint = ((ETEdge) edge)
0454: .getSourceClippingPoint();
0455: TSConstPoint toPoint = ((ETEdge) edge).getTargetClippingPoint();
0456: List bendPoints = ((ETEdge) edge).bendPoints();
0457: if ((bendPoints != null) && (bendPoints.size() >= 1)) {
0458: fromPoint = (TSConstPoint) bendPoints
0459: .get(bendPoints.size() - 1);
0460: }
0461: double y = (fromPoint.getY() + toPoint.getY()) * 0.5;
0462: double x = (fromPoint.getX() + toPoint.getX()) * 0.5;
0463: Point tmp = diagramOperator.getDrawingAreaControl()
0464: .logicalToDevicePoint(
0465: PointConversions.newETPoint(new TSConstPoint(x,
0466: y))).asPoint();
0467: tmp.translate(pnt_shift_x, pnt_shift_y);
0468: tmp = makeVisible(tmp);
0469: //check also +-2 area
0470: /*Point a=new Point(tmp);a.translate(2,2);
0471: Point b=new Point(tmp);b.translate(-2,2);
0472: Point c=new Point(tmp);c.translate(-2,-2);
0473: Point d=new Point(tmp);d.translate(2,-2);*/
0474: boolean notFreeArea = !diagramOperator.getDrawingArea()
0475: .isFreePoint(tmp);// || !diagramOperator.getDrawingArea().isFreePoint(a) || !diagramOperator.getDrawingArea().isFreePoint(b) ||!diagramOperator.getDrawingArea().isFreePoint(c) || !diagramOperator.getDrawingArea().isFreePoint(d);
0476: long counter = 0;//avoid infinit search
0477: while (notFreeArea && findEmptyPoint && counter < 2000) {
0478: y = (y + toPoint.getY()) * 0.5;
0479: x = (x + toPoint.getX()) * 0.5;
0480: tmp = diagramOperator
0481: .getDrawingAreaControl()
0482: .logicalToDevicePoint(
0483: PointConversions
0484: .newETPoint(new TSConstPoint(x, y)))
0485: .asPoint();
0486: tmp.translate(pnt_shift_x, pnt_shift_y);
0487: tmp = makeVisible(tmp);
0488: notFreeArea = !diagramOperator.getDrawingArea()
0489: .isFreePoint(tmp);// || !diagramOperator.getDrawingArea().isFreePoint(a) || !diagramOperator.getDrawingArea().isFreePoint(b) ||!diagramOperator.getDrawingArea().isFreePoint(c) || !diagramOperator.getDrawingArea().isFreePoint(d);
0490: counter++;
0491: }
0492: return tmp;
0493: }
0494:
0495: /**
0496: *
0497: * @return Point close to link center of close to last section center
0498: */
0499: public Point getNearCenterPoint() {
0500: return getPointForClick();
0501: }
0502:
0503: /**
0504: *
0505: * @return Point close to link center of close to last section center
0506: */
0507: public Point getNearCenterPointWithoutOverlayCheck() {
0508: return getPointForClick(false);
0509: }
0510:
0511: /**
0512: *
0513: * @return Point close to Target clipping point (with about 5points shift from the edge)
0514: */
0515: public Point getNearTargetPoint() {
0516: return getNearTargetPoint(5);
0517: }
0518:
0519: /**
0520: * @param edgeShift - shift in local point from edge
0521: * @return Point close to Target clipping point (with about edgeShift points shift from the edge)
0522: */
0523: public Point getNearTargetPoint(int edgeShift) {
0524: TSConstPoint fromPoint = ((ETEdge) edge)
0525: .getSourceClippingPoint();
0526: TSConstPoint toPoint = ((ETEdge) edge).getTargetClippingPoint();
0527: List bendPoints = ((ETEdge) edge).bendPoints();
0528: if ((bendPoints != null) && (bendPoints.size() >= 1)) {
0529: fromPoint = (TSConstPoint) bendPoints
0530: .get(bendPoints.size() - 1);
0531: }
0532: double toX = toPoint.getX();
0533: double toY = toPoint.getY();
0534: double frX = fromPoint.getX();
0535: double frY = fromPoint.getY();
0536: double len = Math.sqrt((frY - toY) * (frY - toY) + (frX - toX)
0537: * (frX - toX));
0538: double y = toY + edgeShift * (frY - toY) / len;
0539: double x = toX + edgeShift * (frX - toX) / len;
0540:
0541: Point tmp = diagramOperator.getDrawingAreaControl()
0542: .logicalToDevicePoint(
0543: PointConversions.newETPoint(new TSConstPoint(x,
0544: y))).asPoint();
0545: tmp.translate(pnt_shift_x, pnt_shift_y);
0546: return tmp;
0547: }
0548:
0549: /**
0550: *
0551: * @return Point close to Source clipping point (with about 5points shift from the edge)
0552: */
0553: public Point getNearSourcePoint() {
0554: return getNearSourcePoint(5);
0555: }
0556:
0557: /**
0558: * @param edgeShift - shift in local point from edge
0559: * @return Point close to Target clipping point (with about edgeShift points shift from the edge)
0560: */
0561: public Point getNearSourcePoint(int edgeShift) {
0562: TSConstPoint fromPoint = ((ETEdge) edge)
0563: .getSourceClippingPoint();
0564: TSConstPoint toPoint = ((ETEdge) edge).getTargetClippingPoint();
0565: List bendPoints = ((ETEdge) edge).bendPoints();
0566: if ((bendPoints != null) && (bendPoints.size() >= 1)) {
0567: toPoint = (TSConstPoint) bendPoints.get(0);
0568: }
0569: double toX = toPoint.getX();
0570: double toY = toPoint.getY();
0571: double frX = fromPoint.getX();
0572: double frY = fromPoint.getY();
0573: double len = Math.sqrt((frY - toY) * (frY - toY) + (frX - toX)
0574: * (frX - toX));
0575: double y = frY - edgeShift * (frY - toY) / len;
0576: double x = frX - edgeShift * (frX - toX) / len;
0577:
0578: Point tmp = diagramOperator.getDrawingAreaControl()
0579: .logicalToDevicePoint(
0580: PointConversions.newETPoint(new TSConstPoint(x,
0581: y))).asPoint();
0582: tmp.translate(pnt_shift_x, pnt_shift_y);
0583: return tmp;
0584: }
0585:
0586: /**
0587: *
0588: * @param obj
0589: * @return
0590: */
0591: public boolean equals(Object obj) {
0592: //was compare with equals
0593: //now with references
0594: if ((obj instanceof LinkOperator)
0595: && (((LinkOperator) obj).getSource() == (edge))) {
0596: return true;
0597: } else {
0598: return false;
0599: }
0600: }
0601:
0602: /**
0603: *
0604: * @param source
0605: * @param destination
0606: * @throws qa.uml.exceptions.NotFoundException
0607: * @return
0608: */
0609: public static LinkOperator waitForLink(
0610: final DiagramElementOperator source,
0611: final DiagramElementOperator destination)
0612: throws NotFoundException {
0613: return waitForLink(source, destination, new LinkByTypeChooser(
0614: LinkTypes.ANY), 0);
0615: }
0616:
0617: /**
0618: *
0619: * @return
0620: * @param linkType
0621: * @param source
0622: * @param destination
0623: * @throws qa.uml.exceptions.NotFoundException
0624: */
0625: public static LinkOperator waitForUndirectedLink(
0626: final DiagramElementOperator source,
0627: final DiagramElementOperator destination,
0628: final LinkTypes linkType) throws NotFoundException {
0629: Waiter w = new Waiter(new Waitable() {
0630: public Object actionProduced(Object obj) {
0631: LinkOperator lnk = findLink(source, destination,
0632: new LinkByTypeChooser(linkType), 0);
0633: if (lnk == null) {
0634: return findLink(destination, source,
0635: new LinkByTypeChooser(linkType), 0);
0636: } else {
0637: return lnk;
0638: }
0639: }
0640:
0641: public String getDescription() {
0642: return ("Wait for undirected link " + linkType);
0643: }
0644: });
0645:
0646: return waitForLink(source, destination, new LinkByTypeChooser(
0647: linkType), 0, w);
0648: }
0649:
0650: /**
0651: *
0652: * @param source
0653: * @param destination
0654: * @param linkType
0655: * @throws qa.uml.exceptions.NotFoundException
0656: * @return
0657: */
0658: public static LinkOperator waitForLink(
0659: final DiagramElementOperator source,
0660: final DiagramElementOperator destination, LinkTypes linkType)
0661: throws NotFoundException {
0662: return waitForLink(source, destination, new LinkByTypeChooser(
0663: linkType), 0);
0664: }
0665:
0666: /**
0667: *
0668: * @param source
0669: * @param destination
0670: * @param linkType
0671: * @param index
0672: * @throws qa.uml.exceptions.NotFoundException
0673: * @return
0674: */
0675: public static LinkOperator waitForLink(
0676: final DiagramElementOperator source,
0677: final DiagramElementOperator destination,
0678: LinkTypes linkType, int index) throws NotFoundException {
0679: return waitForLink(source, destination, new LinkByTypeChooser(
0680: linkType), index);
0681: }
0682:
0683: /**
0684: *
0685: * @param source
0686: * @param destination
0687: * @param linkChooser
0688: * @throws qa.uml.exceptions.NotFoundException
0689: * @return
0690: */
0691: public static LinkOperator waitForLink(
0692: final DiagramElementOperator source,
0693: final DiagramElementOperator destination,
0694: final LinkChooser linkChooser) throws NotFoundException {
0695: return waitForLink(source, destination, linkChooser, 0);
0696: }
0697:
0698: /**
0699: *
0700: * @param source
0701: * @param destination
0702: * @param linkChooser
0703: * @param index
0704: * @throws qa.uml.exceptions.NotFoundException
0705: * @return
0706: */
0707: public static LinkOperator waitForLink(
0708: final DiagramElementOperator source,
0709: final DiagramElementOperator destination,
0710: final LinkChooser linkChooser, final int index)
0711: throws NotFoundException {
0712: Waiter w = new Waiter(new Waitable() {
0713: public Object actionProduced(Object obj) {
0714: return findLink(source, destination, linkChooser, index);
0715: }
0716:
0717: public String getDescription() {
0718: //
0719: String all = "\nfrom source: ";
0720: Object tmp[];
0721: tmp = source.getLinks().toArray();
0722: for (int i = 0; i < tmp.length; i++)
0723: all += ((LinkOperator) tmp[i]).getName() + "|"
0724: + ((LinkOperator) tmp[i]).getType() + "|"
0725: + ((LinkOperator) tmp[i]).getFrom() + "|"
0726: + ((LinkOperator) tmp[i]).getTo() + ";";
0727: tmp = destination.getLinks().toArray();
0728: all += "\nfrom destination: ";
0729: for (int i = 0; i < tmp.length; i++)
0730: all += ((LinkOperator) tmp[i]).getName() + "|"
0731: + ((LinkOperator) tmp[i]).getType() + "|"
0732: + ((LinkOperator) tmp[i]).getFrom() + "|"
0733: + ((LinkOperator) tmp[i]).getTo() + ";";
0734: //
0735: return ("Wait with link chooser: "
0736: + linkChooser.getDescription() + " between "
0737: + source.getName() + "/" + source.getType()
0738: + " and " + destination.getName() + "/"
0739: + destination.getType() + "///all:" + all
0740: + "///findResult: " + findLink(source,
0741: destination, linkChooser, index));
0742: }
0743: });
0744: return waitForLink(source, destination, linkChooser, index, w);
0745: }
0746:
0747: /**
0748: *
0749: * @return
0750: */
0751: public boolean isSelected() {
0752: return edge.isSelected();
0753: }
0754:
0755: /**
0756: *
0757: * @return
0758: */
0759: public String getName() {
0760: String name = null;
0761: ETList<IPresentationElement> els = TypeConversions.getElement(
0762: edge).getPresentationElements();
0763: if (els.size() > 0) {
0764: ETList<IElement> subjects = els.get(0).getSubjects();
0765: if (subjects.size() > 0) {
0766: name = subjects.get(0).toString();
0767: }
0768: }
0769: return name;
0770:
0771: /*String ret=null;
0772: ETList<IETLabel> lbls= edge.getLabels();
0773: for(int i=0;lbls!=null && i<lbls.size();i++)
0774: {
0775: if(isNameLabel(lbls.get(i)))
0776: {
0777: ret=lbls.get(i).getText();
0778: }
0779: }
0780: return ret;*/
0781: }
0782:
0783: private boolean isNameLabel(IETLabel sourceLabel) {
0784: int kind = sourceLabel.getLabelKind();
0785: //
0786: boolean isName = kind == TSLabelKind.TSLK_ACTIVITYEDGE_NAME;
0787: isName = isName || kind == TSLabelKind.TSLK_ASSOCIATION_NAME;
0788: isName = isName || kind == TSLabelKind.TSLK_NAME;
0789: /*isName=isName || kind==TSLabelKind.;
0790: isName=isName || kind==TSLabelKind.;
0791: isName=isName || kind==TSLabelKind.;
0792: isName=isName || kind==TSLabelKind.;
0793: isName=isName || kind==TSLabelKind.;
0794: isName=isName || kind==TSLabelKind.;
0795: isName=isName || kind==TSLabelKind.;
0796: isName=isName || kind==TSLabelKind.;
0797: isName=isName || kind==TSLabelKind.;
0798: isName=isName || kind==TSLabelKind.;*/
0799: return isName;
0800:
0801: }
0802:
0803: /**
0804: *
0805: * @return
0806: * @param w
0807: * @param source
0808: * @param destination
0809: * @param linkChooser
0810: * @param index
0811: * @throws qa.uml.exceptions.NotFoundException
0812: */
0813: public static LinkOperator waitForLink(
0814: final DiagramElementOperator source,
0815: final DiagramElementOperator destination,
0816: final LinkChooser linkChooser, final int index,
0817: final Waiter w) throws NotFoundException {
0818: try {
0819: Timeouts t = JemmyProperties.getCurrentTimeouts();
0820: t.setTimeout("Waiter.WaitingTime", t
0821: .getTimeout("LinkOperator.WaitLinkTime"));
0822: LinkOperator l = (LinkOperator) w.waitAction(null);
0823: if (l != null) {
0824: return l;
0825: }
0826: throw new NotFoundException("Matching link was not found.");
0827: } catch (InterruptedException ie) {
0828: throw new NotFoundException(
0829: "Link was not found due to runtime error.");
0830: }
0831: }
0832:
0833: /**
0834: * find link with certain order (i.e. from source to destination)
0835: * @param source
0836: * @param destination
0837: * @param linkChooser
0838: * @param index
0839: * @return
0840: */
0841: public static LinkOperator findLink(DiagramElementOperator source,
0842: DiagramElementOperator destination,
0843: LinkChooser linkChooser, int index) {
0844: TreeSet<LinkOperator> linksFound = new TreeSet<LinkOperator>(
0845: new LinkComparator<LinkOperator>());
0846: if ((source == null) || (destination == null)
0847: || (linkChooser == null)) {
0848: return null;
0849: }
0850:
0851: //It is not the best way, but retainAll doesn't work :(
0852: HashSet<LinkOperator> outLinks = source.getOutLinks();
0853: HashSet<LinkOperator> inLinks = destination.getInLinks();
0854: HashSet<LinkOperator> intersection = new HashSet<LinkOperator>();
0855: Iterator<LinkOperator> inIt = inLinks.iterator();
0856: Iterator<LinkOperator> outIt = outLinks.iterator();
0857:
0858: while (inIt.hasNext()) {
0859: LinkOperator in = inIt.next();
0860: outIt = outLinks.iterator();
0861: while (outIt.hasNext()) {
0862: LinkOperator out = outIt.next();
0863: //should be compare references here?
0864: if (out.getSource() == in.getSource()) {
0865: //or objects
0866: //if(out.getSource().equals(in.getSource())) {
0867: intersection.add(in);
0868: }
0869: }
0870: }
0871:
0872: Iterator<LinkOperator> it = intersection.iterator();
0873:
0874: while (it.hasNext()) {
0875: LinkOperator edge = it.next();
0876: if (linkChooser.checkLink(edge.getSource())) {
0877: linksFound.add(edge);
0878: }
0879: }
0880:
0881: if (linksFound.size() > index) {
0882: return linksFound.toArray(new LinkOperator[1])[index];
0883: }
0884: return null; //Nothing suitable found
0885:
0886: }
0887:
0888: public String toString() {
0889: return super .toString() + " //name: " + getName() + "//type: "
0890: + getType() + "//";
0891: }
0892:
0893: public static class LinkByElementsChooser implements LinkChooser {
0894:
0895: private IETGraphObject from = null;
0896: private IETGraphObject to = null;
0897: private String linkType = null;
0898:
0899: /**
0900: *
0901: * @param from
0902: * @param to
0903: */
0904: public LinkByElementsChooser(IETGraphObject from,
0905: IETGraphObject to) {
0906: this (from, to, LinkTypes.ANY);
0907: }
0908:
0909: /**
0910: *
0911: * @param from
0912: * @param to
0913: * @param linkType
0914: */
0915: public LinkByElementsChooser(IETGraphObject from,
0916: IETGraphObject to, LinkTypes linkType) {
0917: this .from = from;
0918: this .to = to;
0919: this .linkType = linkType.toString();
0920: }
0921:
0922: /**
0923: *
0924: * @param edge
0925: * @return
0926: */
0927: public boolean checkLink(IETEdge edge) {
0928: IETNode fromNode = edge.getFromNode();
0929: IETNode toNode = edge.getToNode();
0930:
0931: if (from.equals(fromNode) && to.equals(toNode)) {
0932: IPresentationElement presentation = edge
0933: .getPresentationElement();
0934: if (presentation == null) {
0935: return false;
0936: }
0937: presentation.getSubjects();
0938: ETList subjects = presentation.getSubjects();
0939: Iterator itSubj = subjects.iterator();
0940: while (itSubj.hasNext()) {
0941: IElement sbj = (IElement) itSubj.next();
0942: if (sbj.getElementType().equals(linkType)) {
0943: return true;
0944: }
0945: }
0946: }
0947: return false;
0948: }
0949:
0950: /**
0951: *
0952: * @return
0953: */
0954: public String getDescription() {
0955: return "Chooser for " + linkType + " link from:" + from
0956: + " to " + to;
0957: }
0958:
0959: }
0960:
0961: public static class LinkByTypeChooser implements LinkChooser {
0962: private String linkType = null;
0963:
0964: /**
0965: *
0966: * @param linkType
0967: */
0968: public LinkByTypeChooser(LinkTypes linkType) {
0969: this .linkType = linkType.toString();
0970: }
0971:
0972: /**
0973: *
0974: * @param edge
0975: * @return
0976: */
0977: public boolean checkLink(IETEdge edge) {
0978: IPresentationElement presentation = edge
0979: .getPresentationElement();
0980: IEdgePresentation iPres = (IEdgePresentation) (edge
0981: .getPresentationElement());
0982: if (presentation == null) {
0983: return false;
0984: }
0985: if (LinkTypes.ANY.toString().equals(linkType)) {
0986: return true;
0987: }
0988: presentation.getSubjects();
0989: ETList subjects = presentation.getSubjects();
0990: Iterator itSubj = subjects.iterator();
0991: while (itSubj.hasNext()) {
0992: IElement sbj = (IElement) itSubj.next();
0993: if (sbj.getElementType().equals(linkType)) {
0994: return true;
0995: }
0996: }
0997: return false;
0998: }
0999:
1000: /**
1001: *
1002: * @return
1003: */
1004: public String getDescription() {
1005: return "Chooser for link of type " + linkType;
1006: }
1007:
1008: }
1009:
1010: public static class LinkComparator<C extends LinkOperator>
1011: implements Comparator<C> {
1012: /**
1013: *
1014: * @param o1
1015: * @param o2
1016: * @return
1017: */
1018: public int compare(C o1, C o2) {
1019: IETEdge o1s = o1.getSource();
1020: IETEdge o2s = o2.getSource();
1021: if (o1s instanceof ETEdge && o2s instanceof ETEdge) {
1022: //if both are ETEdge it's possible to compare by id which seems to be unique instead of borders center
1023: if ((((ETEdge) o1s).getID() - ((ETEdge) o2s).getID()) < 0)
1024: return -1;
1025: else if ((((ETEdge) o1s).getID() - ((ETEdge) o2s)
1026: .getID()) > 0)
1027: return 1;
1028: else
1029: return 0;
1030: } else {
1031: Point o1Center = o1s.getEngine().getBoundingRect()
1032: .getCenterPoint();
1033: Point o2Center = o2s.getEngine().getBoundingRect()
1034: .getCenterPoint();
1035: if (o1Center.y > o2Center.y) {
1036: return 1;
1037: } else if (o1Center.y == o2Center.y) {
1038: if (o1Center.x > o2Center.y) {
1039: return -1;
1040: } else {
1041: return 1;
1042: }
1043: } else {
1044: return -1;
1045: }
1046: }
1047: }
1048: }
1049:
1050: }
|