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

COVERAGE SUMMARY FOR SOURCE FILE [EventVectorList.java]

nameclass, %method, %block, %line, %
EventVectorList.java0%   (0/1)0%   (0/15)0%   (0/591)0%   (0/183)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EventVectorList0%   (0/1)0%   (0/15)0%   (0/591)0%   (0/183)
EventVectorList (): void 0%   (0/1)0%   (0/9)0%   (0/3)
createEventNote (Entity, Event, TimeInstant): EventNote 0%   (0/1)0%   (0/7)0%   (0/1)
firstNote (): EventNote 0%   (0/1)0%   (0/10)0%   (0/3)
insert (EventNote): void 0%   (0/1)0%   (0/142)0%   (0/41)
insertAfter (EventNote, EventNote): void 0%   (0/1)0%   (0/81)0%   (0/30)
insertAsFirst (EventNote): void 0%   (0/1)0%   (0/38)0%   (0/14)
insertAsLast (EventNote): void 0%   (0/1)0%   (0/47)0%   (0/16)
insertBefore (EventNote, EventNote): void 0%   (0/1)0%   (0/79)0%   (0/30)
isEmpty (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
lastNote (): EventNote 0%   (0/1)0%   (0/13)0%   (0/3)
nextNote (EventNote): EventNote 0%   (0/1)0%   (0/25)0%   (0/5)
prevNote (EventNote): EventNote 0%   (0/1)0%   (0/25)0%   (0/5)
remove (EventNote): void 0%   (0/1)0%   (0/40)0%   (0/12)
removeFirst (): void 0%   (0/1)0%   (0/43)0%   (0/12)
toString (): String 0%   (0/1)0%   (0/28)0%   (0/7)

1package desmoj.core.simulator;
2 
3import java.util.Vector;
4 
5import desmoj.core.exception.SimAbortedException;
6import desmoj.core.report.ErrorMessage;
7 
8/**
9 * Implementation of the interface <code>EventList</code> using a
10 * <code>java.util.Vector</code> as a container for the event-notes. Using Vector
11 * as a container has the advantage of using tested and thread-safe code. Being
12 * based on an array it allows inserting new entries faster using binary search
13 * for the right position, which would not be possible on containers based on
14 * linked lists. The obvious disadvantage is the slow speed of execution of the
15 * thread-safe code of the Vector.
16 * 
17 * @see java.util.Vector
18 * @see EventNote
19 * 
20 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
21 * @author Tim Lechler, modified by Ruth Meyer
22 * 
23 *         Licensed under the Apache License, Version 2.0 (the "License"); you
24 *         may not use this file except in compliance with the License. You may
25 *         obtain a copy of the License at
26 *         http://www.apache.org/licenses/LICENSE-2.0
27 * 
28 *         Unless required by applicable law or agreed to in writing, software
29 *         distributed under the License is distributed on an "AS IS" BASIS,
30 *         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
31 *         implied. See the License for the specific language governing
32 *         permissions and limitations under the License.
33 * 
34 */
35public class EventVectorList extends EventList {
36 
37        /**
38         * The vector container used to store the event-notes.
39         */
40        protected Vector<EventNote> eVector; // The Vector containing all Event notes.
41 
42        /**
43         * Constructs an empty event-list with a default size of 100 for the
44         * underlying vector. The standard initial size of a vector is 10, requiring
45         * the size to be doubled when element nnumber 11 is added. This duplication
46         * of the allovated memory takes some time. To reduce the amount of
47         * duplications necessary, the vector is created with an initial size of 100
48         * to improve performance by avoiding 4 cycles of doubling Vector's
49         * capacity. Choosing a larger initial number would not significantly fasten
50         * processing speeds but waste otherwise unused memory, depending on the
51         * behaviour of the model simulated.
52         */
53        EventVectorList() {
54 
55                eVector = new Vector<EventNote>(100);
56 
57        }
58 
59        /**
60         * Creates a new event-note with the initial values given as parameters. This
61         * resembles the factory method design pattern described in [Gamm95] p. 107.
62         * This design pattern is used to ensure that always the appropriate
63         * implementation of Event notes is used together with an individual
64         * implementation of an event-list. EventVector does not need any special
65         * implementation of Event notes and thus simply passes the construction
66         * through to the default implementation of EventNote.
67         * 
68         * @param who
69         *            Entity : the entity or process associated with the event-note
70         * @param what
71         *            Event : the event or external event associated with the
72         *            EventNote
73         * @param when
74         *            TimeInstant : the point of simulation time associated with the
75         *            EventNote
76         * @see EventNote
77         */
78        EventNote createEventNote(Entity who, Event<Entity> what, TimeInstant when) {
79 
80                return new EventNote(who, what, when);
81 
82        }
83 
84        /**
85         * Returns the first event-note in the event-list. It is the event-note with
86         * the lowest (nearest) associated point of simulation time of all
87         * Event notes contained in the evnet-list. Note that the event-note is not
88         * removed from the event-list.
89         * 
90         * @return EventNote : the event-note to be processed next in the order of
91         *         time. Returns <code>null</code> if the event-list is empty.
92         */
93        EventNote firstNote() {
94 
95                if (isEmpty())
96                        return null; // nothing there, nothing returned
97                else
98                        return eVector.firstElement(); // return but not remove
99 
100        }
101 
102        /**
103         * Inserts the new event-note preserving the temporal order of the event-notes
104         * contained in the event-list. It uses binary search to determine the
105         * position where to insert the new event-note to increase performance.
106         * 
107         * @param newNote
108         *            EventNote : the new note to be inserted in the event-list
109         *            keeping the temporal order
110         */
111        void insert(EventNote newNote) {
112            
113        // code for adding EventNote to all possible entities
114        
115        Entity who1 = newNote.getEntity1();
116        if (who1 != null)
117        {
118            who1.addEventNote(newNote);
119        }
120        
121        Entity who2 = newNote.getEntity2();
122        if (who2 != null)
123        {
124            who2.addEventNote(newNote);
125        }
126        
127        Entity who3 = newNote.getEntity3();
128        if (who3 != null)
129        {
130            who3.addEventNote(newNote);
131        }        
132        
133        EventAbstract Event = newNote.getEvent();
134        if (Event != null) {
135            Event.addEventNote(newNote);
136        }
137 
138                if (isEmpty()) { // no worry about order if it's first
139                        eVector.addElement(newNote); // easy if empty ;-)
140                        return; // no need to continue
141                } else { // now here comes the binary sorting
142 
143                        int left = 0; // left border of search partition
144                        int right = eVector.size() - 1; // right border of search partition
145                        int index = 0; // current position in vector
146                        TimeInstant refTime = newNote.getTime();
147                        // shortcut for call to newNote
148 
149                        do {
150                                index = (left + right) / 2; // center on searchable partition
151                                // check if EventNote at index has smaller or equal time
152                                if (TimeInstant.isBeforeOrEqual(eVector
153                                                .elementAt(index).getTime(), refTime)) {
154                                        if (index < (eVector.size() - 1)) {
155                                                // is there a note to the right
156                                                if (TimeInstant.isAfter(eVector
157                                                                .elementAt(index + 1).getTime(), refTime)) {
158                                                        // if note to the right is larger
159                                                        eVector.insertElementAt(newNote, index + 1);
160                                                        // found position
161                                                        return; // everything done, no need to continue
162                                                } else {
163                                                        left = index + 1;
164                                                        // no hit, so set new boundaries and go on
165                                                }
166                                        } // no Event notes right of the index, so all
167                                        else { // notes are smaller, thus append to end
168                                                eVector.addElement(newNote);
169                                                return; // everything done, get out of here fast!
170                                        }
171                                } else { // EventNote at index has larger time
172                                        if (index > 0) { // is there a note left of the index?
173                                                if (TimeInstant.isBeforeOrEqual(eVector
174                                                                .elementAt(index - 1).getTime(), refTime)) {
175                                                        // if note to the left is smallerOrEqual
176                                                        eVector.insertElementAt(newNote, index);
177                                                        // found position
178                                                        return; // everything done, no need to continue
179                                                } else {
180                                                        right = index - 1;
181                                                        // no hit, so set new boundaries and go on
182                                                }
183                                        } // no Event notes left of the index, so all
184                                        else { // notes are larger, thus insert at pos. 0
185                                                eVector.insertElementAt(newNote, 0);
186                                                return; // everything done, get out of here!
187                                        }
188                                }
189                        } while ((left <= right));
190 
191                        eVector.addElement(newNote);
192                }
193 
194        }
195 
196        /**
197         * Inserts a new event-note after another EventNote specified. Note that to
198         * keep the temporal order of the event-list, the scheduled time will be set
199         * to the same time as the referred "afterNote". Note also, that afterNote
200         * must be contained in the event-list. If the referred "where" is not
201         * contained in the event-list, there is no chance to determine the time
202         * that the new note is intended to be scheduled at. Thus the new event-note
203         * will not be inserted and a <code>EventNotScheduledException</code> will
204         * be thrown, stopping the simulation.
205         * 
206         * @param where
207         *            EventNote : The event-note containing the event after which the
208         *            new note is supposed to be inserted into the event-list.
209         * @param newNote
210         *            EventNote : The new event-note to be inserted after the
211         *            specified EventNote in the event-list.
212         * @throws SimAbortedException
213         *                : if referred EventNote is not contained in the event-list
214         */
215        void insertAfter(EventNote where, EventNote newNote) {
216            
217        // code for adding EventNote to all possible entities
218        Entity who1 = newNote.getEntity1();
219        if (who1 != null)
220        {
221            who1.addEventNote(newNote);
222        }
223        
224        Entity who2 = newNote.getEntity2();
225        if (who2 != null)
226        {
227            who2.addEventNote(newNote);
228        }
229        
230        Entity who3 = newNote.getEntity3();
231        if (who3 != null)
232        {
233            who3.addEventNote(newNote);
234        }
235        
236        EventAbstract Event = newNote.getEvent();
237        if (Event != null) {
238            Event.addEventNote(newNote);
239        }
240 
241                int i = eVector.indexOf(where);
242 
243                if (i < 0) { // negative index means, that where is not contained
244                        Model mBuffer = null; // buffer current model
245                        if (newNote.getEntity1() != null) {
246                                mBuffer = newNote.getEntity1().getModel();
247                        }
248                        if (newNote.getEvent() != null) {
249                                mBuffer = newNote.getEvent().getModel();
250                        }
251                        throw new SimAbortedException(
252                                        new ErrorMessage(
253                                                        mBuffer,
254                                                        "Can not insert new event-note after given EventNote! "
255                                                                        + "Simulation aborted",
256                                                        "Internal DESMO-J class : EventVector Method : "
257                                                                        + "insertAfter(EventNote where, EventNote newNote)",
258                                                        "The event-note to insert the new note after is not contained "
259                                                                        + "in the event vector.",
260                                                        "This is a fatal error. Contact DESMOJ support",
261                                                        newNote.getTime()));
262                } else { // if where is contained, put newNote at next position
263                        newNote.setTime(where.getTime());
264                        // synchronize times to keep order
265                        eVector.insertElementAt(newNote, i + 1);
266                        // everything fine, exit...
267                        
268                }
269 
270        }
271 
272        /**
273         * Inserts the given EventNote at the first position in the event-list. The
274         * Event encapsulated in that EventNote will probably be the next event to
275         * be processed by the scheduler (unless some other calls to this method are
276         * made before). Note that the time of the new event-note is set to the
277         * actual simulation time.
278         * 
279         * @param newNote
280         *            EventNote : The event-note to be inserted at the first position
281         *            in the event-list.
282         */
283        void insertAsFirst(EventNote newNote) {
284 
285                eVector.insertElementAt(newNote, 0);
286                
287                Entity who1 = newNote.getEntity1();
288                if (who1 != null)
289                {
290                                who1.addEventNote(newNote);
291                }
292                
293                Entity who2 = newNote.getEntity2();
294                if (who2 != null)
295                {
296                        who2.addEventNote(newNote);
297                }
298                
299                Entity who3 = newNote.getEntity3();
300                if (who3 != null)
301                {
302                        who3.addEventNote(newNote);
303                }
304                
305        EventAbstract Event = newNote.getEvent();
306        if (Event != null) {
307            Event.addEventNote(newNote);
308        }
309 
310        }
311 
312        /**
313         * Inserts an event-note at the last position in the event-list. Also adapts
314         * the new event-note's scheduled point of time to the same time as the last
315         * elment in the event-list. Time is not changed, if the event-list is
316         * empty.
317         * 
318         * @param newNote
319         *            EventNote : The event-note to be inserted at the last position
320         *            in the event-list.
321         */
322        void insertAsLast(EventNote newNote) {
323 
324                if (!isEmpty()) // if notes in EventList, set time to time of last note
325                        newNote.setTime(eVector.lastElement().getTime());
326 
327                eVector.addElement(newNote); // always append note to end of
328                // EventList
329                
330                // code for adding EventNote to all possible Entity
331                
332                Entity who1 = newNote.getEntity1();
333                if (who1 != null)
334                {
335                                who1.addEventNote(newNote);
336                }
337                
338                Entity who2 = newNote.getEntity2();
339                if (who2 != null)
340                {
341                        who2.addEventNote(newNote);
342                }
343                
344                Entity who3 = newNote.getEntity3();
345                if (who3 != null)
346                {
347                        who3.addEventNote(newNote);
348                }
349                
350        EventAbstract Event = newNote.getEvent();
351        if (Event != null) {
352            Event.addEventNote(newNote);
353        }
354 
355        }
356 
357        /**
358         * Inserts a new event-note before another EventNote specified. Note that
359         * this could disturb the temporal order of the event-list. So this method
360         * should only be used carefully. Note also, that EventNote 'where' must be
361         * contained in the event-list or otherwise an exception will be thrown.
362         * 
363         * @param where
364         *            EventNote : The event-note containing the event before which
365         *            the newNote is supposed to be inserted into the event-list.
366         * @param newNote
367         *            EventNote : The new event-note to be inserted before the
368         *            specified EventNote in the event-list
369         * @throws SimAbortedException
370         *                : if referred EventNote is not contained in the event-list
371         */
372        void insertBefore(EventNote where, EventNote newNote) {
373            
374        // code for adding EventNote to all possible entities
375        
376        Entity who1 = newNote.getEntity1();
377        if (who1 != null)
378        {
379            who1.addEventNote(newNote);
380        }
381        
382        Entity who2 = newNote.getEntity2();
383        if (who2 != null)
384        {
385            who2.addEventNote(newNote);
386        }
387        
388        Entity who3 = newNote.getEntity3();
389        if (who3 != null)
390        {
391            who3.addEventNote(newNote);
392        }
393        
394        EventAbstract Event = newNote.getEvent();
395        if (Event != null) {
396            Event.addEventNote(newNote);
397        }
398 
399                int i = eVector.indexOf(where);
400 
401                if (i < 0) {
402                        Model mBuffer = null; // buffer current model
403                        if (newNote.getEntity1() != null) {
404                                mBuffer = newNote.getEntity1().getModel();
405                        }
406                        if (newNote.getEvent() != null) {
407                                mBuffer = newNote.getEvent().getModel();
408                        }
409                        throw new SimAbortedException(
410                                        new ErrorMessage(
411                                                        mBuffer,
412                                                        "Can not insert new event-note before given EventNote! "
413                                                                        + "Simulation aborted",
414                                                        "Internal DESMO-J class : EventVector Method : "
415                                                                        + "insertBefore(EventNote where, EventNote newNote)",
416                                                        "The event-note to insert the new note before is not contained "
417                                                                        + "in the event vector.",
418                                                        "This is a fatal error. Contact DESMOJ support",
419                                                        newNote.getTime()));
420                } 
421                else 
422                {
423                        newNote.setTime(where.getTime());
424                        // synchronize times to keep order
425                        eVector.insertElementAt(newNote, i);
426                        // insert newN. & push afterN. one up
427                        
428                }
429 
430        }
431 
432        /**
433         * Tests if there are any scheduled events contained in the event-list. If
434         * the event-list happens to be empty during the run of a simulation, this
435         * is a criterium to stop the simulation, since no further action is
436         * scheduled.
437         * 
438         * @return boolean : True if there are no Event notes contained in the
439         *         event-list, false otherwise.
440         */
441        boolean isEmpty() {
442 
443                return eVector.isEmpty();
444                // simply pass the call through to the Vector.
445 
446        }
447 
448        /**
449         * Returns the last EventNote in the event-list. If the event-list is empty,
450         * <code>null</code> will be returned.
451         * 
452         * @return EventNote : the last EventNote in the event-list, null if the
453         *         event-list is empty
454         */
455        EventNote lastNote() {
456 
457                if (isEmpty())
458                        return null; // Nothing here, nothign to return...
459                else
460                        return eVector.elementAt(eVector.size());
461                // return last
462 
463        }
464 
465        /**
466         * Returns the next event-note in the event-list relative to the given
467         * EventNote. If the given EventNote is not contained in the event-list or
468         * happens to be the last EventNote in the event-list, null will be
469         * returned.
470         * 
471         * @return EventNote : The event-note following the given EventNote or
472         *         <ocde>null</code> if the given EventNote was last or not found
473         * @param origin
474         *            EventNote : The event-note whose successor is wanted
475         */
476        EventNote nextNote(EventNote origin) {
477 
478                if (eVector.contains(origin)) {
479                        if (origin == eVector.lastElement()) {
480                                return null;
481                        } else
482                                return eVector.elementAt(eVector.indexOf(origin) + 1);
483                }
484                return null;
485 
486        }
487 
488        /**
489         * Returns the previous EventNote in the event-list relative to the given
490         * EventNote. If the given EventNote is not contained in the event-list or
491         * happens to be the first event-note in the event-list, null will be
492         * returned.
493         * 
494         * @return EventNote : The event-note following the given EventNote or
495         *         <ocde>null</code> if the given EventNote was first or not found
496         * @param origin
497         *            EventNote : The event-note whose predecessor is wanted
498         */
499        EventNote prevNote(EventNote origin) {
500 
501                if (eVector.contains(origin)) {
502                        if (origin == eVector.firstElement()) {
503                                return null;
504                        }
505                        return eVector.elementAt(eVector.indexOf(origin) - 1);
506                }
507                return null;
508 
509        }
510 
511        /**
512         * Removes the given EventNote from the event-list.
513         * 
514         * Warning: Make sure to tell the entity of the event-note to delete
515         * the Note from its List as well.
516         * 
517         * @param note
518         *            EventNote : The event-note to be removed from the event-list
519         */
520        void remove(EventNote note) {
521 
522                if (!eVector.contains(note))
523                        return; // do nothing if it doesn't exist
524                else
525                {
526                        eVector.removeElement(note); // go ahead and crunch it!
527                        
528                        if (note.getEntity1() != null) // if an entity exists (no external event)
529                        {
530                                note.getEntity1().removeEventNote(note); // removes list entry in Entity!
531                        }
532                        
533                        if (note.getEntity2() != null) // if an entity exists (no external event)
534                        {
535                                note.getEntity2().removeEventNote(note); // removes list entry in Entity!
536                        }
537                        
538                        if (note.getEntity3() != null) // if an entity exists (no external event)
539                        {
540                                note.getEntity3().removeEventNote(note); // removes list entry in Entity!
541                        }
542                        
543            if (note.getEvent() != null)   // if an event exists
544            {
545                note.getEvent().removeEventNote(note);      // remove EventNote
546            }
547                }
548 
549        }
550 
551        /**
552         * Removes the first event-note from the event-list. Does nothing if the
553         * event-list is already empty.
554         * 
555         * Warning: Make sure to tell the entity of the event-note to delete
556         * the Note from its List as well.
557         */
558        void removeFirst() {
559 
560                if (!eVector.isEmpty())
561                {
562                        EventNote note = eVector.get(0);
563                        eVector.removeElementAt(0); // no comment ;-)
564                        
565                        if (note.getEntity1() != null) // if an entity exists (no external event)
566                        {
567                                note.getEntity1().removeEventNote(note); // removes list entry in Entity!
568                        }
569                        
570                        if (note.getEntity2() != null) // if an entity exists (no external event)
571                        {
572                                note.getEntity2().removeEventNote(note); // removes list entry in Entity!
573                        }
574                        
575                        if (note.getEntity3() != null) // if an entity exists (no external event)
576                        {
577                                note.getEntity3().removeEventNote(note); // removes list entry in Entity!
578                        }
579 
580                        if (note.getEvent() != null)   // if an event exists
581            {
582                note.getEvent().removeEventNote(note);      // remove EventNote
583            }
584                }
585 
586        }
587 
588        /**
589         * Returns a string representing the entries of this vector in a row. The
590         * resulting string includes all Event notes in ascending order as they are
591         * placed inside the event vector.
592         */
593        public String toString() {
594 
595                StringBuffer textBuffer = new StringBuffer();
596                // faster than String and '+'
597                java.util.Enumeration<EventNote> notes = eVector.elements(); // get all elements
598 
599                while (notes.hasMoreElements()) { // loop through all elements
600                        textBuffer.append("[");
601                        textBuffer.append(notes.nextElement());
602                        textBuffer.append("]"); // compose Note
603                }
604 
605                return textBuffer.toString();
606                // return String representation of StringBuffer
607 
608        }
609}

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