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.modules.uml.ui.products.ad.compartments.sequencediagram.lifelinepieces;
043:
044: import org.netbeans.modules.uml.core.support.umlsupport.IETRect;
045: import org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.ETLifelineCompartment;
046: import org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.IADLifelineCompartment;
047: import org.netbeans.modules.uml.ui.products.ad.compartments.sequencediagram.LifelineConnectorLocation;
048: import com.tomsawyer.drawing.TSConnector;
049: import com.tomsawyer.graph.TSEdge;
050:
051: /**
052: * Lifeline Piece is helper class that provides convience methods used to
053: * manipulate connector pieces.
054: *
055: * @author Trey Spiva
056: */
057: public class LifelinePiece {
058: private ConnectorPiece m_Piece = null;
059: private TSConnector m_AssociatedConnector = null;
060:
061: /**
062: * Initializes the LifelinePiece instance. The default constructor is
063: * protected and therefore can only be used by LifelinePieces.
064: */
065: protected LifelinePiece() {
066: }
067:
068: /**
069: * Initialze the lifeline piece with a connector piece.
070: *
071: * @param piece The piece that the LifelinePiece will reference.
072: */
073: public LifelinePiece(ConnectorPiece piece) {
074: setPiece(piece);
075: }
076:
077: /**
078: * Initializes the LifelinePiece by specifing the connector that is
079: * manipulated. The associated ConnectorPiece is retrieved from the
080: * connector.
081: *
082: * @param connector The connector to use to retrieve the ConnectorPiece.
083: */
084: public LifelinePiece(TSConnector connector) {
085: ConnectorPiece piece = ConnectorPiece
086: .getPieceAttachedToConnector(connector);
087: setPiece(piece);
088: setAssociatedConnector(connector);
089: }
090:
091: /**
092: * Retrieves the location of the connector that is associated with the
093: * LifelinePiece instance.
094: *
095: * @return The location of the connector. The value will be one of the
096: * LifelineConnectorLocation values.
097: *
098: * @see LifelineConnectorLocation
099: */
100: public int getConnectorLocation() {
101: return getConnectorLocation(getAssociatedConnector());
102: }
103:
104: public int getConnectorLocation(TSConnector connector) {
105: int retVal = LifelineConnectorLocation.LCL_UNKNOWN;
106:
107: if (connector instanceof TSConnector) {
108: TSConnector tsConnector = (TSConnector) connector;
109: ConnectorPiece piece = getPiece();
110: if (piece != null) {
111: retVal = piece.getLocation(tsConnector);
112: }
113: }
114:
115: return retVal;
116: }
117:
118: /**
119: * Indicates wether this interface is associated with a valid lifeline piece
120: *
121: * @return <code>true</code> if the piece is valid.
122: */
123: public boolean isValid() {
124: return getPiece() != null;
125: }
126:
127: /**
128: * Get the diagram logical location for the top of the piece.
129: *
130: * @return The vertical location for the top of the piece on the diagram
131: */
132: public int getLogicalTop() {
133: int retVal = 0;
134:
135: ConnectorPiece piece = getPiece();
136: if (piece != null) {
137: ETLifelineCompartment compartment = piece.getParent();
138: if (compartment != null) {
139: IETRect rect = compartment.getLogicalBoundingRect();
140: retVal = rect.getTop() - piece.getTop();
141: }
142: }
143:
144: return retVal;
145: }
146:
147: public void setLogicalTop(int top) {
148: ConnectorPiece piece = getPiece();
149: if (piece != null) {
150: piece.setLogicalTop(top);
151: }
152: }
153:
154: public int getLogicalBottom() {
155: int retVal = 0;
156:
157: ConnectorPiece piece = getPiece();
158: if (piece != null) {
159: retVal = piece.getLogicalBottom();
160: }
161:
162: return retVal;
163: }
164:
165: public void setLogicalBottom(int value) {
166: ConnectorPiece piece = getPiece();
167: if (piece != null) {
168: piece.setLogicalBottom(value);
169: }
170: }
171:
172: public TSConnector createConnector(int lclCorner) {
173: TSConnector retVal = null;
174:
175: ConnectorPiece piece = getPiece();
176: if (piece != null) {
177: retVal = piece.createConnector(lclCorner);
178: }
179:
180: return retVal;
181: }
182:
183: public void attachConnector(int lclCorner, TSConnector connector) {
184: ConnectorPiece piece = getPiece();
185: if (piece instanceof ActivationBar) {
186: piece.attachConnector(connector, lclCorner, true);
187: }
188: }
189:
190: public boolean isPartOfMessageToSelf() {
191: boolean retVal = false;
192:
193: ConnectorPiece piece = getPiece();
194: if (piece instanceof ActivationBar) {
195: ActivationBar bar = (ActivationBar) piece;
196: retVal = bar.isMessageToSelf();
197: }
198:
199: return retVal;
200: }
201:
202: public void setIsPartOfMessageToSelf(boolean value) {
203: ConnectorPiece piece = getPiece();
204: if (piece instanceof ActivationBar) {
205: ActivationBar bar = (ActivationBar) piece;
206: bar.setMessageToSelf(value);
207: }
208: }
209:
210: /**
211: * Returns the LifelinePiece that is associated with this piece.
212: *
213: * @return The LifelinePiece that represents the associated Piece.
214: * <code>null</code> may be returned if
215: */
216: public LifelinePiece getAssociatedPiece() {
217: LifelinePiece retVal = new LifelinePiece();
218:
219: ConnectorPiece piece = getPiece();
220: if (piece != null) {
221: ConnectorPiece associatedPiece = piece
222: .getAssociatedPiece(false);
223: if (associatedPiece != null) {
224: retVal.setPiece(associatedPiece);
225: }
226: }
227:
228: return retVal;
229: }
230:
231: /**
232: * Returns the LifelinePiece that is this piece's parent.
233: *
234: * @return The parent piece LifelinePiece instance.
235: */
236: public LifelinePiece getParentPiece() {
237: LifelinePiece retVal = null;
238:
239: ConnectorPiece piece = getPiece();
240: if (piece != null) {
241: LifelineCompartmentPiece parentPiece = piece
242: .getParentPiece();
243: if (parentPiece instanceof ConnectorPiece) {
244: retVal = new LifelinePiece((ConnectorPiece) parentPiece);
245: }
246: }
247:
248: return retVal;
249: }
250:
251: /**
252: * Returns the compartment that contains this lifeline piece
253: */
254: public IADLifelineCompartment getParentCompartment() {
255: IADLifelineCompartment retVal = null;
256:
257: ConnectorPiece piece = getPiece();
258: if (piece != null) {
259: retVal = piece.getParent();
260: }
261:
262: return retVal;
263: }
264:
265: /**
266: * Returns the edge attached to this lifeline piece's corner
267: *
268: * @param lclCorner The corner that has the attached edge. The valid
269: * values are one of the LifelineConnectorLocation values.
270: * @return The attached edge. If an edge is not attached to the specified
271: * corner then <code>null</code> will be returned.
272: * @see LifelineConnectorLocation
273: */
274: public TSEdge getAttachedEdge(int lclCorner) {
275: TSEdge retVal = null;
276:
277: ConnectorPiece piece = getPiece();
278: if (piece != null) {
279: retVal = piece.getAttachedEdge(lclCorner);
280: }
281:
282: return retVal;
283: }
284:
285: //**************************************************
286: // Helper Methods
287: //**************************************************
288:
289: /**
290: * Retieves the connector piece associated with the lifeline piece.
291: *
292: * @return The connector piece.
293: */
294: protected ConnectorPiece getPiece() {
295: return m_Piece;
296: }
297:
298: /**
299: * Sets the connector piece associated with the lifeline piece.
300: *
301: * @param piece The connector piece.
302: */
303: protected void setPiece(ConnectorPiece piece) {
304: m_Piece = piece;
305: }
306:
307: /**
308: * Retrieves the connector that was used to initalize the LifelinePiece.
309: * If the LifelinePiece was not initialize via a connector then null will
310: * be returned.
311: *
312: * @return The associated connector.
313: */
314: public TSConnector getAssociatedConnector() {
315: return m_AssociatedConnector;
316: }
317:
318: /**
319: * Sets the connector is associated with the Lifeline Connector.
320: *
321: * @param connector The connector to assocate with the LifelinePiece.
322: */
323: public void setAssociatedConnector(TSConnector connector) {
324: m_AssociatedConnector = connector;
325: }
326:
327: /**
328: * Makes a copy of the piece on the input lifeline
329: *
330: * @param pCompartment [in] The compartment where a new piece is created using this piece as a model
331: * @param openConnector [in] The new connector that has no edges attached.
332: *
333: * @return void
334: */
335: public TSConnector copyTo(ETLifelineCompartment compartment) {
336: if (null == compartment)
337: throw new IllegalArgumentException();
338: if (null == m_Piece)
339: throw new IllegalStateException();
340:
341: TSConnector openConnector = null;
342:
343: // Fix W10441: The problem here was create sync 1-2, nest sync 2-1, then move the arrow head
344: // from 2.3, and then back from 3.2. The result message would cross over the
345: // original nested messages.
346: // The solution is to inform the create code that this is a finish piece, so
347: // that the proper parenting logic is kicking in.
348: // UPDATE: we should probabaly have the activation bar remember what type it is.
349:
350: ConnectorPiece connectorPiece = null;
351:
352: int lpk = m_Piece.getLifelinePiecesKind();
353: // we should not be finding a piece, but always creating a new one
354:
355: connectorPiece = (ConnectorPiece) compartment.createElement(
356: m_Piece.getLogicalTop(), lpk);
357:
358: if (connectorPiece != null) {
359: m_Piece.removeSelfFromStack();
360: openConnector = connectorPiece.copy(m_Piece);
361:
362: m_Piece = null;
363: }
364:
365: return openConnector;
366: }
367:
368: }
|