001    /*--------------------------------------------------------------------------+
002    $Id: StateflowMachine.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    import java.util.HashMap;
022    
023    import edu.tum.cs.commons.assertion.CCSMAssert;
024    import edu.tum.cs.commons.assertion.CCSMPre;
025    import edu.tum.cs.commons.collections.CollectionUtils;
026    import edu.tum.cs.commons.collections.IdentityHashSet;
027    import edu.tum.cs.commons.collections.UnmodifiableCollection;
028    import edu.tum.cs.commons.collections.UnmodifiableSet;
029    import edu.tum.cs.simulink.model.SimulinkModel;
030    
031    /**
032     * The Stateflow machine is the container element of all Stateflow elements of a
033     * Simulink model. There is only one machine per model and Stateflow machines do
034     * not have a parent element.
035     * 
036     * @author deissenb
037     * @author $Author: juergens $
038     * @version $Rev: 26285 $
039     * @levd.rating GREEN Hash: E2A81530901B4A6A0972678DFB69415F
040     */
041    public class StateflowMachine extends
042                    StateflowDeclContainerBase<IStateflowElement<?>> {
043    
044            /** The Simulink model this machine belongs to. */
045            private SimulinkModel model;
046    
047            /** Targets of this machine. */
048            private final IdentityHashSet<StateflowTarget> targets = new IdentityHashSet<StateflowTarget>();
049    
050            /** Charts of this machine. */
051            private final HashMap<String, StateflowChart> charts = new HashMap<String, StateflowChart>();
052    
053            /** Create new machine. */
054            public StateflowMachine(SimulinkModel model) {
055                    this.model = model;
056                    model.setStateflowMachine(this);
057            }
058    
059            /**
060             * Copy constructor. This does not clone the charts as these are cloned via
061             * the {@link StateflowBlock}s they belong to.
062             * 
063             * @param orig
064             *            original machine
065             * @param model
066             *            model the clone belongs to.
067             */
068            public StateflowMachine(StateflowMachine orig, SimulinkModel model) {
069                    super(orig);
070                    this.model = model;
071                    model.setStateflowMachine(this);
072    
073                    for (StateflowTarget target : orig.targets) {
074                            addTarget(target.deepClone());
075                    }
076    
077                    // Charts are cloned via the Stateflow blocks
078            }
079    
080            /**
081             * Add chart to the machine.
082             * 
083             * @param fqName
084             *            full qualified name of the Stateflow block this chart belongs
085             *            to.
086             * @param chart
087             *            the chart.
088             */
089            public void addChart(String fqName, StateflowChart chart) {
090                    charts.put(fqName, chart);
091                    chart.setParent(this);
092            }
093    
094            /** Add a target. */
095            public void addTarget(StateflowTarget target) {
096                    targets.add(target);
097                    target.setParent(this);
098            }
099    
100            /**
101             * This throws a {@link UnsupportedOperationException} as the machine can
102             * only be deep cloned by cloning the {@link SimulinkModel} it belongs to.
103             */
104            public StateflowMachine deepClone() {
105                    throw new UnsupportedOperationException("Clone model to clone machine.");
106            }
107    
108            /**
109             * Get chart for full qualified name of the Stateflow block the chart
110             * belongs to.
111             */
112            public StateflowChart getChart(String fqName) {
113                    return charts.get(fqName);
114            }
115    
116            /** Get charts of this machine. */
117            public UnmodifiableCollection<StateflowChart> getCharts() {
118                    return CollectionUtils.asUnmodifiable(charts.values());
119            }
120    
121            /** Get the Simulink model this machine belongs to. */
122            public SimulinkModel getModel() {
123                    return model;
124            }
125    
126            /** Get targets of this machine. */
127            public UnmodifiableSet<StateflowTarget> getTargets() {
128                    return CollectionUtils.asUnmodifiable(targets);
129            }
130    
131            /**
132             * Removes the machine from the model. The Machine can be removed from the
133             * model only after all {@link StateflowBlock}s were removed.
134             */
135            @Override
136            public void remove() {
137                    CCSMPre
138                                    .isTrue(charts.isEmpty(),
139                                                    "All charts must be removed first (via removing the Stateflow blocks).");
140                    model.setStateflowMachine(null);
141                    model = null;
142    
143                    for (StateflowTarget target : new ArrayList<StateflowTarget>(targets)) {
144                            target.remove();
145                    }
146            }
147    
148            /** Remove chart. */
149            /* package */void removeChart(StateflowChart chart) {
150                    CCSMPre.isTrue(chart.getMachine() == this,
151                                    "Machine does not contain chart with name " + chart);
152    
153                    String fqName = chart.getStateflowBlock().getId();
154                    CCSMAssert.isTrue(charts.get(fqName) == chart,
155                                    "Error in chart storage.");
156    
157                    charts.remove(fqName);
158                    chart.removeNodes();
159                    chart.setStateflowBlock(null);
160                    chart.setParent(null);
161            }
162    
163            /** Remove target. */
164            /* package */void removeTarget(StateflowTarget target) {
165                    targets.remove(target);
166                    target.setParent(null);
167            }
168    
169    }