TMLSDInstance.java 12.81 KiB
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille, Andrea Enrici
*
* ludovic.apvrille AT telecom-paristech.fr
* andrea.enrici AT telecom-paristech.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package ui.tmlsd;
import myutil.GraphicLib;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import ui.*;
import ui.util.IconManager;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
//Abstract class, getType() and editOndoubleClick( JFrame ) are abstract
/**
* Class TMLSDInstance
* Instance of a TML sequence diagram
* Creation: 17/02/2004
* @version 1.1 10/06/2014
* @author Ludovic APVRILLE, Andrea ENRICI
*/
public abstract class TMLSDInstance extends TGCWithInternalComponent implements SwallowTGComponent {
//protected int lineLength = 5;
//protected int textX, textY;
protected int spacePt = 10;
protected int wText = 10, hText = 15;
protected int increaseSlice = 250;
protected boolean isActor;
protected static int heightActor = 30;
protected static int widthActor = 16;
protected LinkedList<TAttribute> myAttributes;
protected String mappedUnit = ""; //The arch unit where the instance is mapped to
public TMLSDInstance(int _x, int _y, int _minX, int _maxX, int _minY, int _maxY, boolean _pos, TGComponent _father, TDiagramPanel _tdp) {
super(_x, _y, _minX, _maxX, _minY, _maxY, _pos, _father, _tdp);
width = 10;
height = 500;
//textX = 0;
//textY = 2;
minWidth = 10;
maxWidth = 10;
minHeight = 250;
maxHeight = 1500;
makeTGConnectingPoints();
//addTGConnectingPointsComment();
nbInternalTGComponent = 0;
moveable = true;
editable = true;
removable = true;
userResizable = true;
value = "Instance name";
name = "instance";
myAttributes = new LinkedList<TAttribute> ();
myImageIcon = IconManager.imgic500;
}
public void internalDrawing(Graphics g) {
if (!tdp.isScaled()) {
wText = g.getFontMetrics().stringWidth(name);
hText = g.getFontMetrics().getHeight();
}
g.drawString(name, x - (wText / 2) + width/2, y - 3);
g.drawLine(x - (wText / 2) + width/2, y-2, x + (wText / 2) + width/2, y-2);
g.drawLine(x+(width/2), y, x+(width/2), y +height);
if (isActor) {
int xtmp = x + (width-widthActor) / 2;
int ytmp = y-hText;
// Head
g.drawOval(xtmp+(widthActor/4)-1, ytmp-heightActor, 2+widthActor/2, 2+widthActor/2);
//Body
g.drawLine(xtmp+widthActor/2, ytmp-heightActor/3, xtmp+widthActor/2, ytmp-(2*heightActor)/3);
//Arms
g.drawLine(xtmp, ytmp-(heightActor/2) - 2, xtmp+widthActor, ytmp-(heightActor/2) - 2);
//Left leg
g.drawLine(xtmp+widthActor, ytmp, xtmp+widthActor/2, ytmp-heightActor/3);
//right leg
g.drawLine(xtmp, ytmp, xtmp+widthActor/2, ytmp-heightActor/3);
}
}
public TGComponent isOnOnlyMe(int _x, int _y) {
if (GraphicLib.isInRectangle(_x, _y, x, y, width, height)) {
return this;
}
if (GraphicLib.isInRectangle(_x, _y, x + (width/2) - (wText/2) , y-hText, wText, hText)) {
return this;
}
if (isActor) {
if (GraphicLib.isInRectangle(_x, _y, x + (width-widthActor) / 2, y-heightActor-hText, widthActor, heightActor)) {
return this;
}
}
return null;
}
public int getMyCurrentMinX() {
return Math.min(x + (width/2) - (wText/2), x);
}
public int getMyCurrentMaxX() {
return Math.max(x + (width/2) + (wText/2), x + width);
}
public int getMyCurrentMinY() {
return Math.min(y-hText-heightActor, y);
}
public String getInstanceName() {
return getName();
}
public abstract int getType();
protected void makeTGConnectingPoints() {
nbConnectingPoint = ( (height - (2 * spacePt) ) / spacePt ) + 1;
connectingPoint = new TGConnectingPoint[ nbConnectingPoint ];
int yh = spacePt;
for(int i = 0; i < nbConnectingPoint; i++, yh += spacePt ) {
connectingPoint[i] = new TGConnectingPointTMLSD(this, ( width/2), yh, true, true );
}
}
public abstract boolean editOndoubleClick( JFrame frame );
public boolean acceptSwallowedTGComponent(TGComponent tgc) {
return (tgc instanceof TMLSDActionState);
}
public boolean addSwallowedTGComponent(TGComponent tgc, int x, int y) {
if (!acceptSwallowedTGComponent(tgc)) {
return false;
}
//
// Choose its position
int realY = Math.max(y, getY() + spacePt);
realY = Math.min(realY, getY() + height + spacePt);
int realX = tgc.getX();
// Make it an internal component
// It's one of my son
tgc.setFather(this);
tgc.setDrawingZone(true);
if ((tgc instanceof TMLSDActionState)) {
realX = getX()+(width/2);
//tgc.setCdRectangle((width/2), (width/2), spacePt, height-spacePt-tgc.getHeight());
tgc.setCd(realX, realY);
}
setCDRectangleOfSwallowed(tgc);
//add it
addInternalComponent(tgc, 0);
return true;
}
public void removeSwallowedTGComponent(TGComponent tgc) {
removeInternalComponent(tgc);
}
// previous in the sense of with y the closer and before
public TGComponent getPreviousTGComponent(TGComponent tgcToAnalyse) {
int close = Integer.MAX_VALUE;
TGComponent tgc;
TGComponent tgcfound = null;
int diff;
for(int i=0; i<nbInternalTGComponent; i++) {
tgc = tgcomponent[i];
if (tgc != tgcToAnalyse) {
diff = tgcToAnalyse.getY() - tgc.getY();
if ((diff > 0) && (diff < close)) {
close = diff;
tgcfound = tgc;
}
}
}
return tgcfound;
}
public TGComponent getTGComponentActionCloserTo(TGComponent tgc) {
/* action : message send, message receive, other ? */
/* timers ? */
/* now: only message! */
return ((TMLSDPanel)tdp).messageActionCloserTo(tgc, this);
}
public void addActionToPopupMenu(JPopupMenu componentMenu, ActionListener menuAL, int x, int y) {
componentMenu.addSeparator();
JMenuItem decrease = new JMenuItem("Decrease size");
decrease.addActionListener(menuAL);
componentMenu.add(decrease);
decrease.setEnabled(canDecreaseSize());
JMenuItem increase = new JMenuItem("Increase size");
increase.addActionListener(menuAL);
componentMenu.add(increase);
}
public boolean eventOnPopup(ActionEvent e) {
if ((e.getActionCommand().compareTo("Decrease size")) == 0) {
decreaseSize();
} else {
increaseSize();
}
return true;
}
public void updateMinMaxSize() {
minHeight = 250;
int i;
for(i=0; i<connectingPoint.length ; i++) {
if (!connectingPoint[i].isFree()) {
minHeight = Math.max(minHeight, connectingPoint[i].getY() - y);
}
}
for(i=0; i<nbInternalTGComponent ; i++) {
minHeight = Math.max(minHeight, tgcomponent[i].getY() + tgcomponent[i].getHeight()- y);
}
}
public boolean canDecreaseSize() {
if (height <= increaseSlice) {
return false;
}
int newNbConnectingPoint = (((height-increaseSlice) - (2 * spacePt)) / spacePt) + 1;
int i;
for(i=newNbConnectingPoint; i<connectingPoint.length ; i++) {
if (!connectingPoint[i].isFree()) {
//
return false;
}
}
//SwallowedComponents
for(i=0; i<nbInternalTGComponent ; i++) {
//
if ((tgcomponent[i].getY() + tgcomponent[i].getHeight()) > (getY() + getHeight() - increaseSlice)) {
//
return false;
}
}
return true;
}
public void decreaseSize() {
//
//Check whether it is possible or not (swallowed components and tgconnecting points used
if (!canDecreaseSize()) {
return;
}
// new nb of connectingPoints
// If ok, do the modification
height = height - increaseSlice;
hasBeenResized();
}
public void increaseSize() {
//
height = height + increaseSlice;
hasBeenResized();
}
public void hasBeenResized(){
int i;
TGConnectingPoint [] connectingPointTmp = connectingPoint;
makeTGConnectingPoints();
for(i=0; i<Math.min(connectingPointTmp.length, connectingPoint.length) ; i++) {
connectingPoint[i] = connectingPointTmp[i];
}
// Increase tdp if necessary?
// Reposition each swallowed component
for(i=0; i<nbInternalTGComponent ; i++) {
setCDRectangleOfSwallowed(tgcomponent[i]);
}
}
protected void setCDRectangleOfSwallowed(TGComponent tgc) {
if ((tgc instanceof TMLSDActionState)) {
tgc.setCdRectangle((width/2), (width/2), spacePt, height-spacePt-tgc.getHeight());
}
}
protected String translateExtraParam() {
StringBuffer sb = new StringBuffer( "<extraparam>\n" );
sb.append( "<Mapping mappedOn=\"" );
sb.append( "" + mappedUnit );
sb.append( "\" />\n" );
sb.append( "<Actor data=\"" );
sb.append( ""+isActor );
sb.append( "\" />\n" );
for (TAttribute a: myAttributes) {
sb.append( "<Attribute access=\"" );
sb.append( a.getAccess() );
sb.append( "\" id=\"" );
sb.append( a.getId() );
sb.append( "\" value=\"" );
sb.append( a.getInitialValue() );
sb.append( "\" type=\"" );
sb.append( a.getType() );
sb.append( "\" typeOther=\"" );
sb.append( a.getTypeOther() );
sb.append( "\" />\n" );
}
sb.append( "</extraparam>\n" );
return new String(sb);
}
@Override
public void loadExtraParam( NodeList nl, int decX, int decY, int decId ) throws MalformedModelingException{
//
try {
NodeList nli;
Node n1, n2;
Element elt;
int access, type;
String typeOther;
String id, valueAtt;
for( int i = 0; i < nl.getLength(); i++ ) {
n1 = nl.item(i);
//
if( n1.getNodeType() == Node.ELEMENT_NODE ) {
nli = n1.getChildNodes();
// Issue #17 copy-paste error on j index
for( int j = 0; j < nli.getLength(); j++ ) {
n2 = nli.item(j);
//
if( n2.getNodeType() == Node.ELEMENT_NODE ) {
elt = (Element) n2;
if( elt.getTagName().equals("Mapping") ) {
mappedUnit = elt.getAttribute("mappedOn");
}
if( elt.getTagName().equals("Actor") ) {
if( elt.getAttribute("data").compareTo("true") == 0 ) {
isActor = true;
}
}
//TraceManager.addDev( "I am analyzing " + elt.getTagName() );
if( elt.getTagName().equals("Attribute") ) {
//TraceManager.addDev("Analyzing attribute");
access = Integer.decode(elt.getAttribute("access")).intValue();
type = Integer.decode(elt.getAttribute("type")).intValue();
try {
typeOther = elt.getAttribute("typeOther");
}
catch ( Exception e ) {
typeOther = "";
}
id = elt.getAttribute("id");
valueAtt = elt.getAttribute("value");
if( valueAtt.equals("null") ) {
valueAtt = "";
}
if( (TAttribute.isAValidId(id, false, false, false) ) && ( TAttribute.isAValidInitialValue(type, valueAtt)) ) {
//TraceManager.addDev("Adding attribute " + id + " typeOther=" + typeOther);
TAttribute ta = new TAttribute(access, id, valueAtt, type, typeOther);
myAttributes.add (ta);
}
}
}
}
}
}
}
catch ( Exception e ) {
throw new MalformedModelingException();
}
}
public void setActor(boolean b) {
isActor = b;
}
public int getNumberInternalComponents() {
return nbInternalTGComponent;
}
public TGComponent[] getInternalComponents() {
return tgcomponent;
}
public TGConnectingPoint[] getConnectingPoint() {
return connectingPoint;
}
public LinkedList<TAttribute> getAttributes() {
return myAttributes;
}
}