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

COVERAGE SUMMARY FOR SOURCE FILE [Model.java]

nameclass, %method, %block, %line, %
Model.java0%   (0/1)0%   (0/23)0%   (0/574)0%   (0/139)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Model0%   (0/1)0%   (0/23)0%   (0/574)0%   (0/139)
Model (Model, String, boolean, boolean): void 0%   (0/1)0%   (0/44)0%   (0/11)
checkCompatibility (ModelComponent): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
connectToExperiment (Experiment): void 0%   (0/1)0%   (0/174)0%   (0/40)
createReporter (): Reporter 0%   (0/1)0%   (0/5)0%   (0/1)
doSubmodelInit (): void 0%   (0/1)0%   (0/21)0%   (0/6)
doSubmodelSchedules (): void 0%   (0/1)0%   (0/21)0%   (0/6)
getEntities (boolean): List 0%   (0/1)0%   (0/32)0%   (0/6)
getEntity (long): Entity 0%   (0/1)0%   (0/7)0%   (0/1)
getExperiment (): Experiment 0%   (0/1)0%   (0/10)0%   (0/3)
getParameterManager (): ModelParameterManager 0%   (0/1)0%   (0/3)0%   (0/1)
getReportables (): List 0%   (0/1)0%   (0/6)0%   (0/1)
hasSubModels (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
init (ModelOptions): void 0%   (0/1)0%   (0/6)0%   (0/3)
isConnected (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
isMainModel (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isSubModel (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
linkWithIdentNumber (Entity): long 0%   (0/1)0%   (0/17)0%   (0/3)
register (Reportable): void 0%   (0/1)0%   (0/9)0%   (0/4)
registerSubModel (Model): void 0%   (0/1)0%   (0/26)0%   (0/8)
report (): List 0%   (0/1)0%   (0/68)0%   (0/10)
reset (): void 0%   (0/1)0%   (0/41)0%   (0/10)
setConnectedExperiment (Experiment): void 0%   (0/1)0%   (0/47)0%   (0/18)
setMain (): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package desmoj.core.simulator;
2 
3import java.util.ArrayList;
4import java.util.LinkedList;
5import java.util.List;
6import org.apache.commons.collections.map.ReferenceMap;
7 
8import desmoj.core.report.ReportManager;
9import desmoj.core.report.Reporter;
10 
11/**
12 * The model is supposed to carry references to all static modelcomponents
13 * associated to a model. These are modelcomponents like distributions and
14 * statistic counters. Note that placing all essential components inside the
15 * model class allows you to use object orientation to reuse this model to
16 * implement different versions of it using subclassing for changes necessary
17 * for using other modelling paradigms. This way models can be easily
18 * reimplemented following the process-, event-, transaction- or activity-
19 * oriented paradigm. Note that transaction- and activity-oriented modelling
20 * requires the higher process synchronization mechanisms (Res, Bin, WaitQueue,
21 * CondQueue) by Soenke Claassen.
22 * <p>
23 * The modelcomponents belonging to a model have to be instantiated in the
24 * <code>init()</code> method. They must not be instantiated in the model's
25 * constructor since most components need access to a valid experiment object.
26 * This can only be accessed after a model has been connected to an experiment
27 * using method <code>connectToExperiment(Experiment exp)</code> which
28 * implicitly calls the <code>init()</code> method after receiving the valid
29 * reference to an experiment.
30 * 
31 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
32 * @author Tim Lechler
33 * 
34 * Licensed under the Apache License, Version 2.0 (the "License");
35 * you may not use this file except in compliance with the License. You
36 * may obtain a copy of the License at
37 * http://www.apache.org/licenses/LICENSE-2.0
38 *
39 * Unless required by applicable law or agreed to in writing, software
40 * distributed under the License is distributed on an "AS IS"
41 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
42 * or implied. See the License for the specific language governing
43 * permissions and limitations under the License.
44 *
45 */
46public abstract class Model extends Reportable {
47 
48    /**
49     * The experiment this model is connected to.
50     */
51    private Experiment _myExperiment;
52    
53    /**
54     * The map with all entities and their identifiers.
55     */
56    private ReferenceMap _entityMap;
57    
58    /**
59     * True if this is the main model (not a submodel to another model), false 
60     * for submodels.
61     */
62    boolean isMainModel;
63    
64    /**
65         * The current number of the created entities.
66         */
67        private long _numberOfEntitiesCreated;
68 
69    /**
70     * Dynamic List containing all associated submodels.
71     */
72    private ArrayList<Model> _subModels;
73 
74    /**
75     * Dynamic List containing all reportable components of this model.
76     */
77    private ArrayList<Reportable> _reportables;
78 
79    /**
80     * The parameter manager
81     */
82    private ModelParameterManager _paramManager;
83 
84    /**
85     * Constructs a model, with the given name and parameters for report and
86     * trace files.
87     * 
88     * @param name
89     *            java.lang.String : The name of this model
90     * @param owner
91     *            Model : The main model this model is associated to
92     * @param showInTrace
93     *            boolean : Flag for showing this model in trace-files. Set it
94     *            to <code>true</code> if model should show up in trace,
95     *            <code>false</code> if model should not be shown in trace.
96     */
97    public Model(Model owner, String name, boolean showInReport,
98            boolean showInTrace) {
99 
100        super(owner, name, showInReport, showInTrace); // create a reportable
101 
102        // init data structures
103        _subModels = new ArrayList<Model>(); // create empty Vector for subModels
104        _reportables = new ArrayList<Reportable>(); // create empty Vector for reportables
105 
106        if (owner != null) { // check if this is a submodel
107            this.isMainModel = false;
108            owner.registerSubModel(this);
109            // register as submodel at owner model
110        } else {
111            this.isMainModel = true;
112        }
113        
114        _paramManager = new ParameterManager(); // create ParameterManager
115        
116        _numberOfEntitiesCreated = 0L;
117        
118        _entityMap = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
119    }
120 
121    /**
122     * Checks the given modelcomponent for compatibility. Needed exclusively
123     * when submodels are present that want to share modelcomponents between
124     * them. The standard implementation only checks if the modelcomponent
125     * <code>other</code> belongs to <code>this</code> model. For use with
126     * multiple models, the user has to specify which other models are
127     * compatible to this model by overloading this method.
128     * 
129     * @return boolean : Returns <code>true</code> if the given modelcomponent
130     *         is compatible to this model, <code>false</code> otherwise.
131     * @param other
132     *            ModelComponent : The modelcomponent that needs to be checked
133     *            for compatibility to this model.
134     */
135    protected boolean checkCompatibility(ModelComponent other) {
136 
137        return (this == other.getModel()); // check for same owner
138 
139    }
140 
141    /**
142     * Connects this model to an experiment. The given experiment must not
143     * already be connected to some other model. Otherwise an errormessage will
144     * be given and the experiment will be stopped. Since a model that is not
145     * yet connected has no access to the experiment's messaging subsystem,
146     */
147    public void connectToExperiment(Experiment exp) {
148 
149        if (exp == null) {
150            sendWarning("Can not connect to a <code>null</code> Experiment! "
151                    + "Command ignored.", "Model : " + getName()
152                    + " Method: void connectToExperiment" + "(Experiment exp)",
153                    "The experiment reference passed is a null reference!",
154                    "Make sure to use valid references only.");
155            return; // no connection possible.
156        }
157 
158        if (!isMainModel()) { // only main model should register at experiment
159            sendWarning("Can not connect to Experiment " + exp.getName() + "! "
160                    + "Command ignored.", "Model : " + getName()
161                    + " Method: void connectToExperiment" + "(Experiment exp)",
162                    "The model to be connected is already submodel to model : "
163                            + getModel().getName(),
164                    "Only ,main models are allowed to be connected to an "
165                            + "experiment");
166            return; // model is no main model
167        }
168 
169        if (exp.isConnected()) {
170            sendWarning("Can not connect to Experiment " + exp.getName() + "! "
171                    + "Command ignored.", "Model : " + getName()
172                    + " Method: void connectToExperiment" + "(Experiment exp)",
173                    "The experiment to connect to is itself already connected "
174                            + "to model : " + exp.getModel(),
175                    "Only one main model can be connected to an experiment at "
176                            + "a time.");
177            return; // no connection possible.
178        }
179 
180        if (_myExperiment != null) {
181            sendWarning("Can not connect to Experiment " + exp.getName() + "! "
182                    + "Command ignored.", "Model : " + getName()
183                    + " Method: void connectToExperiment" + "(Experiment exp)",
184                    "The model is already connected to Experiment : "
185                            + _myExperiment.getName() + "!",
186                    "A model can only be connected to just one Experiment.");
187            return;
188        }
189 
190        // set the experiment reference
191        _myExperiment = exp;
192 
193        // register at Experiment
194        _myExperiment.registerModel(this);
195 
196        // set the Experiment parameter at all submodels if necessary
197        if (!_subModels.isEmpty()) {
198 
199            for (Model m : _subModels) {
200                m.setConnectedExperiment(exp);
201            }
202 
203        }
204 
205        // initialize the components of the main model
206        init();
207        // initialize the submodels recursively
208        doSubmodelInit();
209        // reset the model and all submodels recursively
210        reset();
211 
212    }
213 
214    /**
215     * Creates the default reporter associated with this model. The default
216     * reporter returned by this method just prints the model's description as
217     * implemented in method <code>description()</code> and appends the
218     * simulation time of the last reset. If the user's model offers more
219     * information, create a special class derived from class
220     * <code>desmoj.report.ModelReporter</code> to extract and present that
221     * extra information.
222     * 
223     * @return Reportable : The reporter associated with this model
224     */
225    public Reporter createReporter() {
226 
227        // has to be the special reporter designed for this model
228        return new desmoj.core.report.ModelReporter(this);
229 
230    }
231 
232    /**
233     * Should return the description of the model. Implement this method to
234     * document the model's intent, creator, date and all other information that
235     * needs to be published about this model in a report. Please use it
236     * generously, other people interested in your model will thank you.
237     * 
238     * @return java.lang.String : The description of the model as a text String
239     */
240    public abstract String description();
241 
242    /**
243     * Implement this method to schedule the entities and/or events needed for
244     * your model to start in a defined setting. If a model is connected to an
245     * experiment and started without any initial schedules, it will not run
246     * since no events to process are on the scheduler's event-list. This method
247     * is called automatically by the framework when the experiment's
248     * <code>start()</code> method is called.
249     */
250    public abstract void doInitialSchedules();
251    
252    /**
253     * Calls the <code>init()</code> method of all registered
254     * submodels of the current model. Subsequently calls the
255     * <code>init()</code> method of all registered submodels 
256     * of every submodel.
257     */
258    void doSubmodelInit() {
259 
260        if (!this.hasSubModels())
261            return; // no submodels registered here
262        else {
263            
264            for (Model m : _subModels) { // loop submodels
265                m.init(); // init submodel
266                m.doSubmodelInit(); // init submodels of submodels
267            }
268        }
269    }
270 
271    /**
272     * Calls the <code>doInitialSchedules()</code> method of all registered
273     * submodels of the current model. Subsequently calls the
274     * <code>doSubmodelSchedules()</code> method of all registered submodels
275     * of every submodel.
276     */
277    void doSubmodelSchedules() {
278 
279        if (!this.hasSubModels())
280            return; // no submodels registered here
281        else {
282            
283            for (Model m : _subModels) { // loop submodels
284                m.doInitialSchedules(); // initial schedules for the submodel
285                m.doSubmodelSchedules(); // initial schedules for potential submodels of the submodel
286            }
287 
288        }
289    }
290        
291    /**
292     * Returns the entity to the belonging identifier.
293     * @return Entity : The class will return the
294     * <code>Entity</code> or null if no such exists.
295     */
296    public Entity getEntity(long ident)
297    {
298        return (Entity) _entityMap.get(Long.valueOf(ident));
299    }
300        
301    /**
302     * Returns a list of this model's entities.
303     * 
304     * @param includeSubmodels
305     *      boolean : Do include (true) or exclude (false) submodels' entities in the list.
306     * 
307     * @return List<Entity> : The class will return a list of all existing objects of
308     * <code>Entity</code> or null if no list exists.
309     */
310    public List<Entity> getEntities(boolean includeSubmodels)
311    {
312        List<Entity> list = new LinkedList<Entity>();
313               list.addAll(_entityMap.values());
314        
315        if (includeSubmodels) {
316            for (Model submodel : this._subModels) {
317                list.addAll(submodel.getEntities(true));
318            }
319        }
320 
321        return list;
322    }
323 
324    /**
325     * Returns the experiment that is connected to this model or
326     * <code>null</code> if the model is not yet connected to an experiment.
327     * 
328     * @return Experiment : The experiment that this model is connected to or
329     *         <code>null</code> if no connection is established
330     */
331    public Experiment getExperiment() {
332                
333        if (this.isMainModel()) {
334 
335            return _myExperiment;
336        
337        } else {
338            
339            return this.getModel().getExperiment();
340            
341        }
342    }
343    
344    /**
345     * Returns a copy of the dynamic list containing all reportable 
346     * components of this model.
347     * 
348     * @return reportables : A list containing all reportable 
349     * components of this model.
350     */
351    public List<Reportable> getReportables() {
352        return new ArrayList<Reportable>(this._reportables);
353    }
354 
355    /**
356     * Returns the Model's viewpoint of the ParameterManager
357     * 
358     * @return ModelParameterManager : The ParameterManager
359     */
360    public ModelParameterManager getParameterManager()
361    {
362        return _paramManager;
363    }
364 
365    /**
366     * Shows, if there are submodels registered with this model.
367     * 
368     * @return boolean : True, if there is at least one submodel registered at
369     *         this Model, flase if there are no submodels
370     */
371    public boolean hasSubModels() {
372 
373        return !_subModels.isEmpty(); // checks for some submodels in vector
374 
375    }
376 
377    /**
378     * Implement this method to do initialization work for your model. All
379     * ModelComponents associated with this model are supposed to be
380     * instantiated in this method.
381     * <p>
382     * <em>Caution! Do not use the Model's constructor method to instantiate your
383     * modelcomponents!</em>
384     * <br>
385     * This prevents the modelcomponents to get contact to the associated
386     * Experiment since a Model can only be connected to an Experiment after
387     * itself has been instantiated correctly. Thus it is necessary to put all
388     * initialization and instantiation work into this method. Do not use this
389     * method to do the initial schedules needed for the scheduler to start
390     * with. Use method <code>doInitialSchedules()</code> instead. If there
391     * are no events scheduled in the event-list, the scheduler will stop the
392     * simulation immediately because there is nothing for him to do. If you are
393     * using submodels, take care that each of the submodels has its own
394     * <code>init</code> method properly set up.
395     */
396    public abstract void init();
397 
398    /**
399     * Initializes the model by calling method <code>init()</code> to set up
400     * all model related components as specified in that method. After
401     * initializing the model, the given ModelOption's <code>setOption()</code>
402     * method is called with this model as parameter. This enables the user to
403     * specify different model parameter settings for different experiments. It
404     * even allows automated parameter variation to give a small but handy aid
405     * for model optimization. Implement the ModelOptions to set the parameters
406     * for your model. Make sure to react properly on the ModelOptions given.
407     * Note that specifiying ModelOptions is up to the user.
408     * 
409     * @param options
410     *            ModelOptions : The parameter settings for this model
411     */
412    public void init(ModelOptions options) {
413 
414        this.init(); // just call the other init after dealing with the
415        // options
416        options.setOptions(this);
417 
418    }
419 
420    /**
421     * Shows if this model has already been connected to an experiment.
422     * 
423     * @return boolean : Is <code>true</code>, if model is connected to an
424     *         experiment, <code>false</code> otherwise
425     */
426    public boolean isConnected() {
427 
428        return (_myExperiment != null); // no experiment connected
429 
430    }
431 
432    /**
433     * Shows if this model is a main model and thus is not submodel of other
434     * models.
435     * 
436     * @return boolean : Returns <code>true</code> if the model is a main
437     *         model, <code>false</code> if it is a submodel of other models
438     */
439    public boolean isMainModel() {
440        
441        return this.isMainModel;
442 
443    }
444 
445    /**
446     * Shows if this model is submodel to another model and thus is not the main
447     * models.
448     * 
449     * @return boolean : Returns <code>true</code> if the model is a submodel
450     *         of other models, <code>false</code> if it is a main model
451     */
452    public boolean isSubModel() {
453 
454        return !this.isMainModel;
455    }
456    
457    /**
458     * Links an entity with an unique identification number.
459     * 
460     * @param e
461     *         Entity : The new Entity to link with an unique identification number.
462     * 
463     * @return long : Unique identification number.
464     */
465        long linkWithIdentNumber(Entity e)
466        {
467                _numberOfEntitiesCreated++;
468                _entityMap.put(_numberOfEntitiesCreated, e);
469                return _numberOfEntitiesCreated;
470        }
471 
472    /**
473     * Registers a reportable at this model. Reports can only be drawn, if the
474     * reportbale is registered at his model.
475     * 
476     * @param r
477     *            desmoj.core.simulator.Reportable : The reportable to be registered
478     */
479    void register(Reportable r) {
480 
481        if (r == null)
482            return; // do not accept null values
483        else
484            _reportables.add(r);
485 
486    }
487 
488    /**
489     * Registers another model as submodel of this model.
490     * 
491     * @param subModel
492     *            Model : The model to be registerd as a submodel
493     */
494    void registerSubModel(Model subModel) {
495 
496        if (subModel == null) {
497            sendWarning("Can't register Submodel!", "Model : " + getName()
498                    + " Method: registerSubModel(Model " + "subModel)",
499                    "The SubModel given as parameter is a null reference.",
500                    "Be sure to have a valid SubModel reference before calling "
501                            + "this method.");
502            return; // exit
503        }
504 
505        _subModels.add(subModel);
506 
507    }
508 
509    /**
510     * Produces a report about the model and all its related modelcomponents and
511     * submodels. It registers the model's reporter and all other reporters at
512     * the experiment's reportmanager to produce the report output. The
513     * reporters are ordered into the reportmanager returned with this model's
514     * reporter first, followed by all reportable's reporters. After this
515     * section, all submodel's reporters are inserted according to the order
516     * they were attached to this model. Each submodel's section is sorted using
517     * the criteria above. Thus all reporters a re separated by model to prevent
518     * confusion.
519     * 
520     * @return Enumeration : The Enumeration carrying all reporters available
521     *         from this model
522     */
523    List<Reporter> report() {
524 
525        // create the reportmanager necessary for sorting all reporters
526        ReportManager repMan = new ReportManager(getName() + "_ReportManager");
527 
528        // register this model's reporter
529        repMan.register(createReporter());
530 
531        // register all modelcomponent's reporters
532        // in case they are set to produce a report output
533        for (Reportable r : _reportables) { // loop reportables
534            if (r.reportIsOn())
535                repMan.register(r.createReporter());
536        }
537 
538        // register all submodel's reporters
539        List<Reporter> subReporters;
540        // buffer for submodel-reportmanagers returned
541 
542        for (Model m : _subModels) { // loop submodels
543 
544            subReporters = m.report();
545 
546            // add all reporters from the ordered enumeration at last position
547            // of repMan
548            for (Reporter r : subReporters) {
549                repMan.addLast(r);
550            }
551        }
552 
553        return repMan.elements();
554 
555    }
556 
557    /**
558     * Resets the statistic counters of this model and of all its registered
559     * reportables. Also calls all submodels's <code>reset()</code> methods.
560     */
561    public void reset() {
562 
563        // reset this model
564        super.reset(); // reset the own obs & resetAt variables
565 
566        // reset all reportables registered here
567        if (_reportables.isEmpty())
568            return; // no reportables registered
569        else {
570 
571            for (Reportable r : _reportables) { // loop reportables
572                r.reset();
573                // reset each registered
574            }
575 
576        }
577 
578        // reset all registered submodels
579        if (_subModels.isEmpty())
580            return; // no reportables registered
581        else {
582 
583            for (Model m : _subModels) { // loop submodels
584                m.reset();
585                // reset each registered
586            }
587 
588        }
589 
590    }
591 
592    /**
593     * Connects submodels to the experiment given. This method is called by the
594     * main model, when submodels register themselves at the main model.
595     * 
596     * @param e
597     *            desmoj.Experiment : The experiment to connect this model to
598     */
599    void setConnectedExperiment(Experiment e) {
600 
601        if (e == null) {
602            sendWarning(
603                    "Can not connect to experiment! Command ignored.",
604                    "Model : " + getName() + " Method: "
605                            + "void setConnectedExperiment (Experiment e)",
606                    "The given Esperiment parameter contained a null reference",
607                    "Be sure to always give valid parameters.");
608            return; // do nothing
609        }
610 
611        if (isSubModel()) { // this is a submodel
612            _myExperiment = e;
613            return;
614        } else { // this is no submodel
615            sendWarning("Can not connect to experiment! Command ignored.",
616                    "Model : " + getName() + " Method: void "
617                            + "method setConnectedExperiment"
618                            + "(Experiment e)",
619                    "This model is not a submodel.",
620                    "Only submodels can be connected to an experiment using "
621                            + "this method.");
622            return; // do nothing
623        }
624 
625    }
626 
627    /**
628     * Sets the current model to be the main model by setting the
629     * <code>owner</code> reference to itself.
630     */
631    void setMain() {
632 
633        setOwner(this);
634 
635    }
636    
637}

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