001    /*--------------------------------------------------------------------------+
002    $Id: StateflowNodeBase.java 26285 2010-02-18 11:22:54Z juergens $
003    |                                                                          |
004    | Copyright 2005-2010 Technische Universitaet Muenchen                     |
005    |                                                                          |
006    | Licensed under the Apache License, Version 2.0 (the "License");          |
007    | you may not use this file except in compliance with the License.         |
008    | You may obtain a copy of the License at                                  |
009    |                                                                          |
010    |    http://www.apache.org/licenses/LICENSE-2.0                            |
011    |                                                                          |
012    | Unless required by applicable law or agreed to in writing, software      |
013    | distributed under the License is distributed on an "AS IS" BASIS,        |
014    | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015    | See the License for the specific language governing permissions and      |
016    | limitations under the License.                                           |
017    +--------------------------------------------------------------------------*/
018    package edu.tum.cs.simulink.model.stateflow;
019    
020    import java.util.ArrayList;
021    
022    import edu.tum.cs.commons.assertion.CCSMAssert;
023    import edu.tum.cs.commons.assertion.CCSMPre;
024    import edu.tum.cs.commons.collections.CollectionUtils;
025    import edu.tum.cs.commons.collections.IdentityHashSet;
026    import edu.tum.cs.commons.collections.UnmodifiableSet;
027    
028    /**
029     * Base class for Stateflow nodes (elements that can be connected by
030     * transitions).
031     * 
032     * @author deissenb
033     * @author $Author: juergens $
034     * @version $Rev: 26285 $
035     * @levd.rating GREEN Hash: 8A2286A4B4879B5ABBDA3916C4D215E9
036     */
037    public abstract class StateflowNodeBase extends
038                    StateflowDeclContainerBase<IStateflowNodeContainer<?>> {
039    
040            /** Incoming transitions. */
041            private final IdentityHashSet<StateflowTransition> inTransitions = new IdentityHashSet<StateflowTransition>();
042    
043            /** Outgoing transitions. */
044            private final IdentityHashSet<StateflowTransition> outTransitions = new IdentityHashSet<StateflowTransition>();
045    
046            /** Create new node. */
047            protected StateflowNodeBase() {
048                    super();
049            }
050    
051            /** Create new element from existing one (for deep cloning). */
052            protected StateflowNodeBase(StateflowNodeBase element) {
053                    super(element);
054            }
055    
056            /** Add incoming transition. */
057            /* package */void addInTransition(StateflowTransition transition) {
058                    CCSMPre.isTrue(transition.getDst() == this,
059                                    "Transition destination element does not match");
060                    inTransitions.add(transition);
061            }
062    
063            /** Add outgoing transition. */
064            /* package */void addOutTransition(StateflowTransition transition) {
065                    CCSMPre.isTrue(transition.getSrc() == this,
066                                    "Transition source element does not match");
067                    outTransitions.add(transition);
068            }
069    
070            /** Get incoming transitions. */
071            public UnmodifiableSet<StateflowTransition> getInTransitions() {
072                    return CollectionUtils.asUnmodifiable(inTransitions);
073            }
074    
075            /** Get outgoing transitions. */
076            public UnmodifiableSet<StateflowTransition> getOutTransitions() {
077                    return CollectionUtils.asUnmodifiable(outTransitions);
078            }
079    
080            /** Remove this node from the model. */
081            @Override
082            public void remove() {
083                    IStateflowNodeContainer<?> parent = getParent();
084    
085                    CCSMPre.isFalse(parent == null,
086                                    "Node has no parent to be removed from.");
087    
088                    // The reason for this instanceof-constrcut is the following: Java
089                    // interfaces support only public methods. Therefore adding the
090                    // removeNode-method to IStateFlowNodeContainr would make it visible to
091                    // all clients. As we usually only make the parameterless
092                    // remove()-method visible, this is undesirable.
093                    if (parent instanceof StateflowChart) {
094                            ((StateflowChart) parent).removeNode(this);
095                    } else if (parent instanceof StateflowState) {
096                            ((StateflowState) parent).removeNode(this);
097                    } else {
098                            CCSMAssert.fail("Unknown Stateflow container: " + parent);
099                    }
100    
101                    for (StateflowTransition transition : new ArrayList<StateflowTransition>(
102                                    inTransitions)) {
103                            transition.remove();
104                    }
105    
106                    for (StateflowTransition transition : new ArrayList<StateflowTransition>(
107                                    outTransitions)) {
108                            transition.remove();
109                    }
110            }
111    
112            /** Defines covariant returnt type. */
113            public abstract StateflowNodeBase deepClone();
114    
115            /** Remove in transition. */
116            /* package */void removeInTransition(StateflowTransition transition) {
117                    CCSMPre.isTrue(inTransitions.contains(transition),
118                                    "Transition does not belong to this node.");
119                    inTransitions.remove(transition);
120            }
121    
122            /** Remove out transition. */
123            /* package */void removeOutTransition(StateflowTransition transition) {
124                    CCSMPre.isTrue(outTransitions.contains(transition),
125                                    "Transition does not belong to this node.");
126                    outTransitions.remove(transition);
127            }
128    
129    }