EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][desmoj.core.simulator]

COVERAGE SUMMARY FOR SOURCE FILE [Experiment.java]

nameclass, %method, %block, %line, %
Experiment.java0%   (0/2)0%   (0/96)0%   (0/2747)0%   (0/825)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Experiment0%   (0/1)0%   (0/94)0%   (0/2738)0%   (0/822)
Experiment (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
Experiment (String, String): void 0%   (0/1)0%   (0/9)0%   (0/4)
Experiment (String, String, ArrayList, ArrayList, ArrayList, ArrayList): void 0%   (0/1)0%   (0/12)0%   (0/4)
Experiment (String, String, String, String, String, String): void 0%   (0/1)0%   (0/12)0%   (0/4)
Experiment (String, String, TimeUnit, TimeUnit, TimeFormatter, ArrayList, Arr... 0%   (0/1)0%   (0/32)0%   (0/8)
Experiment (String, String, TimeUnit, TimeUnit, TimeFormatter, String, String... 0%   (0/1)0%   (0/72)0%   (0/12)
Experiment (String, TimeUnit, TimeUnit, TimeFormatter): void 0%   (0/1)0%   (0/12)0%   (0/4)
Experiment (String, boolean): void 0%   (0/1)0%   (0/28)0%   (0/6)
addDebugReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/10)
addErrorReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/10)
addReceiver (MessageReceiver, Class): void 0%   (0/1)0%   (0/46)0%   (0/18)
addTraceReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/10)
createScheduler (String, EventList): Scheduler 0%   (0/1)0%   (0/9)0%   (0/2)
deRegister (FileOutput): void 0%   (0/1)0%   (0/24)0%   (0/9)
debugIsOn (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
debugOff (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
debugOff (TimeInstant): void 0%   (0/1)0%   (0/57)0%   (0/19)
debugOn (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
debugOn (TimeInstant): void 0%   (0/1)0%   (0/72)0%   (0/22)
debugPeriod (SimTime, SimTime): void 0%   (0/1)0%   (0/7)0%   (0/3)
debugPeriod (TimeInstant, TimeInstant): void 0%   (0/1)0%   (0/108)0%   (0/42)
finish (): void 0%   (0/1)0%   (0/167)0%   (0/30)
getDelayInMillis (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getDescription (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getDesmoJLicense (boolean): String 0%   (0/1)0%   (0/6)0%   (0/2)
getDesmoJVersion (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getDistributionManager (): DistributionManager 0%   (0/1)0%   (0/3)0%   (0/1)
getEpsilon (): SimTime 0%   (0/1)0%   (0/7)0%   (0/1)
getEpsilonUnit (): TimeUnit 0%   (0/1)0%   (0/2)0%   (0/1)
getExecutionSpeedRate (): double 0%   (0/1)0%   (0/4)0%   (0/1)
getMessageManager (): MessageDistributor 0%   (0/1)0%   (0/3)0%   (0/1)
getModel (): Model 0%   (0/1)0%   (0/3)0%   (0/1)
getNameCatalog (): NameCatalog 0%   (0/1)0%   (0/3)0%   (0/1)
getOutputAppendixes (): List 0%   (0/1)0%   (0/106)0%   (0/18)
getOutputPath (): String 0%   (0/1)0%   (0/7)0%   (0/1)
getRealTimeStartTime (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getReferenceUnit (): TimeUnit 0%   (0/1)0%   (0/2)0%   (0/1)
getResourceDB (): ResourceDB 0%   (0/1)0%   (0/3)0%   (0/1)
getScheduler (): Scheduler 0%   (0/1)0%   (0/3)0%   (0/1)
getSimClock (): SimClock 0%   (0/1)0%   (0/4)0%   (0/1)
getStopConditions (): List 0%   (0/1)0%   (0/6)0%   (0/1)
getStopTime (): TimeInstant 0%   (0/1)0%   (0/3)0%   (0/1)
getThreadGroup (): ThreadGroup 0%   (0/1)0%   (0/3)0%   (0/1)
getTimeFloats (): int 0%   (0/1)0%   (0/10)0%   (0/3)
isAborted (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
isConnected (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
isRandomizingConcurrentEvents (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
isRunning (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
isShowProgressBar (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isStopped (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
proceed (): void 0%   (0/1)0%   (0/231)0%   (0/57)
randomizeConcurrentEvents (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
register (OutputType): void 0%   (0/1)0%   (0/30)0%   (0/11)
registerFileOutput (FileOutput): void 0%   (0/1)0%   (0/30)0%   (0/11)
registerModel (Model): void 0%   (0/1)0%   (0/74)0%   (0/29)
removeDebugReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/11)
removeErrorReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/11)
removeReceiver (MessageReceiver): void 0%   (0/1)0%   (0/25)0%   (0/11)
removeReceiver (MessageReceiver, Class): void 0%   (0/1)0%   (0/46)0%   (0/20)
removeStopConditions (): void 0%   (0/1)0%   (0/4)0%   (0/2)
removeTraceReceiver (MessageReceiver): void 0%   (0/1)0%   (0/26)0%   (0/11)
rename (String): void 0%   (0/1)0%   (0/1)0%   (0/1)
report (): void 0%   (0/1)0%   (0/5)0%   (0/2)
report (Model): void 0%   (0/1)0%   (0/82)0%   (0/29)
sendDebugNote (String, String): void 0%   (0/1)0%   (0/15)0%   (0/3)
sendMessage (Message): void 0%   (0/1)0%   (0/23)0%   (0/8)
sendWarning (String, String, String, String): void 0%   (0/1)0%   (0/17)0%   (0/4)
setDelayInMillis (long): void 0%   (0/1)0%   (0/4)0%   (0/2)
setDescription (String): void 0%   (0/1)0%   (0/4)0%   (0/2)
setExecutionSpeedRate (double): void 0%   (0/1)0%   (0/5)0%   (0/2)
setRandomNumberGenerator (Class): void 0%   (0/1)0%   (0/48)0%   (0/18)
setSeedGenerator (long): void 0%   (0/1)0%   (0/5)0%   (0/2)
setShowProgressBar (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setSilent (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setStatus (int): void 0%   (0/1)0%   (0/26)0%   (0/9)
setTimeFormatter (TimeFormatter): void 0%   (0/1)0%   (0/3)0%   (0/2)
setupExperiment (String, String, TimeUnit, TimeUnit, TimeFormatter, ArrayList... 0%   (0/1)0%   (0/359)0%   (0/99)
start (): void 0%   (0/1)0%   (0/14)0%   (0/4)
start (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
start (TimeInstant): void 0%   (0/1)0%   (0/108)0%   (0/35)
stop (): void 0%   (0/1)0%   (0/7)0%   (0/3)
stop (Condition): void 0%   (0/1)0%   (0/27)0%   (0/8)
stop (ModelCondition): void 0%   (0/1)0%   (0/24)0%   (0/8)
stop (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
stop (TimeInstant): void 0%   (0/1)0%   (0/55)0%   (0/15)
traceIsOn (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
traceOff (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
traceOff (TimeInstant): void 0%   (0/1)0%   (0/57)0%   (0/18)
traceOn (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
traceOn (TimeInstant): void 0%   (0/1)0%   (0/72)0%   (0/21)
tracePeriod (SimTime, SimTime): void 0%   (0/1)0%   (0/7)0%   (0/3)
tracePeriod (TimeInstant, TimeInstant): void 0%   (0/1)0%   (0/108)0%   (0/42)
writeReport (Model, String): void 0%   (0/1)0%   (0/55)0%   (0/12)
writeReport (String): void 0%   (0/1)0%   (0/58)0%   (0/14)
     
class Experiment$10%   (0/1)0%   (0/2)0%   (0/9)0%   (0/4)
Experiment$1 (Experiment): void 0%   (0/1)0%   (0/6)0%   (0/2)
windowClosing (WindowEvent): void 0%   (0/1)0%   (0/3)0%   (0/2)

1package desmoj.core.simulator;
2 
3import java.awt.event.WindowAdapter;
4import java.awt.event.WindowEvent;
5import java.io.File;
6import java.util.ArrayList;
7import java.util.List;
8import java.util.concurrent.TimeUnit;
9 
10import javax.swing.JFrame;
11 
12import desmoj.core.dist.DistributionManager;
13import desmoj.core.exception.DESMOJException;
14import desmoj.core.report.DebugNote;
15import desmoj.core.report.ErrorMessage;
16import desmoj.core.report.FileOutput;
17import desmoj.core.report.Message;
18import desmoj.core.report.MessageDistributor;
19import desmoj.core.report.MessageReceiver;
20import desmoj.core.report.OutputType;
21import desmoj.core.report.OutputTypeEndToExport;
22import desmoj.core.report.Reporter;
23import desmoj.core.report.TraceNote;
24 
25/**
26 * Experiment is the class that provides the infrastructure for running the
27 * simulation of a model. It contains all data structures necessary to simulate
28 * the model and takes care of all necessary output. To actually run an
29 * experiment, a new instance of the experiment class and a new instance of the
30 * desired model have to be created. To link both instances, call the
31 * <code>connectToExperiment(Experiment e)</code> method of the model instance
32 * and pass the new experiment as a parameter.
33 * 
34 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
35 * @author Tim Lechler
36 * @author modified by Soenke Claassen, Ruth Meyer, Nicolas Knaak, Gunnar
37 *         Kiesel,Felix Klueckmann
38 * 
39 * Licensed under the Apache License, Version 2.0 (the "License");
40 * you may not use this file except in compliance with the License. You
41 * may obtain a copy of the License at
42 * http://www.apache.org/licenses/LICENSE-2.0
43 *
44 * Unless required by applicable law or agreed to in writing, software
45 * distributed under the License is distributed on an "AS IS"
46 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
47 * or implied. See the License for the specific language governing
48 * permissions and limitations under the License.
49 *
50 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
51 * @modifier new Example Variable _traceOutput, _reportOutput for Outputclasscollection
52 *                          new class constructors 
53 *                          Experiment(String , String , ArrayList<String> , ArrayList<String> ,ArrayList<String> , ArrayList<String> ) and
54 *                          Experiment(String , String , TimeUnit ,TimeUnit , TimeFormatter ,ArrayList<String> , 
55 *                                         ArrayList<String> ,ArrayList<String> ,ArrayList<String> )
56 * @author Xiufeng Li
57 */
58public class Experiment extends NamedObject {
59 
60        /**
61         * The experiment's name catalog for ensuring uniqueness of simulation
62         * object names within a single experiment.
63         */
64        private NameCatalog _nameCatalog = new NameCatalog();
65        
66        /** 
67         * The default report output 
68         */
69        public static final String DEFAULT_REPORT_OUTPUT_TYPE = "desmoj.core.report.HTMLReportOutput";
70 
71        /** 
72         * The default trace output 
73         */
74        public static final String DEFAULT_TRACE_OUTPUT_TYPE = "desmoj.core.report.HTMLTraceOutput";
75 
76        /** 
77         * The default error output 
78         */
79        public static final String DEFAULT_ERROR_OUTPUT_TYPE = "desmoj.core.report.HTMLErrorOutput";
80 
81        /** 
82         * The default debug output 
83         */
84        public static final String DEFAULT_DEBUG_OUTPUT_TYPE = "desmoj.core.report.HTMLDebugOutput";
85 
86        /**
87         * Status of an Experiment just created without any accessories created yet.
88         */
89        public static final int NOT_INITIALIZED = -3;
90 
91        /**
92         * Status of an Experiment instantiated with all needed accessories
93         * available.
94         */
95        public static final int INITIALIZED = -2;
96 
97        /**
98         * Status of an Experiment connected to a Model and ready to be started.
99         */
100        public static final int CONNECTED = -1;
101 
102        /**
103         * Status of an Experiment being started. Only if an Experiment is
104         */
105        public static final int STARTED = 0;
106 
107        /**
108         * Status of an Experiment stopped after having run.
109         */
110        public static final int STOPPED = 1;
111 
112        /**
113         * Status of an Experiment currently running the simulation.
114         */
115        public static final int RUNNING = 2;
116 
117        /**
118         * Status of an Experiment finished and to be cleared.
119         */
120        public static final int ABORTED = 3;
121 
122        /**
123         * The last suffix used with filenames when creating multiple batch runs of
124         * an experiment.
125         */
126        private static int lastSuffix;
127 
128        /**
129         * The class reference to messages of type desmoj.core.report.TraceNote
130         */
131        static Class<desmoj.core.report.TraceNote> tracenote;
132 
133        /**
134         * The class reference to messages of type desmoj.core.report.DebugNote
135         */
136        static Class<desmoj.core.report.DebugNote> debugnote;
137 
138        /**
139         * The class reference to messages of type desmoj.core.report.ErrorMessage
140         */
141        static Class<desmoj.core.report.ErrorMessage> errormessage;
142 
143        /**
144         * The class reference to messages of type desmoj.core.report.Reporter
145         */
146        static Class<desmoj.core.report.Reporter> reporter;
147 
148        /**
149     * Flag indicating to suppress notifications like 'experiment started'.
150     */
151    private boolean _silent;
152    
153    /**
154     * The description of this Experiment
155     */
156    private String _description = null;
157        
158        /**
159         * Flag indicating if the simulation is running.
160         */
161        private int _status;
162 
163        /**
164         * The model to be run by this experiment.
165         */
166        private Model _client;
167 
168        /**
169         * The scheduler used for this experiment.
170         */
171        protected Scheduler clientScheduler;
172 
173        /**
174         * The distribution manager for the model's distributions.
175         */
176        private DistributionManager _distMan;
177 
178        /**
179         * The message manager for the model's messages.
180         */
181        private MessageDistributor _messMan;
182 
183        /**
184         * The ThreadGroup for this Experiment.
185         */
186        private ThreadGroup _expThreads;
187 
188        /**
189         * The list to register all OutputType objects to close them after finishing
190         * the Experiment.
191         */
192        private java.util.ArrayList<OutputType> _registryOutputType;
193 
194        /**
195         * The list to register all FileOutput objects to close them after finishing
196         * the Experiment.
197         */
198        private java.util.ArrayList<FileOutput> _registryFileOutput;
199 
200        /**
201         * The resource database storing all resource allocations and requests. Also
202         * needed to detect deadlocks.
203         */
204        private ResourceDB _resDB;
205 
206        /**
207         * The TimeInstant when the experiment is supposed to stop. Is initially
208         * <code>null</code> and will be set only if the user provides a time limit.
209         */
210        private TimeInstant _stopTime = null;
211        
212   /**
213     * The event to stop the experiment. Is initially <code>null</code> and will 
214     * be set only if the user provides a time limit.
215     */
216    private ExternalEventStop _stopTimeEvent = null;
217        
218    /**
219     * A list of <code>Condition</code>s which cause the experiment to stop. The
220     * user has to implement the <code>check()</code> method of the 
221     * <code>Condition</code>s in order to effectively stop an experiment.
222     */
223    private List<ModelCondition> _stopConditions;
224 
225        /**
226         * Flag indicating whether a progressbar for this experiment should be
227         * displayed or not.
228         */
229        private boolean _showProgressBar;
230 
231        /**
232         * Specifies an output path for the report files (Modification by Nicolas
233         * Knaak, 02/2001)
234         */
235        private String _pathName;
236 
237        /**
238         * Delay between steps of the scheduler in milliseconds. Necessary for
239         * online observation of experiments in FAMOS. (Modification by Nicolas
240         * Knaak, 07/2001)
241         */
242        private long _delayInMillis = 0;
243 
244        /**
245         * The real time (wallclock time) start time of the simulation run.
246         * (Modification by Felix Klueckmann, 05/2009)
247         */
248        private long _realTimeStartTime;
249 
250        /**
251         * The output types of the debug channel.
252     */
253        private ArrayList<OutputType> _debugOutput;
254        
255    /**
256     * The output types of the report channel.
257     */
258        private ArrayList<OutputType> _reportOutput;
259        
260    /**
261     * The output types of the error channel.
262     */
263        private ArrayList<OutputType> _errorOutput;
264 
265    /**
266     * The output types of the trance channel.
267     */
268        private ArrayList<OutputType> _traceOutput;
269        
270        /**
271     * Constructs a new Experiment with a given name.  
272     * Data channel output (report, error, debug, trace) will either be
273     * written to HTML files in the current directory. 
274     * Epsilon (granularity of simulation) defaults to a microsecond,
275     * reference time (default time unit) to a second. 
276         * 
277         * @param name
278         *            String : The name of the experiment determining the
279         *            outputfile's names, too. So please avoid characters that your
280         *            local filesystem does not support in filenames.
281         */
282        public Experiment(String name) {
283                this(name, true);
284        }
285 
286        /**
287         * Constructs a new Experiment with the given parameters. Experiment name can be specified. 
288         * Data channel output (report, error, debug, trace) will either be
289     * suppressed or written to HTML files in the current directory. 
290     * Epsilon (granularity of simulation) defaults to a microsecond,
291     * reference time (default time unit) to a second. 
292         * 
293         * @param name
294         *            String : The name of the experiment determining the
295         *            outputfile's names, too. So please avoid characters that your
296         *            local filesystem does not support in filenames.
297         * @param output
298         *            boolean : This flag indicates if the experiment should write
299         *            output files in the default format (HTML) or no output files
300         *            at all.
301         */
302        public Experiment(String name, boolean output) {
303                this(name, ".", TimeUnit.MICROSECONDS, TimeUnit.SECONDS, null,
304                                output ? DEFAULT_REPORT_OUTPUT_TYPE : null,
305                                output ? DEFAULT_TRACE_OUTPUT_TYPE : null,
306                                output ? DEFAULT_ERROR_OUTPUT_TYPE : null,
307                                output ? DEFAULT_DEBUG_OUTPUT_TYPE : null); // call most special
308                // constructor
309        }
310 
311        /**
312         * Constructs a new Experiment with the given parameters. Experiment name and output path
313         * can be specified. Data channel output (report, error, debug, trace) will either be
314     * written to HTML files, epsilon (granularity of simulation) defaults to a microsecond,
315     * reference time (default time unit) to a second. 
316         * 
317         * @param name
318         *            String : The name of the experiment determining the
319         *            outputfile's names, too. So please avoid characters that your
320         *            local filesystem does not support in filenames.
321         * @param pathName
322         *            java.lang.String : The output path for report files
323         */
324        public Experiment(String name, String pathName) {
325 
326                this(name, pathName, DEFAULT_REPORT_OUTPUT_TYPE,
327                                DEFAULT_TRACE_OUTPUT_TYPE, DEFAULT_ERROR_OUTPUT_TYPE,
328                                DEFAULT_DEBUG_OUTPUT_TYPE);
329                // call more special constructor
330 
331        }
332 
333        /**
334         * Constructs a new Experiment with the given parameters. This is a shortcut
335         * constructor. Parameters for the name, the granularity(epsilon), the
336         * reference time unit and a time formatter are needed. All other possible
337         * settings are set to default values. These settings for an experiment
338         * without special ExperimentOptions are:
339         * <ol>
340         * <li>seed = 979 : The initial seed setting for the seed-generator</li>
341         * </ol>
342         * The default stop condition for this experiment will never interfere,
343         * always returning false.
344         * 
345         * @param name
346         *            String : The name of the experiment determining the
347         *            outputfile's names, too. So please avoid characters that your
348         *            local filesystem does not support in filenames.
349         * @param epsilon
350         *            java.util.concurrent.TimeUnit: The granularity of simulation
351         *            time.
352         * @param referenceUnit
353         *            java.util.concurrent.TimeUnit : In statements without an
354         *            explicit declaration of a TimeUnit the reference unit is used.
355         * @param formatter
356         *            desmoj.core.simulator.TimeFormatter: Defines how time values
357         *            will be formatted in the output files.
358         * 
359         * @see java.util.concurrent.TimeUnit
360         */
361        public Experiment(String name, TimeUnit epsilon, TimeUnit referenceUnit,
362                        TimeFormatter formatter) {
363                // call most special constructor
364                this(name, ".", epsilon, referenceUnit, formatter,
365                                DEFAULT_REPORT_OUTPUT_TYPE, DEFAULT_TRACE_OUTPUT_TYPE,
366                                DEFAULT_ERROR_OUTPUT_TYPE, DEFAULT_DEBUG_OUTPUT_TYPE);
367 
368        }
369        
370    /**
371     * Constructs a new Experiment with the given parameters. Experiment name, output path 
372     * and a single file type per output channel can be specified.
373     * Epsilon (granularity of simulation) defaults to a microsecond,
374     * reference time (default time unit) to a second. 
375     * 
376     * @param name
377     *            String : The name of the experiment determining the
378     *            outputfile's names, too. So please avoid characters that your
379     *            local filesystem does not support in filenames.
380     * @param pathName
381     *            java.lang.String : The output path for report files
382     * @see desmoj.core.simulator.Units
383     * @param reportOutputType
384     * @param traceOutputType
385     * @param errorOutputType
386     * @param debugOutputType
387     */
388    public Experiment(String name, String pathName, String reportOutputType,
389            String traceOutputType, String errorOutputType,
390            String debugOutputType) {
391        this(name, pathName, TimeUnit.MICROSECONDS, TimeUnit.SECONDS, null,
392                reportOutputType, traceOutputType, errorOutputType,
393                debugOutputType);
394    }
395 
396        /**
397     * Constructs a new Experiment with the given parameters. Experiment name, output path, epsilon, reference time unit, time format, 
398     * can be specified. Same holds for file output channels, though this constructor assumes a single file type per output channel.  
399         * 
400         * @param name
401         *            String : The name of the experiment determining the
402         *            outputfile's names, too. So please avoid characters that your
403         *            local filesystem does not support in filenames.
404         * @param pathName
405         *            java.lang.String : The output path for report files
406         * @param epsilon
407         *            java.util.concurrent.TimeUnit: The granularity of simulation
408         *            time.
409         * @param referenceUnit
410         *            java.util.concurrent.TimeUnit : In statements without an
411         *            explicit declaration of a TimeUnit the reference unit is used.
412         * @param formatter
413         *            desmoj.core.simulator.TimeFormatter: Defines how time values
414         *            will be formatted in the output files.
415         * 
416         * @see java.util.concurrent.TimeUnit
417         */
418        public Experiment(String name, String pathName, TimeUnit epsilon,
419                        TimeUnit referenceUnit, TimeFormatter formatter,
420                        String reportOutputType, String traceOutputType,
421                        String errorOutputType, String debugOutputType) {
422                super(name); // create a NamedObject with an attitude ;-)
423                
424                ArrayList<String> reportOutputs = new ArrayList<String>(); if (reportOutputType!=null) reportOutputs.add(reportOutputType);
425                ArrayList<String> traceOutputs = new ArrayList<String>();  if (traceOutputType!=null)  traceOutputs.add(traceOutputType);
426                ArrayList<String> errorOutputs = new ArrayList<String>();  if (errorOutputType!=null)  errorOutputs.add(errorOutputType);
427                ArrayList<String> debugOutputs = new ArrayList<String>();  if (debugOutputType!=null)  debugOutputs.add(debugOutputType);
428                
429                setupExperiment(name, pathName, epsilon, referenceUnit, formatter, reportOutputs, traceOutputs, errorOutputs, debugOutputs);
430        }
431        
432        /**
433         * Constructs a new Experiment with the given parameters. This is the most
434         * flexible constructor. Experiment name, output path, epsilon, reference time unit, time format, 
435         * and multiple file types per output channel can be specified.   
436         * 
437         * @param name
438         *            String : The name of the experiment determining the
439         *            outputfile's names, too. So please avoid characters that your
440         *            local filesystem does not support in filenames.
441         * @param outputPath
442         *            java.lang.String : The output path for report files
443         * @param epsilon
444         *            java.util.concurrent.TimeUnit: The granularity of simulation
445         *            time.
446         * @param referenceUnit
447         *            java.util.concurrent.TimeUnit : In statements without an
448         *            explicit declaration of a TimeUnit the reference unit is used.
449         * @param formatter
450         *            desmoj.core.simulator.TimeFormatter: Defines how time values
451         *            will be formatted in the output files.
452         * 
453         * @see java.util.concurrent.TimeUnit
454         */
455        public Experiment(String name, String outputPath, TimeUnit epsilon,
456                        TimeUnit referenceUnit, TimeFormatter formatter,
457                        ArrayList<String> reportOutputs, ArrayList<String> traceOutputs,
458                        ArrayList<String> errorOutputs, ArrayList<String> debugOutputs)
459        {
460                super(name);
461                setupExperiment(name, outputPath, epsilon, referenceUnit, formatter, reportOutputs, traceOutputs, errorOutputs, debugOutputs);
462        }
463        /**
464     * Constructs a new Experiment with the given parameters. Experiment name, output path 
465     * and a multiple file type per output channel can be specified.
466     * Epsilon (granularity of simulation) defaults to a microsecond,
467     * reference time (default time unit) to a second. 
468         * 
469         * @param name
470         *            String : The name of the experiment determining the
471         *            outputfile's names, too. So please avoid characters that your
472         *            local filesystem does not support in filenames.
473         * @param outputPath
474         *            java.lang.String : The output path for report files
475         * @see desmoj.core.simulator.Units
476         */
477        public Experiment(String name, String outputPath,
478                        ArrayList<String> reportOutputs, ArrayList<String> traceOutputs,
479                        ArrayList<String> errorOutputs, ArrayList<String> debugOutputs) {
480        this(name, outputPath, TimeUnit.MICROSECONDS, TimeUnit.SECONDS, null,
481                reportOutputs, traceOutputs, errorOutputs,
482                debugOutputs);
483        }
484        
485        
486        /**
487     * Private helper method to initialize the experiment; should be called
488     * from all constructors.
489     * 
490     * @param name
491     *            String : The name of the experiment determining the
492     *            outputfile's names, too. So please avoid characters that your
493     *            local filesystem does not support in filenames.
494     * @param outputPath
495     *            java.lang.String : The output path for report files
496     * @param epsilon
497     *            java.util.concurrent.TimeUnit: The granularity of simulation
498     *            time.
499     * @param referenceUnit
500     *            java.util.concurrent.TimeUnit : In statements without an
501     *            explicit declaration of a TimeUnit the reference unit is used.
502     * @param formatter
503     *            desmoj.core.simulator.TimeFormatter: Defines how time values
504     *            will be formatted in the output files.
505     * 
506     * @see java.util.concurrent.TimeUnit
507     */
508    private void setupExperiment(String name, String outputPath, TimeUnit epsilon,
509            TimeUnit referenceUnit, TimeFormatter formatter,
510            ArrayList<String> reportOutputs, ArrayList<String> traceOutputs,
511            ArrayList<String> errorOutputs, ArrayList<String> debugOutputs)
512    {
513        // initialize variables
514        _traceOutput = new ArrayList<OutputType>();
515        _debugOutput = new ArrayList<OutputType>();
516        _errorOutput = new ArrayList<OutputType>();
517        _reportOutput = new ArrayList<OutputType>();
518        _status = NOT_INITIALIZED;
519        _stopConditions = new ArrayList<ModelCondition>(); // empty, i.e. no Stopper
520                                                        // can be set at
521                                                        // instantiation time
522        _expThreads = new ThreadGroup(name);
523        _registryFileOutput = new ArrayList<FileOutput>();
524        _registryOutputType = new ArrayList<OutputType>();
525        lastSuffix = 0; // no batches have run so far ;-)
526        _showProgressBar = true; // display a progress bar for this experiment
527        _silent = false; // notify the user about what is going on
528 
529        // Check and set output path
530//      if (pathName == null
531//              || (pathName != null && (pathName.isEmpty() || pathName
532//                      .equals("."))))
533//          this.pathName = System.getProperty("user.dir", ".");
534//      else
535            this._pathName = outputPath;
536 
537        // set class variables for basic messagetypes
538        try
539        {
540            tracenote = (Class<TraceNote>) Class
541                    .forName("desmoj.core.report.TraceNote");
542            debugnote = (Class<DebugNote>) Class
543                    .forName("desmoj.core.report.DebugNote");
544            errormessage = (Class<ErrorMessage>) Class
545                    .forName("desmoj.core.report.ErrorMessage");
546            reporter = (Class<Reporter>) Class
547                    .forName("desmoj.core.report.Reporter");
548        } catch (ClassNotFoundException cnfEx)
549        {
550            System.err.println("Can not create Experiment!");
551            System.err.println("Constructor of desmoj.core.Experiment.");
552            System.err.println("Classes are probably not installed correctly.");
553            System.err.println("Check your CLASSPATH setting.");
554            System.err.println("Exception caught : " + cnfEx);
555        }
556 
557        // create output system first
558        _messMan = new MessageDistributor();
559 
560        // create and register the debug output
561        for (String debugOutputType : debugOutputs)
562        {
563            try
564            {
565                Class<OutputType> debugOType = (Class<OutputType>) Class
566                        .forName((debugOutputType != null) ? debugOutputType
567                                : DEFAULT_DEBUG_OUTPUT_TYPE);
568                OutputType dbg = debugOType.newInstance();
569                _debugOutput.add(dbg);
570                if (debugOutputType != null)
571                    dbg.open(_pathName, name);
572                _messMan.register(dbg, debugnote);
573                _messMan.switchOff(debugnote);
574                register(dbg);
575            } catch (Exception e)
576            {
577                System.err.println(e.toString());
578            }
579        }
580 
581        // create and register the report output
582        for (String reportOutputType : reportOutputs)
583        {
584            try
585            {
586                Class<OutputType> reportOType = (Class<OutputType>) Class
587                        .forName((reportOutputType != null) ? reportOutputType
588                                : DEFAULT_REPORT_OUTPUT_TYPE);
589                OutputType rpt = reportOType.newInstance();
590                _reportOutput.add(rpt);
591                if (reportOutputType != null)
592                    rpt.open(_pathName, name);
593                _messMan.register(rpt, reporter);
594                register(rpt);
595            } catch (Exception e)
596            {
597                System.err.println(e.toString());
598            }
599        }
600 
601        // create and register the error output
602        for (String errorOutputType : errorOutputs)
603        {
604            try
605            {
606                Class<OutputType> errorOType = (Class<OutputType>) Class
607                        .forName((errorOutputType != null) ? errorOutputType
608                                : DEFAULT_ERROR_OUTPUT_TYPE);
609                OutputType err = errorOType.newInstance();
610                _errorOutput.add(err);
611                // err.setTimeFloats(timeFloats);
612                if (errorOutputType != null)
613                    err.open(_pathName, name);
614                _messMan.register(err, errormessage);
615                register(err);
616            } catch (Exception e)
617            {
618                System.err.println(e.toString());
619            }
620        }
621        // create and register the trace output
622        for (String traceOutputType : traceOutputs)
623        {
624            try
625            {
626 
627                Class<OutputType> traceOType = (Class<OutputType>) Class
628                        .forName((traceOutputType != null) ? traceOutputType
629                                : DEFAULT_TRACE_OUTPUT_TYPE);
630                OutputType trc = traceOType.newInstance();
631                _traceOutput.add(trc);
632                if (traceOutputType != null)
633                    trc.open(_pathName, name);
634                _messMan.register(trc, tracenote);
635                _messMan.switchOff(tracenote);
636                register(trc);
637            } catch (Exception e)
638            {
639                System.err.println(e.toString());
640            }
641        }
642 
643        // create the distributionmanager to register distributions at
644        _distMan = new DistributionManager(name, 979);
645 
646        // now create the simulation runtime accessories
647        _client = null; // no object connected
648 
649        // check for null reference
650        if (epsilon == null)
651        {
652            // set to default unit
653            epsilon = TimeUnit.MICROSECONDS;
654        }
655        if (referenceUnit == null)
656        {
657            // set to default unit
658            referenceUnit = TimeUnit.SECONDS;
659        }
660        // interchange epsilon and reference unit if the reference unit has a
661        // finer granularity than epsilon
662        if (referenceUnit.compareTo(epsilon) < 0)
663        {
664            TimeUnit buffer = referenceUnit;
665            referenceUnit = epsilon;
666            epsilon = buffer;
667        }
668        // set epsilon and referenceUnit
669        TimeOperations.setEpsilon(epsilon);
670        TimeOperations.setReferenceUnit(referenceUnit);
671 
672        // check for null reference
673        if (formatter == null)
674        {
675            formatter = new SingleUnitTimeFormatter(referenceUnit, epsilon, 4,
676                    false);
677        }
678        TimeOperations.setTimeFormatter(formatter);
679 
680        // building the scheduler: prepare event list...
681        // (for efficiency reasons, we use the TreeList-basd implementation)
682        EventList eventList = new EventTreeList();
683 
684        // create the scheduler (and clock)
685        clientScheduler = createScheduler(name, eventList);
686 
687        // create a resource database and tell it that it belongs to this
688        // experiment
689        _resDB = new ResourceDB(this);
690 
691        // set status to first valid value - initialized, but not connected
692        _status = INITIALIZED;
693    }
694        
695        /**
696         * Creates a scheduler for this experiment.
697         * 
698         * @param name
699         *            experiment name
700         * @return a new scheduler
701         */
702        protected Scheduler createScheduler(String name, EventList evl) {
703                Scheduler s = new Scheduler(this, name, evl);
704                return s;
705        }
706 
707        /**
708         * Adds a messagereceiver for debugnotes to the experiment. Whenever a model
709         * produces a message of that type, it will also be sent to the given
710         * messagereceiver for further processing. Note that the given receiver must
711         * be capable of handling debugnotes.
712         * 
713         * @param trcRec
714         *            desmoj.report.MessageReceiver : The new messagereceiver for
715         *            the given type of messages
716         */
717        public void addDebugReceiver(MessageReceiver trcRec) {
718 
719                if (trcRec == null) {
720                        sendWarning("Can not add receiver to experiment! Command ignored.",
721                                        "Experiment '" + getName()
722                                                        + "', method 'void addDebugReceiver("
723                                                        + "MessageReceiver trcRec)'",
724                                        "The parameter 'trc' passed was a null reference.",
725                                        "Make sure to construct a valid MessageReciever before adding it to "
726                                                        + "the experiment's messaging system.");
727                        return; // do nothing
728                }
729 
730                _messMan.register(trcRec, debugnote);
731 
732        }
733 
734        /**
735         * Adds a messagereceiver for error messages to the experiment. Whenever a
736         * model produces a message of that type, it will also be sent to the given
737         * messagereceiver for further processing. Note that the given receiver must
738         * be capable of handling messagereceiver.
739         * 
740         * @param trcRec
741         *            desmoj.report.MessageReceiver : The new messagereceiver for
742         *            the given type of messages
743         */
744        public void addErrorReceiver(MessageReceiver trcRec) {
745 
746                if (trcRec == null) {
747                        sendWarning("Can not add receiver to experiment! Command ignored.",
748                                        "Experiment '" + getName()
749                                                        + "', method 'void addErrorReceiver("
750                                                        + "MessageReceiver trcRec)'",
751                                        "The parameter 'trc' passed was a null reference.",
752                                        "Make sure to construct a valid MessageReciever before adding it to "
753                                                        + "the experiment's messaging system.");
754                        return; // do nothing
755                }
756 
757                _messMan.register(trcRec, errormessage);
758 
759        }
760 
761        /**
762         * Returns the experiments name catalog for ensuring unique names of
763         * simulation objects within a single experiment.
764         */
765        NameCatalog getNameCatalog() {
766                return _nameCatalog;
767        }
768 
769        /**
770         * Adds a messagereceiver for the given subtype of message to the
771         * experiment. Whenever a model produces a message of that type, it will
772         * also be sent to the given messagereceiver for further processing.
773         * 
774         * @param trcRec
775         *            desmoj.report.MessageReceiver : The new messagereceiver for
776         *            the given type of messages
777         * @param messageType
778         *            Class : The type of message to be sent to the given
779         *            messagereceiver
780         */
781        public void addReceiver(MessageReceiver trcRec, Class<?> messageType) {
782 
783                if (trcRec == null) {
784                        sendWarning("Can not add receiver to experiment! Command ignored.",
785                                        "Experiment '" + getName()
786                                                        + "', method 'void addReceiver(MessageReceiver "
787                                                        + "trcRec, Class messageType)'",
788                                        "The parameter 'trc' passed was a null reference.",
789                                        "Make sure to construct a valid MessageReciever before adding it to "
790                                                        + "the experiment's messaging system.");
791                        return; // do nothing
792                }
793 
794                if (messageType == null) { // again these damned null values
795                        sendWarning("Can not add receiver to experiment! Command ignored.",
796                                        "Experiment '" + getName()
797                                                        + "', method 'void addReceiver(MessageReceiver "
798                                                        + "trcRec, Class messageType)'",
799                                        "The parameter 'messageType' passed was a null reference.",
800                                        "Make sure to construct a valid Class object before adding it to "
801                                                        + "the experiment's messaging system.");
802                        return; // do nothing
803                }
804 
805                _messMan.register(trcRec, messageType);
806 
807        }
808 
809        /**
810         * Adds a messagereceiver for tracenotes to the experiment. Whenever a model
811         * produces a message of that type, it will also be sent to the given
812         * messagereceiver for further processing. Note that the given Receiver must
813         * be capable of handling tracenotes.
814         * 
815         * @param trcRec
816         *            desmoj.report.MessageReceiver : The new messagereceiver for
817         *            the given type of messages
818         */
819        public void addTraceReceiver(MessageReceiver trcRec) {
820 
821                if (trcRec == null) {
822                        sendWarning("Can not add receiver to experiment! Command ignored.",
823                                        "Experiment '" + getName()
824                                                        + "', method 'void addTraceReceiver("
825                                                        + "MessageReceiver trcRec)'",
826                                        "The parameter 'trc' passed was a null reference.",
827                                        "Make sure to construct a valid MessageReciever before adding it to "
828                                                        + "the experiment's messaging system.");
829                        return; // do nothing
830                }
831 
832                _messMan.register(trcRec, tracenote);
833 
834        }
835 
836        /**
837         * Returns a boolean indicating whether debug notes are forwarded to the
838         * debug ouput or not. Debug ouput can be switched on and off using the
839         * methods <code>debugOn(TimeInstant startTime)</code> or
840         * <code>debugOff(TimeInstant stopTime)</code>
841         * 
842         * @return boolean
843         */
844        public boolean debugIsOn() {
845 
846                return _messMan.isOn(debugnote);
847 
848        }
849 
850        /**
851         * Switches the debug output off at the given point of simulation time.
852         * 
853         * @param stopTime
854         *            TimeInstant : The point in simulation time to switch off debug
855         */
856        public void debugOff(TimeInstant stopTime) {
857 
858                // check initial TimeInstant parameter
859                if (stopTime == null) {
860                        sendWarning(
861                                        "Invalid start time parameter for debug output given! "
862                                                        + "StopTime is set to current time.",
863                                        "Experiment '" + getName()
864                                                        + "', method 'void debugOn(TimeInstant startTime)'",
865                                        "A null value or a not initialized TimeInstant reference has been passed.",
866                                        "Make sure to have a valid TimeInstant object, otherwise use method "
867                                                        + "start() without TimeInstant parameter.");
868                        stopTime = clientScheduler.presentTime();
869                }
870 
871                // check if parameter is in future
872                if (TimeInstant.isAfter(clientScheduler.presentTime(), stopTime)) {
873                        sendWarning("Invalid start time parameter for debug output given! "
874                                        + "StopTime is set to current time.", "Experiment '"
875                                        + getName()
876                                        + "', method 'void debugOn(TimeInstant stopTime)'",
877                                        "The stopTime given is in the past.",
878                                        "Make sure to give a TimeInstant parameter larger than the current time.");
879                        stopTime = clientScheduler.presentTime();
880                }
881 
882                ExternalEvent debugOff = new ExternalEventDebugOff(_client, true);
883 
884                debugOff.schedule(stopTime);
885 
886        }        
887           
888    /**
889     * @deprecated Use debugOff(TimeInstant startTime). Switches the debug output off at the given point of simulation time.
890     * 
891     * @param stopTime
892     *            SimTime : The point in simulation time to switch debug off
893     */
894    public void debugOff(SimTime stopTime) {
895        this.debugOff(SimTime.toTimeInstant(stopTime));        
896    }
897 
898        /**
899         * Switches the debug output on at the given point of simulation time.
900         * 
901         * @param startTime
902         *            TimeInstant : The point in simulation time to switch on debug
903         */
904        public void debugOn(TimeInstant startTime) {
905 
906                // check initial TimeInstant parameter
907                if (startTime == null) {
908                        sendWarning(
909                                        "Invalid start time parameter for debug output given! "
910                                                        + "StartTime is set to current time.",
911                                        "Experiment '" + getName()
912                                                        + "', method 'void debugOn(TimeInstant startTime)'",
913                                        "A null value or a not initialized TimeInstant reference has been passed.",
914                                        "Make sure to have a valid TimeInstant object, otherwise use method "
915                                                        + "start() without TimeInstant parameter.");
916                        startTime = clientScheduler.presentTime();
917                }
918 
919                // check if parameter is in future
920                if (TimeInstant.isAfter(clientScheduler.presentTime(), startTime)) {
921                        sendWarning("Invalid start time parameter for debug output given! "
922                                        + "StartTime is set to current time.", "Experiment '"
923                                        + getName()
924                                        + "', method 'void debugOn(TimeInstant startTime)'",
925                                        "The startTime given is in the past.",
926                                        "Make sure to give a TimeInstant parameter larger than the current time.");
927                        startTime = clientScheduler.presentTime();
928                }
929 
930        // if parameter equals current time, set trace on immediately, e.g. 
931        // to include initial scheduling
932        if (TimeInstant.isEqual(clientScheduler.presentTime(), startTime)) {
933            this.getMessageManager().switchOn(Experiment.debugnote);
934            _client.sendTraceNote("Debug switched on");
935        // Otherwise schedule an appropriate event    
936        } else {
937            ExternalEvent debugOn = new ExternalEventDebugOn(_client, true);
938            debugOn.schedule(startTime);
939        }
940 
941        }
942    
943    /**
944     * @deprecated Use debugOn(TimeInstant startTime). Switches the debug output on at the given point of simulation time.
945     * 
946     * @param startTime
947     *            SimTime : The point in simulation time to switch debug on
948     */
949    public void debugOn(SimTime startTime) {
950        this.debugOn(SimTime.toTimeInstant(startTime));        
951    }
952 
953        /**
954         * Switches the debug output on for the given period of simulation time. If
955         * the second parameter (off) is "sooner" then the first parameter (on),
956         * they will be swapped automatically. Same parameters will result in no
957         * debug output at all!
958         * 
959         * @param startTime
960         *            TimeInstant : The point in simulation time to switch debug on
961         * @param stopTime
962         *            TimeInstant : The point in simulation time to switch debug off
963         */
964        public void debugPeriod(TimeInstant startTime, TimeInstant stopTime) {
965                // check initial TimeInstant parameter
966                if (startTime == null) {
967                        sendWarning(
968                                        "Invalid start time parameter for debug output given! Command ignored",
969                                        "Experiment '" + getName()
970                                                        + "', Method 'debugPeriod(TimeInstant startTime, "
971                                                        + "TimeInstant stopTime)'",
972                                        "A null value or a not initialized TimeInstant reference has been passed.",
973                                        "Make sure to have a valid TimeInstant object.");
974                        return;
975                }
976 
977                // check initial TimeInstant parameter
978                if (stopTime == null) {
979                        sendWarning(
980                                        "Invalid stop time parameter for debug output given! Command ignored.",
981                                        "Experiment '" + getName()
982                                                        + "', Method 'debugPeriod(TimeInstant startTime, "
983                                                        + "TimeInstant stopTime)'",
984                                        "A null value or a not initialized TimeInstant reference has been passed.",
985                                        "Make sure to have a valid TimeInstant object.");
986                        return;
987                }
988 
989                // check for correct order in parameters
990                if (TimeInstant.isAfter(startTime, stopTime)) {
991 
992                        // swap parameters
993                        TimeInstant buffer = stopTime;
994                        stopTime = startTime;
995                        startTime = buffer;
996 
997                }
998 
999                // check if stop parameter is in future
1000                if (TimeInstant.isAfter(clientScheduler.presentTime(), stopTime)) {
1001                        sendWarning(
1002                                        "Invalid stop time parameter for debug output given! Command ignored.",
1003                                        "Experiment '" + getName()
1004                                                        + "', Method 'debugPeriod(TimeInstant startTime, "
1005                                                        + "TimeInstant stopTime)'",
1006                                        "The stopTime given is in the past.",
1007                                        "Make sure to give a TimeInstant parameter larger than the current time.");
1008                        return;
1009                }
1010 
1011                // check if start parameter is in past
1012                if (TimeInstant.isAfter(clientScheduler.presentTime(), startTime)) {
1013                        sendWarning("Invalid start time parameter for debug output given! "
1014                                        + "Debug output has been set to start immediately.",
1015                                        "Experiment '" + getName()
1016                                                        + "', Method 'debugPeriod(TimeInstant startTime, "
1017                                                        + "TimeInstant stopTime)'",
1018                                        "The startTime given is in the past.",
1019                                        "Make sure to give a TimeInstant parameter larger than the current time.");
1020                        startTime = clientScheduler.presentTime();
1021                }
1022 
1023                // set debug to switch on
1024                debugOn(startTime);
1025 
1026                // set debug to switch off
1027                debugOff(stopTime);
1028        }
1029 
1030        /**
1031         * @deprecated Replaced by debugTime(TimeInstant a, TimeInstant b). Switches
1032         *             the debug output on for the given period of simulation time.
1033         *             If the second parameter (off) is "sooner" then the first
1034         *             parameter (on), they will be swapped automatically. Same
1035         *             parameters will result in no debug output at all!
1036         * 
1037         * @param startTime
1038         *            SimTime : The point in simulation time to switch debug on
1039         * @param stopTime
1040         *            SimTime : The point in simulation time to switch debug off
1041         */
1042        @Deprecated
1043        public void debugPeriod(SimTime startTime, SimTime stopTime) {
1044                debugPeriod(SimTime.toTimeInstant(startTime), SimTime
1045                                .toTimeInstant(stopTime));
1046        }
1047 
1048        /**
1049         * De-registers a file at the experiment. Registered files will be flushed
1050         * and closed after the experiment has finished. If the file is manually
1051         * closed by the user and has been registered at the Experiment, deRegister
1052         * it
1053         * 
1054         * @param file
1055         *            desmoj.report.FileOutput : The file to be closed with the end
1056         *            of an Experiment
1057         */
1058        public void deRegister(FileOutput file) {
1059 
1060                if (file == null) {
1061                        sendWarning("Can not de-register FileOutput! Command ignored.",
1062                                        "Experiment '" + getName()
1063                                                        + "' method 'void deRegister(FileOutput file).'",
1064                                        "The parameter given was a null reference.",
1065                                        "Make sure to only connect valid FileOutputs at the Experiment.");
1066                        return;
1067                }
1068 
1069                _registryFileOutput.remove(file);
1070                // remove whether it was inside or not
1071 
1072        }
1073 
1074        /**
1075         * Stopps all running simprocesses that might still be scheduled and closes
1076         * the output files.
1077         */
1078        public void finish() {
1079 
1080                // check if experiment has not been aborted before
1081                if (_status >= ABORTED)        {
1082                        return;
1083                }
1084 
1085                if (_traceOutput != null)                {
1086                        for (OutputType trc : _traceOutput)                        
1087                        {
1088                                if (trc instanceof OutputTypeEndToExport)                                {
1089                                        ((OutputTypeEndToExport) trc).export(_pathName, getName());
1090                                }
1091                        }
1092                }
1093                if (_debugOutput != null) {
1094                        for (OutputType dbg : _debugOutput)        {
1095                                if (dbg instanceof OutputTypeEndToExport) {
1096                                        ((OutputTypeEndToExport) dbg).export(_pathName, getName());
1097                                }
1098                        }
1099                }
1100                if (_errorOutput != null) {
1101                        for (OutputType err : _errorOutput) {
1102                                if (err instanceof OutputTypeEndToExport) {
1103                                        ((OutputTypeEndToExport) err).export(_pathName, getName());
1104                                }
1105                        }
1106                }
1107                if (_reportOutput != null){
1108                        for (OutputType rpt : _reportOutput) {
1109                                if (rpt instanceof OutputTypeEndToExport){
1110                                        ((OutputTypeEndToExport) rpt).export(_pathName, getName());
1111                                }
1112                        }
1113                }
1114 
1115                // set status to let all simthreads be killed
1116                _status = ABORTED;
1117 
1118                // close all files still open
1119                for (OutputType o : _registryOutputType)
1120                        o.close();
1121                for (FileOutput f : _registryFileOutput)
1122                        f.close();
1123 
1124                // kill all SimThreads still active
1125                Thread[] survivors = new Thread[_expThreads.activeCount()];
1126                _expThreads.enumerate(survivors);
1127 
1128                for (int i = 0; i < survivors.length; i++)                {
1129 
1130                        // print existing threads for controlling purposes only
1131                        // System.out.println(survivors[i]);
1132 
1133                        // if we get the enumeration of survivors, some of them
1134                        // might not have made it until here and die in between
1135                        // so an occasional NullPointerException is perfectly
1136                        // alright and no reason to worry -> we just dump it.
1137                        if (survivors[i] instanceof SimThread)                        {
1138                                try                                {
1139                                        ((SimThread) survivors[i]).kill();
1140                                } catch (NullPointerException e)                                {
1141                                        ; // forget it anyway...
1142                                }
1143                        }
1144                }
1145 
1146        }
1147 
1148        /**
1149         * Returns the distributionmanager for this experiment. Distributions need
1150         * access to the distributionmanager for handling antithetic modes,
1151         * resetting and their initial seeds.
1152         * 
1153         * @return desmoj.dist.DistributionManager : The distributionmanager for
1154         *         this experiment
1155         */
1156        public DistributionManager getDistributionManager() {
1157 
1158                return _distMan;
1159 
1160        }
1161 
1162        /**
1163         * Returns the epsilon value representing the granularity 
1164         * of simulation time for this experiment. So far, Hour, Minute,
1165         * Second and Millisecond are supported.
1166         * Default (unless set explicitly) is TimeUnit.MICROSECONDS.
1167         * 
1168         * @return TimeUnit : The Granularity of the simulation time
1169         */        
1170        public TimeUnit getEpsilonUnit() {
1171 
1172                return TimeOperations.getEpsilon();
1173        }
1174        
1175    /**
1176     * @deprecated Use getEpsilonUnit(). 
1177     * Returns a SimTime representation of the granularity of simulation time 
1178     * for this experiment. So far, Hour, Minute,
1179     * Second and Millisecond are supported.
1180     * 
1181     * @return SimTime : The Granularity of the simulation time
1182     */ 
1183    public SimTime getEpsilon() {
1184 
1185        return SimTime.toSimTime(new TimeSpan (1L, TimeOperations.getEpsilon()));
1186    }
1187 
1188        /**
1189         * Returns the current execution Speed Rate.
1190         * 
1191         * @return double : The current execution speed rate.
1192         */
1193        public double getExecutionSpeedRate() {
1194                return this.clientScheduler.getExecutionSpeedRate();
1195        }
1196 
1197        /**
1198         * Returns the messagemanager for this experiment. Messages need access to
1199         * the MessageManager for distributing the messages to one or more specified
1200         * output streams.
1201         * 
1202         * @return desmoj.dist.MessageManager : The messagemanager for this
1203         *         experiment
1204         */
1205        public MessageDistributor getMessageManager() {
1206 
1207                return _messMan;
1208 
1209        }
1210        
1211        /**
1212         * Returns the model that is connected to this experiment or
1213         * <code>null</code> if no model is connected so far.
1214         * 
1215         * @return Model : The model that this experiment is connected to or
1216         *         <code>null</code> if no connection is established.
1217         */
1218        public Model getModel() {
1219 
1220                return _client;
1221 
1222        }
1223 
1224        /**
1225         * Returns the name of the path the experiment's report-, trace-, debug- and
1226         * error-files are written to.
1227         * 
1228         * @return String the experiment's output path
1229         */
1230        public String getOutputPath() {
1231                return new File(_pathName).getAbsolutePath();
1232        }
1233 
1234        public List<List<String>> getOutputAppendixes() {
1235            
1236            List<List<String>> appendixes = new ArrayList<List<String>>();
1237            
1238            ArrayList<String> debugAppendixes = new ArrayList<String>(); 
1239            for (OutputType o : this._debugOutput) {
1240                debugAppendixes.add(o.getAppendix());
1241            }
1242            appendixes.add(debugAppendixes);
1243            
1244        ArrayList<String> traceAppendixes = new ArrayList<String>(); 
1245        for (OutputType o : this._debugOutput) {
1246            traceAppendixes.add(o.getAppendix());
1247        }
1248        appendixes.add(traceAppendixes);
1249        
1250        ArrayList<String> errorAppendixes = new ArrayList<String>(); 
1251        for (OutputType o : this._debugOutput) {
1252            errorAppendixes.add(o.getAppendix());
1253        }
1254        appendixes.add(errorAppendixes);
1255        
1256        ArrayList<String> reportAppendixes = new ArrayList<String>(); 
1257        for (OutputType o : this._debugOutput) {
1258            reportAppendixes.add(o.getAppendix());
1259        }
1260        appendixes.add(reportAppendixes);
1261            
1262                return appendixes;
1263        }
1264 
1265        public long getRealTimeStartTime() {
1266                return _realTimeStartTime;
1267        }
1268 
1269        /**
1270         * Returns the reference unit for this experiment. This is the time unit
1271         * mapped to a time step of 1.0 in simulation time. So far, Hour, Minute,
1272         * Second and Millisecond are supported. 
1273         * Default (unless set explicitly) is TimeUnit.SECONDS.
1274         * 
1275         * @return TimeUnit : The reference unit.
1276         */
1277        public TimeUnit getReferenceUnit() {
1278                return TimeOperations.getReferenceUnit();
1279        }
1280 
1281        /**
1282         * Returns the resource database for this experiment. The <code>Res</code>
1283         * objects need access to the resource database to note their resource
1284         * allocations and requests and for deadlock detection.
1285         * 
1286         * @return desmoj.ResourceDB : the resource database storing all resource
1287         *         allocations and requests.
1288         * @author Soenke Claassen
1289         */
1290        public ResourceDB getResourceDB() {
1291 
1292                return _resDB;
1293        }
1294 
1295        /**
1296         * Returns the scheduler for this experiment. ModelComponents need access to
1297         * the scheduler for identifying the current active entity or process and to
1298         * schedule themselves or other schedulables to activate at a given time in
1299         * the future.
1300         * 
1301         * @return Scheduler : The scheduler for this experiment
1302         */
1303        public Scheduler getScheduler() {
1304 
1305                return clientScheduler;
1306 
1307        }
1308 
1309        /**
1310         * Returns the simclock for this experiment. ModelComponents need access to
1311         * the simclock for retrieveing the current simulation time.
1312         * 
1313         * @return SimCLock : The simclock for this experiment
1314         */
1315        public SimClock getSimClock() {
1316 
1317                return clientScheduler.getSimClock();
1318 
1319        }
1320 
1321        /**
1322         * Returns the TimeInstant when the experiment is expected to stop running.
1323         * 
1324         * @return desmoj.TimeInstant : The time, the experiment is expected to stop
1325         *         running.
1326         */
1327        public TimeInstant getStopTime() {
1328 
1329                return _stopTime;
1330        }
1331        
1332    /**
1333     * Returns the Conditions which can cause an experiment to stop.
1334     * May be empty if there are no such Conditions.
1335     *
1336     * @return Condition
1337     * @author Tim Janz
1338     */
1339     public List<ModelCondition> getStopConditions() {
1340     
1341            return new java.util.ArrayList<ModelCondition>(this._stopConditions);
1342     }
1343     
1344     /**
1345      * Removes all conditions set to stop the experiment.
1346      */
1347      public void removeStopConditions() {
1348      
1349             this._stopConditions.clear();
1350      }
1351 
1352        /**
1353         * Returns the threadgroup associated to this experiment. All Threads are
1354         * associated to this threadgroup to get control of their number and state
1355         * and to have a means to differentiate them from possible other
1356         * experiments' threads.
1357         * 
1358         * @return java.lang.ThreadGroup
1359         */
1360        ThreadGroup getThreadGroup() {
1361 
1362                return _expThreads;
1363 
1364        }
1365        
1366        /**
1367     * @deprecated Depends on TimeFormatter in use. Returns the experiment's number 
1368     * of floating point digits of simulation time that are displayed in the various output files,
1369     * as read from the SingleUnitTimeFormatter, if in use. Otherwise, 0 will be returned.
1370     * 
1371     * @return int : The number of floating point digits of simulation time to
1372     *         be displayed in output files
1373     */
1374    public int getTimeFloats() {
1375        
1376        if (TimeOperations.getTimeFormatter() instanceof SingleUnitTimeFormatter) {
1377            return (int) ((SingleUnitTimeFormatter)TimeOperations.getTimeFormatter())._floats;
1378        } else 
1379            return 0;
1380    }
1381 
1382        /**
1383         * Displays the current state of the simulation run. If an experient is
1384         * aborted, it can not be proceeded. All SimThreads still active are
1385         * stopped, the main routine can finish.
1386         * 
1387         * @return boolean : Is <code>true</code> if the simulation is aborted,
1388         *         <code>false</code> if it has not started yet or is still running
1389         */
1390        public boolean isAborted() {
1391 
1392                return (_status >= ABORTED);
1393 
1394        }
1395 
1396        /**
1397         * Shows if this experiment has already been connected to a model.
1398         * 
1399         * @return boolean : Is <code>true</code>, if experiment is connected to a
1400         *         model, <code>false</code> otherwise
1401         */
1402        public boolean isConnected() {
1403 
1404                return (_status >= CONNECTED); // model connected
1405 
1406        }
1407 
1408        /**
1409         * Returns if the event-list processes concurrent Events in random order or
1410         * not. Default is not.
1411         * 
1412         * @return boolean: <code>true</code> if concurrent Events are randomized,
1413         *         <code>false</code> otherwise
1414         * @author Ruth Meyer
1415         */
1416        public boolean isRandomizingConcurrentEvents() {
1417                return clientScheduler.isRandomizingConcurrentEvents();
1418        }
1419 
1420        /**
1421         * Displays the current state of the simulation run.
1422         * 
1423         * @return boolean : Is <code>true</code> if the simulation is running,
1424         *         <code>false</code> if it has not started yet or has already
1425         *         finished
1426         */
1427        public boolean isRunning() {
1428 
1429                return (_status == RUNNING);
1430 
1431        }
1432 
1433        /**
1434         * Returns if a progress bar should be displayed for this experiment or not.
1435         * 
1436         * @return boolean :<code>true</code> if a progress bar should be displayed
1437         *         for this experiment, <code>false</code> otherwise.
1438         */
1439        public boolean isShowProgressBar() {
1440 
1441                return _showProgressBar;
1442        }
1443 
1444        /**
1445         * Displays the current state of the simulation run. If an experient is
1446         * stopped, it can be proceeded by calling proceed().
1447         * 
1448         * @return boolean : Is <code>true</code>, if experiment is stopped,
1449         *         <code>false</code> otherwise
1450         */
1451        public boolean isStopped() {
1452 
1453                return (_status == STOPPED); // model stopped
1454 
1455        }
1456 
1457        /**
1458         * Proceeds with a stopped experiment. An experiment can be stopped, if
1459         * either its status is changed from <code>RUNNING</code> to some other
1460         * state, the scheduler runs out of scheduled events or if the
1461         * <code>check()</code> method of the given stop <code>Condition</code>
1462         * returns <code>true</code> after an event has been processed.
1463         */
1464        public void proceed() {
1465 
1466                if (_status < STARTED) {
1467                        sendWarning(
1468                                        "Can not proceed with Experiment! Command ignored.",
1469                                        "Experiment: " + getName() + " Method: void proceed().",
1470                                        "The Experiment has not been started yet.",
1471                                        "Only Experiments that have been stopped after method 'start()' has "
1472                                                        + "been called can use method 'proceed()' to continue.");
1473                        return;
1474                }
1475 
1476                if (_status > STOPPED) {
1477                        sendWarning("Can not proceed with Experiment! Command ignored.",
1478                                        "Experiment " + getName() + " Method: void proceed().",
1479                                        "The Experiment has already been aborted.",
1480                                        "Use method 'proceed()' only on stopped experiments.");
1481                        return;
1482                }
1483                if (_status == STARTED) {
1484                        // print status message to calm users waiting long, long, long
1485                        // hours...
1486                        if (!_silent) System.out.println("***** DESMO-J version " + getDesmoJVersion()
1487                                        + " ***** \n" + getName() + " starts at simulation time "
1488                                        + getScheduler().presentTime() + "\n ...please wait...");
1489                }
1490                else{
1491                    if (!_silent) System.out.println(getName() + " resumes at simulation time "
1492                                        + getScheduler().presentTime() + "\n ...please wait...");
1493                }
1494                // display a progress bar if stop time is known and showProgressBar is
1495                // true
1496                if (_stopTime != null && _showProgressBar) {
1497                        JFrame frame = new ExpProgressBar(this);
1498 
1499                        frame.addWindowListener(new WindowAdapter() {
1500                                public void windowClosing(WindowEvent e) {
1501                                        System.exit(0);
1502                                }
1503                        });
1504 
1505                        frame.pack();
1506                        // frame.setSize(380,90);
1507                        frame.setVisible(true);
1508                }
1509 
1510                _status = RUNNING; // now checked to run
1511                boolean gotEvent = false; // buffer to check if scheduler works
1512 
1513                try {
1514 
1515                        while (_status == RUNNING) {
1516                                // infinite loop until condition/time expired
1517                                gotEvent = clientScheduler.processNextEventNote();
1518                                if (gotEvent == false) {
1519                                        _status = STOPPED;
1520                                }
1521 
1522                                // check potential stop conditions
1523                                if (!_stopConditions.isEmpty()) {
1524                                    for (ModelCondition c : _stopConditions) {
1525                                            if (c.check()) {
1526                                                    _status = STOPPED;
1527                                                    break;
1528                                            }
1529                                    }
1530                                }
1531 
1532                                // Sleep a while (modified by N. Knaak)
1533                                if (_status == RUNNING && _delayInMillis != 0)
1534                                        Thread.sleep(_delayInMillis);
1535                        }
1536                } catch (DESMOJException e) {
1537                        System.err.println("desaster recovery");
1538                        // this is the desaster recovery routine to stop simulation and save
1539                        // the report to disc before exiting the faulty experiment
1540                        _messMan.receive(e.getErrorMessage());
1541                        report();
1542                        finish();
1543                        _status = ABORTED;
1544                        e.printStackTrace();
1545                } catch (java.lang.InterruptedException e) {
1546                        System.err.println("desaster recovery");
1547                        // this is the disaster recovery routine to stop simulation and save
1548                        // the report to disc before exiting the faulty experiment
1549                        // messMan.receive(e.getMessage());
1550                        report();
1551                        finish();
1552                        _status = ABORTED;
1553                }
1554 
1555                // give warning if reason for stopping was empty EventList
1556                if (gotEvent == false) {
1557                        sendWarning("No more events scheduled! Experiment is stopped.",
1558                                        "Experiment '" + getName() + "' method void proceed().",
1559                                        "The scheduler has run out of events to handle.",
1560                                        "Make sure to always have events to be scheduled i.e. by letting an "
1561                                                        + "Entity create and schedule its successor.");
1562                }
1563 
1564                // print status message to user...
1565                if (!_silent) System.out.println(getName() + " stopped at simulation time "
1566                                + getScheduler().presentTime());
1567 
1568        }
1569 
1570        /**
1571         * Sets the delay between each step of the scheduler.
1572         * 
1573         * @param delay
1574         *            : Delay time in milliseconds as a long value
1575         * @author Nicolas Knaak
1576         */
1577        public void setDelayInMillis(long delay) {
1578                _delayInMillis = delay;
1579        }
1580 
1581        /**
1582         * Returns the delay between each step of the scheduler
1583         * 
1584         * @return A long value representing the delay time in milliseconds
1585         * @author Nicolas Knaak
1586         * 
1587         */
1588        public long getDelayInMillis() {
1589                return _delayInMillis;
1590        }
1591 
1592 
1593        /**
1594         * Registers a file output (Report, Trace, Error, Debug) in specific formats
1595         * (e.g. HTML, ASCII, XML) at the experiment. Registered files will be
1596         * flushed and closed after the experiment has finished. This is handy for
1597         * modellers producing their own output who want their files to be closed at
1598         * the end of the experiment.
1599         * 
1600         * @param file
1601         *            desmoj.report.FileOutput : The file to be closed with the end
1602         *            of an experiment
1603         */
1604        public void register(OutputType file) {
1605 
1606                if (file == null) {
1607                        sendWarning("Can not register OutputType! Command ignored.",
1608                                        "Experiment '" + getName()
1609                                                        + "' method void register(OutputType file).",
1610                                        "The parameter given was a null reference.",
1611                                        "Make sure to only connect valid OutputType at the Experiment.");
1612                        return;
1613                }
1614 
1615                if (_registryOutputType.contains(file))
1616                        return; // file already registered
1617 
1618                _registryOutputType.add(file);
1619 
1620        }
1621 
1622        /**
1623         * Registers a custom file output at the experiment, e.g. TimeSeries
1624         * plotting data to a file. Registered files will be flushed and closed
1625         * after the experiment has finished. This is handy for modellers producing
1626         * their own output who want their files to be closed at the end of the
1627         * experiment.
1628         * 
1629         * @param file
1630         *            desmoj.report.FileOutput : The file to be closed with the end
1631         *            of an experiment
1632         */
1633        public void registerFileOutput(FileOutput file) {
1634 
1635                if (file == null) {
1636                        sendWarning("Can not register FileOutput! Command ignored.",
1637                                        "Experiment '" + getName()
1638                                                        + "' method void register(OutputType file).",
1639                                        "The parameter given was a null reference.",
1640                                        "Make sure to only connect valid FileOutput at the Experiment.");
1641                        return;
1642                }
1643 
1644                if (_registryFileOutput.contains(file))
1645                        return; // file already registered
1646 
1647                _registryFileOutput.add(file);
1648 
1649        }
1650 
1651        /**
1652         * Connects a model to this experiment. The given model must not be submodel
1653         * of other models and not already be connected to some other experiment.
1654         * Otherwise an errormessage will be given and the experiment will be
1655         * stopped.
1656         */
1657        void registerModel(Model mainModel) {
1658 
1659                if (mainModel == null) {
1660                        sendWarning(
1661                                        "Can not register model at experiment! Command ignored.",
1662                                        "Experiment '" + getName()
1663                                                        + "', Method 'void registerModel(Model mainModel)'",
1664                                        "The parameter passed was a null reference.",
1665                                        "Make sure to connect a valid main model to this experiment.");
1666                        return; // no connection possible.
1667                }
1668 
1669                if (mainModel.getModel() != null) {
1670                        sendWarning(
1671                                        "Can not register model at experiment! Command ignored.",
1672                                        "Experiment '" + getName()
1673                                                        + "', Method 'void registerModel(Model mainModel)'",
1674                                        "The model references another model as its owner, thus can not be the "
1675                                                        + "main model.",
1676                                        "Make sure to connect a valid main model to this experiment.");
1677                        return; // no connection possible.
1678                }
1679 
1680                if (isConnected()) {
1681                        sendWarning(
1682                                        "Can not register model at experiment! Command ignored.",
1683                                        "Experiment '" + getName()
1684                                                        + "', Method 'void registerModel(Model mainModel)'",
1685                                        "This experiment is already connected to model : "
1686                                                        + _client.getName(),
1687                                        "An experiment may only be connected to one main model at a time.");
1688                        return; // no connection possible.
1689                }
1690 
1691                _status = CONNECTED;
1692                _client = mainModel;
1693                _client.setMain();
1694 
1695        }
1696 
1697        /**
1698         * Removes a messagereceiver for debugnotes from the experiment's
1699         * messagedistributor. Whenever a model produces a message of that type, it
1700         * will not be sent to the given messagereceiver anymore. Note that if the
1701         * messagereceiver is also registered for other types of messages, these
1702         * will not be affected. Use method
1703         * <code>removeReceiverAll(MessageReceiver msgRec)</code> to remove a
1704         * messagereceiver from all types of messages.
1705         * 
1706         * @param msgRec
1707         *            desmoj.report.MessageReceiver : The new messagereceiver to be
1708         *            removed from the messagedistributor's list for the given
1709         *            messagetype
1710         */
1711        public void removeDebugReceiver(MessageReceiver msgRec) {
1712 
1713                if (msgRec == null) {
1714                        sendWarning(
1715                                        "Can not remove receiver to experiment! Command ignored.",
1716                                        "Experiment '" + getName()
1717                                                        + "', Method 'void removeDebugReceiver"
1718                                                        + "(MessageReceiver msgRec)'",
1719                                        "The parameter 'msgRec' passed was a null reference.",
1720                                        "Make sure to give a valid MessageReciever reference before removing it "
1721                                                        + "from the experiment's messaging system.");
1722                        return; // do nothing
1723                }
1724 
1725                _messMan.deRegister(msgRec, debugnote);
1726 
1727        }
1728 
1729        /**
1730         * Removes a messagereceiver for errormessages from the experiment's
1731         * messagedistributor. Whenever a model produces a message of that type, it
1732         * will not be sent to the given messagereceiver anymore. Note that if the
1733         * messagereceiver is also registered for other types of messages, these
1734         * will not be affected. Use method
1735         * <code>removeReceiverAll(MessageReceiver msgRec)</code> to remove a
1736         * messagereceiver from all types of messages.
1737         * 
1738         * @param msgRec
1739         *            desmoj.report.MessageReceiver : The new messagereceiver to be
1740         *            removed from the vessagedistributor's list for the given
1741         *            messagetype
1742         */
1743        public void removeErrorReceiver(MessageReceiver msgRec) {
1744 
1745                if (msgRec == null) {
1746                        sendWarning(
1747                                        "Can not remove receiver to experiment! Command ignored.",
1748                                        "Experiment '" + getName()
1749                                                        + "', Method 'void removeErrorReceiver"
1750                                                        + "(MessageReceiver msgRec)'",
1751                                        "The parameter 'msgRec' passed was a null reference.",
1752                                        "Make sure to give a valid MessageReciever reference before removing it "
1753                                                        + "from the experiment's messaging system.");
1754                        return; // do nothing
1755                }
1756 
1757                _messMan.deRegister(msgRec, errormessage);
1758 
1759        }
1760 
1761        /**
1762         * Removes a messagereceiver from the experiment's messagedistributor. The
1763         * given messagereceiver will not receive messages of any type any more Use
1764         * method <code>removeReceiver(MessageReceiver msgRec, Class
1765         * messageType)</code> to remove the messagereceiver from one type of
1766         * messages only.
1767         * 
1768         * @param msgRec
1769         *            desmoj.report.MessageReceiver : The new messagereceiver to be
1770         *            removed from the messagedistributor's list for the given
1771         *            messagetype
1772         */
1773        public void removeReceiver(MessageReceiver msgRec) {
1774 
1775                if (msgRec == null) {
1776                        sendWarning(
1777                                        "Can not remove receiver to experiment! Command ignored.",
1778                                        "Experiment '" + getName()
1779                                                        + "', Method 'void removeReceiver(MessageReceiver "
1780                                                        + "msgRec)'",
1781                                        "The parameter 'msgRec' passed was a null reference.",
1782                                        "Make sure to give a valid MessageReciever reference before removing it "
1783                                                        + "from the experiment's messaging system.");
1784                        return; // do nothing
1785                }
1786 
1787                _messMan.deRegister(msgRec);
1788 
1789        }
1790 
1791        /**
1792         * Removes a messagereceiver for the given subtype of message from the
1793         * Experiment's messagedistributor. Whenever a model produces a message of
1794         * that type, it will not be sent to the given messagereceiver anymore. Note
1795         * that if the messagereceiver is also registered for other types of
1796         * messages, these will not be affected. Use method
1797         * <code>removeReceiverAll(MessageReceiver msgRec)</code> to remove a
1798         * messagereceiver from all types of messages.
1799         * 
1800         * @param msgRec
1801         *            desmoj.report.MessageReceiver : The new messagereceiver to be
1802         *            removed from the messagedistributor's list for the given
1803         *            messagetype
1804         * @param messageType
1805         *            Class : The type of message not to be sent to the given
1806         *            messagereceiver
1807         */
1808        public void removeReceiver(MessageReceiver msgRec, Class<?> messageType) {
1809 
1810                if (msgRec == null) {
1811                        sendWarning(
1812                                        "Can not remove receiver to experiment! Command ignored.",
1813                                        "Experiment '" + getName()
1814                                                        + "', Method 'void removeReceiver(MessageReceiver "
1815                                                        + "msgRec, Class messageType)'",
1816                                        "The parameter 'msgRec' passed was a null reference.",
1817                                        "Make sure to give a valid MessageReciever reference before removing it "
1818                                                        + "from the experiment's messaging system.");
1819                        return; // do nothing
1820                }
1821 
1822                if (messageType == null) {
1823                        sendWarning(
1824                                        "Can not remove receiver to experiment! Command ignored.",
1825                                        "Experiment '" + getName()
1826                                                        + "', Method 'void removeReceiver(MessageReceiver "
1827                                                        + "msgRec, Class messageType)'",
1828                                        "The parameter 'msgRec' passed was a null reference.",
1829                                        "Make sure to give a valid MessageReciever reference before removing it "
1830                                                        + "from the experiment's messaging system.");
1831                        return; // do nothing
1832                }
1833 
1834                _messMan.deRegister(msgRec, messageType);
1835 
1836        }
1837 
1838        /**
1839         * Removes a messagereceiver for tracenotes from the experiment's
1840         * messagedistributor. Whenever a model produces a message of that type, it
1841         * will not be sent to the given messagereceiver anymore. Note that if the
1842         * messagereceiver is also registered for other types of messages, these
1843         * will not be affected. Use method
1844         * <code>removeReceiverAll(MessageReceiver msgRec)</code> to remove a
1845         * messagereceiver from all types of messages.
1846         * 
1847         * @param msgRec
1848         *            desmoj.report.MessageReceiver : The new messagereceiver to be
1849         *            removed from the messagedistributor's list for the given
1850         *            messagetype
1851         */
1852        public void removeTraceReceiver(MessageReceiver msgRec) {
1853 
1854                if (msgRec == null) {
1855                        sendWarning(
1856                                        "Can not remove receiver to experiment! Command ignored.",
1857                                        "Experiment '" + getName()
1858                                                        + "', Method 'void removeTraceReceiver"
1859                                                        + "(MessageReceiver msgRec)'",
1860                                        "The parameter 'msgRec' passed was a null reference.",
1861                                        "Make sure to give a valid MessageReciever reference before removing it "
1862                                                        + "from the experiment's messaging system.");
1863                        return; // do nothing
1864                }
1865 
1866                _messMan.deRegister(msgRec, tracenote);
1867 
1868        }
1869 
1870        /**
1871         * Overrides inherited <code>NamedObjectImp.rename(String newName)</code>
1872         * method to prevent the user from changing the experiment's name during an
1873         * experiment. Renaming is not allowed with experiments, since it would not
1874         * allow the user to identify the reports produced by an experiment. The
1875         * method simply returns without changing the experiment's name, ignoring
1876         * the given parameter.
1877         * 
1878         * @param newName
1879         *            java.lang.String : The parameter given is not taken as the new
1880         *            name, method simply returns
1881         */
1882        public void rename(String newName) {
1883 
1884                // do nothing since renaming experiments is not allowed
1885                // would do too much confusion
1886 
1887        }
1888 
1889        /**
1890         * Writes a report about the model connected top this experiment, its
1891         * reportable components and all related submodels into the report output.
1892         * Note that a report can only be produced, if a valid main model is already
1893         * connected to the experiment.
1894         */
1895        public void report() {
1896 
1897                // just pass on the call with main model as parameter
1898                report(_client);
1899 
1900        }
1901 
1902        /**
1903         * Writes a report about the given model which has to be connected to this
1904         * experiment as main model or as a submodel. Note that this will report
1905         * about a branch of the tree of submodels constructed. A report will only
1906         * be produced, if the model given is connected to this experiment. All
1907         * reportable components of this model and all related submodels will be
1908         * sent to the report output configured at the experiment's
1909         * messagedistributor. Note that a report can only be produced, if a valid
1910         * main model is already connected to the experiment.
1911         */
1912        public void report(Model m) {
1913 
1914                List<Reporter> reporters;
1915                // buffer for the reportmanager returned by client
1916 
1917                if (_status < CONNECTED) {
1918                        sendWarning(
1919                                        "Can not produce report! Command ignored.",
1920                                        "Experiment: " + getName()
1921                                                        + " Method: void report(Model m).",
1922                                        "The Experiment has not been connected to a model to report about yet.",
1923                                        "Connect a model to the experiment first using the model's method "
1924                                                        + "connectToExperiment(Experiment exp).");
1925                        return; // no client there to be reported
1926                }
1927 
1928                if (_status >= ABORTED) {
1929                        // do nothing since experiment has already been aborted and all
1930                        // output channels are already shut down
1931                        return; // Experiment aborted
1932                }
1933 
1934                if (m == null) {
1935                        sendWarning("Can not produce report! Command ignored.",
1936                                        "Experiment: " + getName()
1937                                                        + " Method: void report(Model m).",
1938                                        "The model parameter given is a null reference.",
1939                                        "Always make sure to use valid references.");
1940                        return; // no model there to be reported
1941                }
1942 
1943                if (m.getExperiment() != this) {
1944                        sendWarning(
1945                                        "Can not produce report! Command ignored.",
1946                                        "Experiment: " + getName()
1947                                                        + " Method: void report(Model m).",
1948                                        "The model parameter given is connected to a different experiment.",
1949                                        "Only experiments connected to theat model can produce reports "
1950                                                        + "about that model.");
1951                        return; // model connected to other experiment
1952                }
1953 
1954                // get the client's reportmanager containing all reporters in sorted
1955                // order
1956                reporters = m.report();
1957 
1958                // get all out according to sorted order and send them to the report
1959                // output
1960                // registered at the experiment's messagemanager
1961                for (Reporter r : reporters) {
1962 
1963                        _messMan.receive(r);
1964 
1965                }
1966        }
1967 
1968        /**
1969         * Creates and sends a debugnote to the messagedistributor. Be sure to have
1970         * a correct location, since the object and method that the error becomes
1971         * apparent is not necessary the location it was produced in. The
1972         * information about the simulation time is extracted from the Experiment
1973         * and must not be given as a parameter.
1974         * 
1975         * @param description
1976         *            java.lang.String : The description of the error that occured
1977         */
1978        void sendDebugNote(String component, String description) {
1979 
1980                // comnpose the DebugNote and send it in one command
1981                sendMessage(new DebugNote(clientScheduler.getCurrentModel(),
1982                                clientScheduler.getSimClock().getTime(), component, description));
1983 
1984        }
1985 
1986        /**
1987         * Sends a message to the messagedistributor. Note that there are other
1988         * shorthands for sending the standard DESMO-J messages.
1989         * 
1990         * @param m
1991         *            Message : The Message to be transmitted
1992         * @see ModelComponent#sendTraceNote
1993         * @see ModelComponent#sendDebugNote
1994         * @see ModelComponent#sendWarning
1995         */
1996        void sendMessage(Message m) {
1997 
1998                if (m == null) {
1999                        sendWarning("Can't send Message!", "Experiment :" + getName()
2000                                        + " Method: SendMessage(Message m)",
2001                                        "The Message given as parameter is a null reference.",
2002                                        "Be sure to have a valid Message reference.");
2003                        return; // no proper parameter
2004                }
2005 
2006                _messMan.receive(m);
2007 
2008        }
2009 
2010        /**
2011         * Creates and sends an error message to the messagedistributor to warn the
2012         * modeller that some conditions required by the framework are not met. Be
2013         * sure to have a correct location, since the object and method that the
2014         * error becomes apparent is not necessary the location it was produced in.
2015         * The information about the simulation time is extracted from the
2016         * experiment and must not be given as a parameter.
2017         * 
2018         * @param description
2019         *            java.lang.String : The description of the error that occured
2020         * @param location
2021         *            java.lang.String : The class and method the error occured in
2022         * @param reason
2023         *            java.lang.String : The reason most probably responsible for
2024         *            the error to occur
2025         * @param prevention
2026         *            java.lang.String : The measures a user should take to prevent
2027         *            this warning to be issued again
2028         */
2029        void sendWarning(String description, String location, String reason,
2030                        String prevention) {
2031 
2032                // comnpose the WarningMessage and send it in one command
2033                sendMessage(new ErrorMessage(clientScheduler.getCurrentModel(),
2034                                description, location, reason, prevention, clientScheduler
2035                                                .getSimClock().getTime()));
2036 
2037        }
2038 
2039        /**
2040         * Sets the TimeFormatter to be used for output of time Strings.
2041         * 
2042         * @param format
2043         *            TimeFormatter : the formatter to be used for formatting time
2044         *            Strings.
2045         * 
2046         */
2047        public void setTimeFormatter(TimeFormatter format) {
2048                TimeOperations.setTimeFormatter(format);
2049        }
2050 
2051        /**
2052         * Determines if the event-list processes concurrent Events in random order
2053         * or not. Default is not, i.e. when a new experiment is constructed, the
2054         * event-list is set to "linear" order. Note: If you want the event-list to
2055         * randomize concurrent Events you should call this method BEFORE scheduling
2056         * any events. Otherwise any connections between events established via
2057         * scheduleBefore() or scheduleAfter() are lost. So it's a good idea to call
2058         * this method only once and right after constructing the experiment.
2059         * 
2060         * @param randomizing
2061         *            boolean :<code>true</code> forces random order,
2062         *            <code>false</code> forces "linear" order
2063         * @author Ruth Meyer
2064         */
2065        public void randomizeConcurrentEvents(boolean randomizing) {
2066                clientScheduler.setRandomizingConcurrentEvents(randomizing);
2067        }
2068 
2069        /**
2070         * Sets the speed rate for an execution that is proportional to wall-clock
2071         * time (real time). Set the speed rate to a value bigger than zero for a
2072         * simulation that will progress proportional to wall-clock time. The
2073         * following equation applies for speed rates >0 : rate*simulation time =
2074         * wallclock-time. If the speed rate is 0 or less the simulation will be
2075         * executed as fast as possible. Default is 0 (as-fast-as-possible).
2076         * 
2077         * @param rate
2078         *            double : The execution speed rate
2079         */
2080        public void setExecutionSpeedRate(double rate) {
2081                clientScheduler.setExecutionSpeedRate(rate);
2082        }
2083 
2084        /**
2085         * Sets the seed of the SeedGenerator to the given value. If the seed is not
2086         * set here, its default is 979, unless specified different in the
2087         * ExperimentOptions.
2088         * 
2089         * @param seed
2090         *            long : The seed for the SeedGenerator
2091         */
2092        public void setSeedGenerator(long seed) {
2093 
2094                _distMan.setSeed(seed);
2095 
2096        }
2097 
2098        /**
2099         * Sets the underlying pseudo random number generator to be used by all
2100         * distributions created from now on. The default generator is
2101         * LinearCongruentialRandomGenerator; any other generator to be used must
2102         * implement the interface UniformRandomGenerator.
2103         * 
2104         * @see desmoj.core.dist.LinearCongruentialRandomGenerator
2105         * @see desmoj.core.dist.UniformRandomGenerator
2106         * 
2107         * @param randomNumberGenerator
2108         *            Class : The random number generator class to be used
2109         */
2110        public void setRandomNumberGenerator(
2111                        Class<? extends desmoj.core.dist.UniformRandomGenerator> randomNumberGenerator) {
2112 
2113                boolean classValid = false;
2114                // // Verify that a class implementing interface
2115                // desmoj.desmoj.core.dist.UniformRandomGenerator was passed
2116                // for (int i = 0; i < randomNumberGenerator.getInterfaces().length;
2117                // i++) {
2118                // if
2119                // (randomNumberGenerator.getInterfaces()[i].equals(desmoj.core.dist.UniformRandomGenerator.class))
2120                // {
2121                // classValid = true;
2122                // break;
2123                // }
2124                // }
2125 
2126                // Verify the class provided is not abstract
2127                if ((randomNumberGenerator.getModifiers() & java.lang.reflect.Modifier.ABSTRACT) > 0
2128                                || (randomNumberGenerator.getModifiers() & java.lang.reflect.Modifier.INTERFACE) > 0)
2129                        classValid = false;
2130 
2131                // Update the random number generator...
2132                if (classValid) {
2133 
2134                        this._distMan.setRandomNumberGenerator(randomNumberGenerator);
2135 
2136                        // ...or otherwise return an error
2137                } else {
2138 
2139                        this
2140                                        .sendWarning(
2141                                                        "Invalid random number generator given! Method call ignored!",
2142                                                        "Experiment '"
2143                                                                        + getName()
2144                                                                        + "', Method 'setRandomNumberGenerator(Class randomNumberGenerator)'",
2145                                                        "The class provided '"
2146                                                                        + randomNumberGenerator.getSimpleName()
2147                                                                        + "' is abstract or does not implement the interface"
2148                                                                        + " desmoj.desmoj.core.dist.UniformRandomGenerator.",
2149                                                        "Make sure to use a non-abstract class that implements the interface"
2150                                                                        + " desmoj.desmoj.core.dist.UniformRandomGenerator.");
2151                }
2152        }
2153 
2154        /**
2155         * Sets the new value for showing the progress bar for this experiment or
2156         * not.
2157         * 
2158         * @param newShowProgressBar
2159         *            boolean : set it to <code>true</code> if a progress bar should
2160         *            be displayed; for not showing the progress bar of this
2161         *            experiment set it to <code>false</code>.
2162         */
2163        public void setShowProgressBar(boolean newShowProgressBar) {
2164 
2165                this._showProgressBar = newShowProgressBar;
2166        }
2167        
2168        /**
2169     * Sets the new value for displaying basic experiment notifications like
2170     * 'experiment started', 'experiment stopped' oder 'experiment resumed'
2171     * at the system output.
2172     * 
2173     * @param silent
2174     *            boolean : set it to <code>true</code> to suppress notifications
2175     *            or <code>false</code> to print them.
2176     */
2177    public void setSilent(boolean silent) {
2178 
2179        this._silent = silent;
2180    }
2181 
2182        /**
2183         * Sets the experiment's status to the given integer value. The value must
2184         * be in the legal range of [-1,5], otherwise a warning is issued.
2185         * 
2186         * @param newStatus
2187         *            int : The integer value of the experiments' new status
2188         */
2189        void setStatus(int newStatus) {
2190 
2191                if ((newStatus < -1) || (newStatus > 5)) {
2192                        sendWarning(
2193                                        "Can not start experiment! Command ignored.",
2194                                        "Experiment '" + getName() + "', Method 'start'",
2195                                        "No main model's connectToExperiment(Experiment e) method was called.",
2196                                        "Make sure to connect a valid main model first before starting "
2197                                                        + "this experiment.");
2198                        return;
2199                } else
2200                        _status = newStatus;
2201 
2202        }
2203 
2204        /**
2205         * Starts the simulation with default start time 0. This method can only be
2206         * used once on an experiment. it initializes the connected model and starts
2207         * the simulation. Note that in order to stop the simulation, the
2208         * <code>stop(TimeInstant stopTime)</code> method has to be called first!
2209         */
2210        public void start() {
2211 
2212                // this allows us to use start() in loops for multiple experiment runs
2213                // in other words, this is a shortcut for the lazy programmer
2214                if (_status == STOPPED)
2215                        proceed();
2216 
2217                // here's what start was supposed to be at first
2218                // a shortcut for startig an Experiment at TimeInstant(0)
2219                else {
2220                        // now prepare connected model to start simulation
2221                        start(new TimeInstant(0));
2222                }
2223 
2224        }
2225 
2226        /**
2227         * Starts the experiment with the given simulation time as starting time.
2228         * The experiment will not start unless a valid model has been connected to
2229         * it before. Note that in order to stop the simulation at some point of
2230         * time, the <code>stop</code> method has to be called first.
2231         * <code>StopCondition</code> s can be given alternatively.
2232         * 
2233         * @param initTime
2234         *            TimeInstant : The starting time instant
2235         */
2236        public void start(TimeInstant initTime) {
2237 
2238                if (_status < CONNECTED) {
2239                        sendWarning(
2240                                        "Can not start experiment! Command ignored.",
2241                                        "Experiment: " + getName()
2242                                                        + " Method: void start(SimTime initTime)",
2243                                        "The Experiment has not been connected to a model to report about yet.",
2244                                        "Connect a model to the experiment first using the model's method "
2245                                                        + "connectToExperiment(Experiment exp).");
2246                        return;
2247                }
2248                if (_status > CONNECTED) {
2249                        sendWarning(
2250                                        "Can not start experiment! Command ignored.",
2251                                        "Experiment: " + getName()
2252                                                        + " Method: void start(SimTime initTime)",
2253                                        "The Experiment has already been started before.",
2254                                        "An experiment can only be started once. If it has been stopped, "
2255                                                        + "it can be issued to continue using method proceed()");
2256                        return;
2257                }
2258 
2259                // check initial TimeInstant parameter
2260                if (initTime != null) {
2261                        clientScheduler.getSimClock().setInitTime(initTime);
2262                        if(!TimeInstant.isEqual(initTime,new TimeInstant(0))){
2263                        _client.reset();
2264                        }
2265                } else {
2266                        clientScheduler.getSimClock().setTime(new TimeInstant(0));
2267                        sendWarning(
2268                                        "Invalid start time parameter given! Start time set to "
2269                                                        + clientScheduler.presentTime() + ".",
2270                                        "Experiment: '" + getName()
2271                                                        + "', Method: void start(SimTime initTime)",
2272                                        "A null calue or a not initialized TimeInstant reference has been passed.",
2273                                        "Make sure to have a valid TimeInstnat object, otherwise use method "
2274                                                        + "start() without TimeInstant parameter.");
2275                }
2276 
2277                // client.init(); already done in connectToExperiment
2278                _client.doInitialSchedules();
2279                _client.doSubmodelSchedules();
2280                TimeOperations.setStartTime(initTime);
2281                // now everything is set up, go on and process events
2282                _status = STARTED;
2283                this._realTimeStartTime = System.nanoTime();
2284 
2285                proceed();
2286 
2287        }
2288        
2289    /**
2290     * @deprecated Use start(TimeInstant initTime). 
2291     * Starts the experiment with the given simulation time as starting time.
2292     * The experiment will not start unless a valid model has been connected to
2293     * it before. Note that in order to stop the simulation at some point of
2294     * time, the <code>stop</code> method has to be called first.
2295     * <code>StopCondition</code> s can be given alternatively.
2296     * 
2297     * @param initTime
2298     *            TimeInstant : The starting time instant
2299     */
2300    public void start(SimTime initTime) {
2301        start(SimTime.toTimeInstant(initTime));
2302    }
2303 
2304        /**
2305         * Specifies a ModelCondition to stop the simulation. Note that this methode can
2306         * be called muliple times, defining alternative conditions to terminate the 
2307         * simulation. Once at least one of the conditions passed using this method 
2308         * returns true, the experiment will stop. 
2309         * Beware that the simulation will run endlessly if none of the conditions 
2310         * are met; thus it is recommended to additionally always use a time limit 
2311         * if none of the conditions in question can be proven to be met during the 
2312         * run of the simulation!
2313         * 
2314         * @param stopCond
2315         *            ModelCondition : A condition to stop the simulation once
2316     *            it's check() methode returns true.
2317         */
2318        public void stop(ModelCondition stopCond) {
2319 
2320                if (stopCond == null) {
2321                        sendWarning("Can not set stop-condition! Command ignored.",
2322                                        "Experiment '" + getName()
2323                                                        + "', Method 'stop(Condition stopCond)'",
2324                                        "The parameter passed was either null or a not initialized "
2325                                                        + "Condition reference.",
2326                                        "Make sure to provide a valid stop Condition for "
2327                                                        + "this experiment.");
2328                } else {
2329                        this._stopConditions.add(stopCond);
2330                }
2331 
2332        }
2333        
2334        @Deprecated
2335    /**
2336     * @deprecated Replaced by <code>stop(ModelCondition stopCond)</code>
2337     * 
2338     * Specifies a Condition to stop the simulation. 
2339     * 
2340     * @param stopCond
2341     *            Condition<?> : A condition to stop the simulation once
2342     *            it's check() methode returns true.
2343     */
2344    public void stop(Condition<?> stopCond) {
2345 
2346        if (stopCond == null) {
2347            sendWarning("Can not set stop-condition! Command ignored.",
2348                    "Experiment '" + getName()
2349                            + "', Method 'stop(Condition stopCond)'",
2350                    "The parameter passed was either null or a not initialized "
2351                            + "Condition reference.",
2352                    "Make sure to provide a valid stop Condition for "
2353                            + "this experiment.");
2354        } else {
2355            this.stop(new ModelCondition.ConditionWrapper(this.getModel(), stopCond));
2356        }
2357 
2358    }
2359 
2360        /**
2361         * Stops the simulation at the given point of simulation time. If no valid
2362         * simulation time is given, the default is 0 which would not
2363         * let the simulation run past that time. Repeatedly calling this method
2364         * will override stop times specified before. 
2365         * 
2366         * @param stopTime
2367         *            desmoj.TimeInstant : The point of simulation time to stop the
2368         *            simulation
2369         */
2370        public void stop(TimeInstant stopTime) {
2371                if (stopTime == null) {
2372                        sendWarning(
2373                                        "Can not set stop-time! The stop-time will be set to 0",
2374                                        "Experiment '" + getName()
2375                                                        + "', Method: 'stop(TimeInstant stopTime)'",
2376                                        "The parameter passed was either null or a not initialized "
2377                                                        + "TimeInstance reference.",
2378                                        "Pass an initialized TimeInstant object as stop time.");
2379 
2380                        ExternalEventStop stopper = new ExternalEventStop(_client,
2381                                        "Simulation stopped", true);
2382                        stopper.schedule(new TimeInstant(0));
2383 
2384                } else {
2385 
2386                        this._stopTime = stopTime;
2387                        if (this._stopTimeEvent != null) this._stopTimeEvent.cancel();
2388 
2389                        this._stopTimeEvent = new ExternalEventStop(_client, "Simulation stopped", true);
2390                        _stopTimeEvent.schedule(stopTime);
2391                }
2392        }
2393 
2394        /**
2395         * @deprecated Stops the simulation at the given point of simulation time.
2396         *             If no valid simulation time is given, the default is 0.0
2397         *             which would not let the simulation run past that time.
2398         * 
2399         * @param stopTime
2400         *            desmoj.SimTime : The point of simulation time to stop the
2401         *            simulation
2402         */
2403        @Deprecated
2404        public void stop(SimTime stopTime) {
2405                stop(SimTime.toTimeInstant(stopTime));
2406        }
2407 
2408        /**
2409         * Stops the simulation at the current simulation time (immediately). A
2410         * stopped Simulation run can be resumed by calling proceed().
2411         */        
2412        public void stop() {
2413                setStatus(STOPPED);
2414                clientScheduler.signalStop();
2415        }
2416 
2417        /**
2418         * Returns a boolean indicating whether trace notes are forwarded to the
2419         * trace ouput or not. Trace ouput can be switched on and off using the
2420         * methods <code>traceOn(TimeInstant startTime)</code> and
2421         * <code>traceOff(TimeInstant stopTime)</code>
2422         * 
2423         * @return boolean : Is <code>true</code>
2424         */
2425        public boolean traceIsOn() {
2426 
2427                return _messMan.isOn(tracenote);
2428 
2429        }
2430 
2431        /**
2432         * Switches the trace output off at the given point of simulation time.
2433         * 
2434         * @param stopTime
2435         *            TimeInstant : The point in simulation time to switch trace off
2436         */
2437        public void traceOff(TimeInstant stopTime) {
2438 
2439                // check initial TimeInstant parameter
2440                if (stopTime == null) {
2441                        sendWarning(
2442                                        "Invalid start time parameter for trace output given! "
2443                                                        + "Trace output is set to start immediately.",
2444                                        "Experiment '" + getName()
2445                                                        + "', Method 'traceOn(TimeInstant startTime)'",
2446                                        "A null value or a not initialized TimeInstant reference has been passed.",
2447                                        "Make sure to have a valid TimeInstant object, otherwise use method "
2448                                                        + "start() without TimeInstant parameter.");
2449                        stopTime = clientScheduler.presentTime();
2450                }
2451 
2452                // check if parameter is in future
2453                if (TimeInstant.isAfter(clientScheduler.presentTime(), stopTime)) {
2454                        sendWarning("Invalid start time parameter for trace output given! "
2455                                        + "Trace output is set to start immediately.",
2456                                        "Experiment '" + getName()
2457                                                        + "', Method 'traceOn(TimeInstant stopTime)'",
2458                                        "The stopTime given is in the past.",
2459                                        "Make sure to give a TimeInstant parameter larger than the current time.");
2460                        stopTime = clientScheduler.presentTime();
2461                }
2462 
2463                ExternalEvent traceOff = new ExternalEventTraceOff(_client, true);
2464                traceOff.schedule(stopTime);
2465        }
2466        
2467    /**
2468     * @deprecated Use traceOff(TimeInstant startTime). Switches the trace output off at the given point of simulation time.
2469     * 
2470     * @param stopTime
2471     *            SimTime : The point in simulation time to switch trace off
2472     */
2473    public void traceOff(SimTime stopTime) {
2474        this.traceOff(SimTime.toTimeInstant(stopTime));        
2475    }
2476 
2477        /**
2478         * Switches the trace output on at the given point of simulation time.
2479         * 
2480         * @param startTime
2481         *            TimeInstant : The point in simulation time to switch trace on
2482         */
2483        public void traceOn(TimeInstant startTime) {
2484 
2485                // check initial TimeInstant parameter
2486                if (startTime == null) {
2487                        sendWarning(
2488                                        "Invalid start time parameter for trace output given! "
2489                                                        + "Trace output is set to start immediately.",
2490                                        "Experiment '" + getName()
2491                                                        + "', Method 'traceOn(TimeInstant startTime)'",
2492                                        "A null value or a not initialized TimeInstant reference has been passed.",
2493                                        "Make sure to have a valid TimeInstant object, otherwise use method "
2494                                                        + "start() without TimeInstant parameter.");
2495                        startTime = clientScheduler.presentTime();
2496                }
2497 
2498                // check if parameter is in future
2499                if (TimeInstant.isAfter(clientScheduler.presentTime(), startTime)) {
2500                        sendWarning("Invalid start time parameter for trace output given! "
2501                                        + "Trace output is set to start immediately.",
2502                                        "Experiment '" + getName()
2503                                                        + "', Method 'traceOn(TimeInstant startTime)'",
2504                                        "The startTime given is in the past.",
2505                                        "Make sure to give a TimeInstant parameter larger than the current time.");
2506                        startTime = clientScheduler.presentTime();
2507                }
2508 
2509        // if parameter equals current time, set trace on immediately, e.g. 
2510        // to include initial scheduling
2511        if (TimeInstant.isEqual(clientScheduler.presentTime(), startTime)) {
2512            this.getMessageManager().switchOn(Experiment.tracenote);
2513            _client.sendTraceNote("Trace switched on");
2514        // Otherwise schedule an appropriate event    
2515        } else {
2516            ExternalEvent traceOn = new ExternalEventTraceOn(_client, true);
2517            traceOn.schedule(startTime);
2518        }
2519 
2520        }
2521        
2522        /**
2523     * @deprecated Use traceOn(TimeInstant startTime). Switches the trace output on at the given point of simulation time.
2524     * 
2525     * @param startTime
2526     *            SimTime : The point in simulation time to switch trace on
2527     */
2528    public void traceOn(SimTime startTime) {
2529        this.traceOn(SimTime.toTimeInstant(startTime));        
2530    }
2531 
2532        /**
2533         * Switches the trace output on for the given period of simulation time. If
2534         * the second parameter (off) is "sooner" then the first parameter (on),
2535         * they will be swapped automatically. Same parameters will result in no
2536         * trace output at all.
2537         * 
2538         * @param startTime
2539         *            TimeInstant : The point in simulation time to switch trace on
2540         * @param stopTime
2541         *            TimeInstant : The point in simulation time to switch trace off
2542         */
2543        public void tracePeriod(TimeInstant startTime, TimeInstant stopTime) {
2544                if (startTime == null) {
2545                        sendWarning(
2546                                        "Invalid start time parameter for trace output given! Command ignored",
2547                                        "Experiment '" + getName()
2548                                                        + "', Method 'tracePeriod(TimeInstant startTime, "
2549                                                        + "TimeInstant stopTime)'",
2550                                        "A null value or a not initialized TimeInstant reference has been passed.",
2551                                        "Make sure to have a valid TimeInstant object.");
2552                        return;
2553                }
2554 
2555                // check initial TimeInstant parameter
2556                if (stopTime == null) {
2557                        sendWarning(
2558                                        "Invalid stop time parameter for trace output given! Command ignored.",
2559                                        "Experiment '" + getName()
2560                                                        + "', Method 'tracePeriod(TimeInstant startTime, "
2561                                                        + "TimeInstant stopTime)'",
2562                                        "A null value or a not initialized TimeInstant reference has been passed.",
2563                                        "Make sure to have a valid TimeInstant object.");
2564                        return;
2565                }
2566 
2567                // check for correct order in parameters
2568                if (TimeInstant.isAfter(startTime, stopTime)) {
2569 
2570                        // swap parameters
2571                        TimeInstant buffer = stopTime;
2572                        stopTime = startTime;
2573                        startTime = buffer;
2574 
2575                }
2576 
2577                // check if stop parameter is in future
2578                if (TimeInstant.isAfter(clientScheduler.presentTime(), stopTime)) {
2579                        sendWarning(
2580                                        "Invalid stop time parameter for trace output given! Command ignored.",
2581                                        "Experiment '" + getName()
2582                                                        + "', Method 'tracePeriod(TimeInstant startTime, "
2583                                                        + "TimeInstant stopTime)'",
2584                                        "The stopTime given is in the past.",
2585                                        "Make sure to give a TimeInstant parameter larger than the current time.");
2586                        return;
2587                }
2588 
2589                // check if start parameter is in past
2590                if (TimeInstant.isAfter(clientScheduler.presentTime(), startTime)) {
2591                        sendWarning("Invalid start time parameter for trace output given! "
2592                                        + "Trace output has been set to start immediately.",
2593                                        "Experiment '" + getName()
2594                                                        + "', Method 'tracePeriod(TimeInstant startTime, "
2595                                                        + "TimeInstant startTime)'",
2596                                        "The startTime given is in the past.",
2597                                        "Make sure to give a TimeInstant parameter larger than the current time.");
2598                        startTime = clientScheduler.presentTime();
2599                }
2600 
2601                // set trace to switch on
2602                traceOn(startTime);
2603 
2604                // set trace to switch off
2605                traceOff(stopTime);
2606        }
2607 
2608        /**
2609         * @deprecated Replaced by tracePeriod(TimeInstant startTime, TimeInstant
2610         *             stopTime). Switches the trace output on for the given period
2611         *             of simulation time. If the second parameter (off) is "sooner"
2612         *             then the first parameter (on), they will be swapped
2613         *             automatically. Same parameters will result in no trace output
2614         *             at all.
2615         * 
2616         * @param startTime
2617         *            SimTime : The point in simulation time to switch trace on
2618         * @param stopTime
2619         *            SimTime : The point in simulation time to switch trace off
2620         */
2621        @Deprecated
2622        public void tracePeriod(SimTime startTime, SimTime stopTime) {
2623                tracePeriod(SimTime.toTimeInstant(startTime), SimTime
2624                                .toTimeInstant(stopTime));
2625        }
2626 
2627        /**
2628         * Triggers the reporters of the given model or submodel to write their
2629         * report data into the report output registered at the experiment's
2630         * messagemanager. The string given will be added as a suffix to the report
2631         * filename to help identify teh report when more than one report is
2632         * produced by one Experiment at differnet points of simulation time.
2633         * 
2634         * @param m
2635         *            desmoj.Model
2636         * @param suffix
2637         *            java.lang.String : Suffix for report filename if multiple
2638         *            reports are drawn
2639         */
2640        public void writeReport(Model m, String suffix) {
2641 
2642                if (suffix == null)
2643                        suffix = "";
2644 
2645                // buffer used for storing the filename in
2646                String nameBuffer = null;
2647 
2648                // now flush and close all files and reopen with new names
2649                for (FileOutput f : _registryFileOutput) {
2650 
2651                        // remember the name the file had
2652                        nameBuffer = f.getFileName();
2653 
2654                        // flush buffer and close file
2655                        f.close();
2656 
2657                        // open new file with old name stripping off old suffix and
2658                        // adding new suffix
2659                        nameBuffer = nameBuffer.substring(0, nameBuffer.lastIndexOf("."));
2660                        f.open(nameBuffer.substring(0, (nameBuffer.length() - lastSuffix))
2661                                        + suffix + "html");
2662                }
2663                lastSuffix = suffix.length(); // remember last suffix length
2664                report(m);
2665        }
2666 
2667        /**
2668         * Triggers the reporters to write their data into the report output
2669         * registered at the experiment's messagemanager. The string given will be
2670         * added as a suffix to the report filename to help identification when more
2671         * than one report is produced by one Experiment at differnet points of
2672         * simulation time.
2673         * 
2674         * @param suffix
2675         *            java.lang.String : Suffix for report filename if multiple
2676         *            reports are drawn
2677         */
2678        public void writeReport(String suffix) {
2679 
2680                if (suffix == null)
2681                        suffix = "";
2682 
2683                // write report data about main model
2684                report(_client);
2685 
2686                // buffer used for storing the filename in
2687                String nameBuffer = null;
2688 
2689                // now flush and close all files and reopen with new names
2690                for (FileOutput f : _registryFileOutput) {
2691 
2692                        // remember the name the file had
2693                        nameBuffer = f.getFileName();
2694 
2695                        // flush buffer and close file
2696                        f.close();
2697 
2698                        // open new file with old name stripping off old suffix and
2699                        // adding new suffix
2700                        // strip the _debug / _error / _trace / _report part
2701                        nameBuffer = nameBuffer.substring(0, nameBuffer.lastIndexOf("_"));
2702                        // strip the previous suffix
2703                        nameBuffer = nameBuffer.substring(0, nameBuffer.length()
2704                                        - lastSuffix);
2705                        // add new suffix
2706                        nameBuffer = nameBuffer + suffix;
2707                        // now open file with new name
2708                        f.open(nameBuffer);
2709                }
2710                lastSuffix = suffix.length(); // remember last suffix length
2711        }
2712 
2713        /**
2714         * Returns the current DESMO-J version
2715         * 
2716         * @return The string "2.3.3".
2717         */
2718        public static String getDesmoJVersion() {
2719                return "2.3.3";
2720        }
2721 
2722        /**
2723         * Returns the DESMO-J license
2724         * 
2725         * @param html
2726         *            boolean: Include link (HTML, true) or not (plain text, false)
2727         * 
2728         * @return The string "Apache License, Version 2.0", embedded in a HTML link
2729         *         tag (currently http://www.apache.org/licenses/LICENSE-2.0) if
2730         *         <code>html</code> is set true.
2731         */
2732        public static String getDesmoJLicense(boolean html) {
2733                return html ? "<A HREF=http://www.apache.org/licenses/LICENSE-2.0>Apache License, Version 2.0</A>"
2734                                : "Apache License, Version 2.0";
2735        }
2736        
2737    public void setDescription(String description) {
2738        this._description = description;
2739    }
2740 
2741    public String getDescription() {
2742        return _description;
2743    }
2744}

[all classes][desmoj.core.simulator]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov