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

COVERAGE SUMMARY FOR SOURCE FILE [Queue.java]

nameclass, %method, %block, %line, %
Queue.java0%   (0/2)0%   (0/30)0%   (0/1238)0%   (0/328)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Queue0%   (0/1)0%   (0/26)0%   (0/1195)0%   (0/317)
Queue (Model, String, boolean, boolean): void 0%   (0/1)0%   (0/18)0%   (0/5)
Queue (Model, String, int, int, boolean, boolean): void 0%   (0/1)0%   (0/99)0%   (0/33)
createReporter (): Reporter 0%   (0/1)0%   (0/5)0%   (0/1)
first (): Entity 0%   (0/1)0%   (0/4)0%   (0/1)
first (Condition): Entity 0%   (0/1)0%   (0/45)0%   (0/13)
get (Entity): int 0%   (0/1)0%   (0/5)0%   (0/1)
get (int): Entity 0%   (0/1)0%   (0/5)0%   (0/1)
getQueueList (): QueueList 0%   (0/1)0%   (0/3)0%   (0/1)
getQueueStrategy (): String 0%   (0/1)0%   (0/4)0%   (0/1)
getRefused (): long 0%   (0/1)0%   (0/3)0%   (0/1)
insert (Entity): boolean 0%   (0/1)0%   (0/161)0%   (0/35)
insertAfter (Entity, Entity): boolean 0%   (0/1)0%   (0/197)0%   (0/47)
insertBefore (Entity, Entity): boolean 0%   (0/1)0%   (0/201)0%   (0/46)
isEmpty (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
iterator (): Iterator 0%   (0/1)0%   (0/6)0%   (0/1)
last (): Entity 0%   (0/1)0%   (0/4)0%   (0/1)
last (Condition): Entity 0%   (0/1)0%   (0/45)0%   (0/14)
pred (Entity): Entity 0%   (0/1)0%   (0/24)0%   (0/7)
pred (Entity, Condition): Entity 0%   (0/1)0%   (0/57)0%   (0/19)
remove (Entity): void 0%   (0/1)0%   (0/97)0%   (0/21)
remove (int): boolean 0%   (0/1)0%   (0/21)0%   (0/6)
reset (): void 0%   (0/1)0%   (0/6)0%   (0/3)
setQueueStrategy (int): void 0%   (0/1)0%   (0/74)0%   (0/23)
setSeed (long): void 0%   (0/1)0%   (0/26)0%   (0/9)
succ (Entity): Entity 0%   (0/1)0%   (0/24)0%   (0/7)
succ (Entity, Condition): Entity 0%   (0/1)0%   (0/57)0%   (0/19)
     
class Queue$QueueIterator0%   (0/1)0%   (0/4)0%   (0/43)0%   (0/11)
Queue$QueueIterator (Queue, Queue): void 0%   (0/1)0%   (0/16)0%   (0/5)
hasNext (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
next (): Entity 0%   (0/1)0%   (0/14)0%   (0/3)
remove (): void 0%   (0/1)0%   (0/6)0%   (0/2)

1package desmoj.core.simulator;
2 
3import java.util.Iterator;
4 
5/**
6 * Queue provides models with a ready-to-use modelling element to enqueue
7 * entities in. The sort order of the queue is determined first
8 * by the priorities of the enqueued entities and second by the given sort
9 * order. The default sort order is FIFO (first in, first out) but others like
10 * LIFO (last in, first out) can be chosen, too. See the constants in class
11 * <code>QueueBased</code> and the derived classes from <code>QueueList</code>.
12 * The capacity of the Queue, that is the maximum number of entities enqueued,
13 * can be chosen, too.
14 * <p>
15 * For queueing <code>SimProcess</code>es the usage of class
16 * <code>ProcessQueue</code> is recommended.  
17 * 
18 * 
19 * @see QueueBased
20 * @see QueueList
21 * @see QueueListFifo
22 * @see QueueListLifo
23 * @see ProcessQueue
24 * 
25 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
26 * @author Tim Lechler
27 * @author modified by Soenke Claassen
28 * 
29 * Licensed under the Apache License, Version 2.0 (the "License");
30 * you may not use this file except in compliance with the License. You
31 * may obtain a copy of the License at
32 * http://www.apache.org/licenses/LICENSE-2.0
33 *
34 * Unless required by applicable law or agreed to in writing, software
35 * distributed under the License is distributed on an "AS IS"
36 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
37 * or implied. See the License for the specific language governing
38 * permissions and limitations under the License.
39 *
40 */
41public class Queue<E extends Entity> extends QueueBased implements Iterable<E>{
42 
43        /**
44         * The queue implementation (data structure) that actually stores the
45         * entities
46         */
47        private QueueList<E> _ql;
48 
49        /**
50         * Counter for the entities which are refused to be enqueued, because the
51         * queue capacity is full.
52         */
53        private long _refused;
54        
55        /**
56         * Constructs a simple priority based waiting-queue for entities, the kind
57         * of queue sort order and the capacity of the queue can be chosen. 
58         * Note that since SimProcesses are derived from Entities, they can be 
59         * queued inside this queue, too.
60         * <p>
61         * Queues can be sorted as follows:<ul>
62     * <li><code>QueueBased.FIFO</code> sorts entities by their priority,
63     * highest priority first. Entities with the same priority are 
64     * enqueued based on &quot;first in, first out&quot;.</li>
65     * <li><code>QueueBased.LIFO</code> also sorts entities by their priority,
66     * highest priority first. However, entities with the same priority are 
67     * enqueued based on &quot;last in, first out&quot;.</li>
68     * <li><code>QueueBased.Random</code> assigns a random position to each
69     * entity entering the queue, disregarding priority.</li>
70     * </ul>
71         * <p>
72         * The usage of the generic version <code>Queue&lt;Type&gt;</code> where 
73         * <code>Type</code> is derived from <code>Entity</code> is recommended
74         * for type safety. Using the raw type <code>Queue</code> yields a queue
75         * in which any <code>Entity</code> can be enqueued, typically requiring
76         * type casting on accessing entities enqueued.  
77         * 
78         * @param owner
79         *            Model : The model this queue is associated to
80         * @param name
81         *            java.lang.String : The queue's name
82         * @param sortOrder
83         *            int : determines the sort order of the underlying queue
84         *            implementation. Choose a constant from <code>QueueBased</code>:
85         *            <code>QueueBased.FIFO</code>, <code>QueueBased.LIFO</code> or
86         *            QueueBased.Random.
87         * @param qCapacity
88         *            int : The capacity of the Queue, that is how many entities can
89         *            be enqueued. Zero (0) means unlimited capacity.
90         * @param showInReport
91         *            boolean : Flag if queue should produce a report
92         * @param showInTrace
93         *            boolean : Flag for queue to produce trace messages
94         */
95        public Queue(Model owner, String name, int sortOrder, int qCapacity,
96                        boolean showInReport, boolean showInTrace) {
97 
98                super(owner, name, showInReport, showInTrace); // create the QBased
99                // object
100                reset();
101            
102                // determine the queueing strategy
103            switch (sortOrder) {
104            case QueueBased.FIFO :
105                _ql = new QueueListFifo<E>(); break;
106        case QueueBased.LIFO :
107            _ql = new QueueListLifo<E>(); break;
108        case QueueBased.RANDOM :
109            _ql = new QueueListRandom<E>(); break;
110        default :
111            sendWarning(
112                    "The given sortOrder parameter " + sortOrder + " is not valid! "
113                            + "A queue with Fifo sort order will be created.",
114                    "Queue : "
115                            + getName()
116                            + " Constructor: Queue(Model owner, String name, "
117                            + "int sortOrder, long qCapacity, boolean showInReport, "
118                            + "boolean showInTrace)",
119                    "A valid positive integer number must be provided to "
120                            + "determine the sort order of the queue.",
121                    "Make sure to provide a valid positive integer number "
122                            + "by using the constants in the class QueueBased, like "
123                            + "QueueBased.FIFO, QueueBased.LIFO or QueueBased.RANDOM.");
124            _ql = new QueueListFifo<E>(); 
125            }
126 
127                // give the QueueList a reference to this QueueBased
128                _ql.setQueueBased(this);
129 
130                // set the capacity of the queue
131                queueLimit = qCapacity;
132 
133                // check if it the capacity does make sense
134                if (qCapacity < 0) {
135                        sendWarning(
136                                        "The given capacity of the queue is negative! "
137                                                        + "A queue with unlimited capacity will be created instead.",
138                                        "Queue : "
139                                                        + getName()
140                                                        + " Constructor: Queue(Model owner, String name, "
141                                                        + "int sortOrder, long qCapacity, boolean showInReport, "
142                                                        + "boolean showInTrace)",
143                                        "A negative capacity for a queue does not make sense.",
144                                        "Make sure to provide a valid positive capacity "
145                                                        + "for the queue.");
146                        // set the capacity to the maximum value
147                        queueLimit = Integer.MAX_VALUE;
148                }
149 
150                // check if qCapacity is zero (that means unlimited capacity)
151                if (qCapacity == 0) {
152                        // set the capacity to the maximum value
153                        queueLimit = Integer.MAX_VALUE;
154                }
155 
156        }
157 
158        /**
159         * Constructs a simple priority and FIFO based waiting-queue for entities
160         * with unlimited capacity of the queue. Note that since SimProcesses are
161         * derived from Entities, they can be queued inside this queue, too.
162     * <p>
163     * The usage of the generic version <code>Queue&lt;Type&gt;</code> where 
164     * <code>Type</code> is derived from <code>Entity</code> is recommended
165     * for type safety. Using the raw type <code>Queue</code> yields a queue
166     * in which any <code>Entity</code> can be enqueued, typically requiring
167     * type casting on accessing entities enqueued.  
168     * 
169         * @param owner
170         *            Model : The model this queue is associated to
171         * @param name
172         *            java.lang.String : The queue's name
173         * @param showInReport
174         *            boolean : Flag if queue should produce a report
175         * @param showInTrace
176         *            boolean : Flag for queue to produce trace messages
177         */
178        public Queue(Model owner, String name, boolean showInReport,
179                        boolean showInTrace) {
180 
181                super(owner, name, showInReport, showInTrace); // create the QBased
182                // object
183                reset();
184 
185                // make the queue with Fifo queueing discipline and unlimited capacity
186                _ql = new QueueListFifo<E>();
187                _ql.setQueueBased(this);
188 
189        }
190 
191        /**
192         * Returns a special queue reporter to produce a report about this queue.
193         * 
194         * @return desmoj.core.report.Reporter : The reporter for this queue
195         */
196        public desmoj.core.report.Reporter createReporter() {
197 
198                return new desmoj.core.report.QueueReporter(this);
199 
200        }
201 
202        /**
203         * Returns the first entity queued in this queue or <code>null</code> in
204         * case the queue is empty.
205         * 
206         * @return desmoj.core.Entity : The first entity in the queue or
207         *         <code>null</code> if the queue is empty
208         */
209        public E first() {
210 
211                return _ql.first(); // straight design
212 
213        }
214 
215        /**
216         * Returns the first entity queued in this queue that applies to the given
217         * condition. The queue is searched from front to end and the first entity
218         * that returns <code>true</code> when the condition is applied to it is
219         * returned by this method. If no Entity apply to the given condition or the
220         * queue is empty, <code>null</code> will be returned.
221         * 
222         * @return desmoj.core.Entity : The first entity queued in this queue applying to
223         *         the given condition or <code>null</code>
224         * @param c
225         *            Condition : The condition that the entity returned must comply
226         *            to
227         */
228        public E first(Condition<E> c) {
229 
230                if (c == null) {
231                        sendWarning(
232                                        "Can not return first entity complying to condition!",
233                                        "Queue : " + getName() + " Method: void first(Condition c)",
234                                        "The Condition 'c' given as parameter is a null reference!",
235                                        "Check to always have valid references when querying Queues.");
236                        return null; // no proper parameter
237                }
238                if (_ql.isEmpty())
239                        return null; // nobody home to be checked
240                for (E tmp = _ql.first(); tmp != null; tmp = _ql.succ(tmp)) {
241                        if (c.check(tmp))
242                                return tmp;
243                }
244                // if no Entity complies to the condition just return null
245                return null;
246 
247        }
248        
249           /**
250     * Returns the <code>Entity</code> queued at the named position.
251     * The first position is 0, the last one size()-1.
252     * 
253     * @return int :The position of the entity as an <code>int</code>. 
254     *              Returns -1 if no such position exists.
255     */
256    public int get(E e)  
257    {
258        
259        return _ql.get(e);
260        
261    }
262 
263    /**
264     * Returns the <code>Entity</code> queued at the named position.
265     * The first position is 0, the last one size()-1.
266     * 
267     * @return desmoj.core.Entity : The <code>Entity</code> at the position of
268     *         <code>int</code> or <code>null</code> if no such position exists.
269     */
270    public E get(int index)  
271    {
272        
273        return _ql.get(index);
274        
275    }
276        
277 
278        /**
279         * Returns the implemented queueing discipline of the underlying queue as a
280         * String, so it can be displayed in the report.
281         * 
282         * @return String : The String indicating the queueing discipline.
283         */
284        public String getQueueStrategy() {
285 
286                return _ql.getAbbreviation(); // that's it
287 
288        }
289 
290        /**
291         * Returns the number of entities refused to be enqueued in the queue.
292         * 
293         * @return long : The number of entities refused to be enqueued in the
294         *         queue.
295         */
296        public long getRefused() {
297 
298                return _refused; // that's it
299        }
300 
301        /**
302         * Enters a new Entity into the queue. If the capacity of the queue is full,
303         * the entity will not be enqueued and <code>false</code> will be
304         * returned. The Entity will be stored in the queue until method
305         * <code>remove(Entity e)</code> is called with this specific Entity.
306         * Entities inside the queue are ordered according to their priority. Higher
307         * priorities are sorted in front of lower priorities. Entities with same
308         * priority are orderer according to the specified strategy. The first
309         * Entity inside the queue will always be the one with the highest priority.
310         * 
311         * @return boolean : Is <code>true</code> if insertion was successful,
312         *         <code>false</code> otherwise (i.e. capacity limit is reached).
313         * @param e
314         *            Entity : The Entity to be added to the queue.
315         */
316        public boolean insert(E e) {
317 
318                if (e == null) { // null returns with warning
319                        sendWarning("Can not insert entity into Queue! Command ignored.",
320                                        "Queue : " + getName()
321                                                        + " Method: boolean insert(Entity e)",
322                                        "The Entity given as parameter is a null reference!",
323                                        "Check to always have valid references when enqueueing Entities");
324                        return false; // no proper parameter
325                }
326 
327                if (!isModelCompatible(e)) {
328                        sendWarning("Can not insert entity into Queue! Command ignored.",
329                                        "Queue : " + getName() + " Method: boolean insert"
330                                                        + "(Entity e)",
331                                        "The Entity given as parameter is not compatible to "
332                                                        + "the model this queue belongs to!",
333                                        "Check if your submodels are allowed to mingle with other "
334                                                        + "model's components.");
335                        return false; // not of my model type!!!
336                }
337 
338                if (queueLimit <= length()) {
339 
340                        if (currentlySendDebugNotes()) {
341                                sendDebugNote("refuses to insert " + e.getQuotedName()
342                                        + " because the " + "capacity limit is reached. Queue:<br>"
343                                        + _ql.toString());
344                        }
345 
346                        if (currentlySendTraceNotes()) {
347                                sendTraceNote("is refused to be enqueued in "
348                                        + this.getQuotedName() + "because the capacity limit ("
349                                        + getQueueLimit() + ") of this queue is " + "reached");
350                        }
351 
352                        _refused++; // count the refused ones
353 
354                        return false; // capacity limit is reached
355                }
356 
357                _ql.insert(e); // that's it
358 
359                if (currentlySendDebugNotes()) {
360                        sendDebugNote("inserts " + e.getQuotedName() + " in the queue:<br>"
361                                        + _ql.toString());
362                }
363 
364                // produce trace output
365                if (currentlySendTraceNotes()) {
366                        if (e == currentEntity() && currentEntityAll().size() == 1) {
367                                sendTraceNote("inserts itself into " + this.getQuotedName());
368                        } else {
369                                sendTraceNote("inserts " + e.getName() + " into "
370                                                + this.getQuotedName());
371                        }
372                }
373 
374                return true;
375        }
376 
377        /**
378         * Enters a new Entity into the queue and places it after the given Entity.
379         * If the capacity of the queue is full, the entity will not be enqueued and
380         * <code>false</code> will be returned. Make sure that the entity given as
381         * reference is already queued inside the queue, else the entity will not be
382         * enqueued and <code>false</code> will be returned. The Entity will be
383         * stored in the queue until method <code>remove(Entity e)</code> is
384         * called with this specific Entity.
385         * 
386         * @return boolean : Is <code>true</code> if insertion was successful,
387         *         <code>false</code> otherwise (i.e. capacity limit is reached).
388         * @param e
389         *            Entity : The Entity to be added to the queue
390         * @param after
391         *            Entity : The Entity after which the entity e is to be inserted
392         */
393        public boolean insertAfter(E e, E after) {
394 
395                if (e == null) {
396                        sendWarning(
397                                        "Can not insert entity into Queue! Command ignored.",
398                                        "Queue : "
399                                                        + getName()
400                                                        + " Method: boolean insertAfter(Entity e, Entity after)",
401                                        "The Entity -e- given as parameter is a null reference!",
402                                        "Check to always have valid references when enqueueing Entities");
403                        return false; // no proper parameter
404                }
405 
406                if (after == null) {
407                        sendWarning(
408                                        "Can not insert entity into Queue! Command ignored.",
409                                        "Queue : "
410                                                        + getName()
411                                                        + " Method: boolean insertAfter(Entity e, Entity after)",
412                                        "The Entity -after- given as parameter is a null reference!",
413                                        "Check to always have valid references when enqueueing Entities");
414                        return false; // no proper parameter
415                }
416 
417                if (!isModelCompatible(e)) {
418                        sendWarning("Can not insert entity into Queue! Command ignored.",
419                                        "Queue : " + getName() + " Method: boolean insertAfter"
420                                                        + "(Entity e, Entity after)",
421                                        "The Entity given as parameter is not compatible to "
422                                                        + "the model this queue belongs to!",
423                                        "Check if your submodels are allowed to mingle with other "
424                                                        + "model's components.");
425                        return false; // not of my model type!!!
426                }
427 
428                if (queueLimit <= length()) {
429 
430                        if (currentlySendDebugNotes()) {
431                                sendDebugNote("refuses to insert " + e.getQuotedName()
432                                        + " because the " + "capacity limit is reached. Queue:<br>"
433                                        + _ql.toString());
434                        }
435 
436                        if (currentlySendTraceNotes()) {
437                                sendTraceNote("is refused to be enqueued in "
438                                        + this.getQuotedName() + "because the capacity limit ("
439                                        + getQueueLimit() + ") of this queue is " + "reached");
440                        }
441 
442                        _refused++; // count the refused ones
443 
444                        return false; // capacity limit is reached
445                }
446 
447                boolean successful = _ql.insertAfter(e, after); // that's the point
448 
449                if (currentlySendDebugNotes()) {
450                        sendDebugNote("inserts " + e.getQuotedName() + " after "
451                                        + after.getQuotedName() + "<br>" + _ql.toString());
452                }
453 
454                // produce trace output
455                if (currentlySendTraceNotes()) {
456                        if (e == currentEntity() && currentEntityAll().size() == 1) {
457                                sendTraceNote("inserts itself into " + this.getQuotedName()
458                                                + " after " + after.getName());
459                        } else {
460                                sendTraceNote("inserts " + e.getName() + " into "
461                                                + this.getQuotedName() + " after " + after.getName());
462                        }
463                }
464 
465                return successful;
466 
467        }
468 
469        /**
470         * Enters a new Entity into the queue and places it in front of the given
471         * Entity. If the capacity of the queue is full, the entity will not be
472         * enqueued and <code>false</code> will be returned. Make sure that the
473         * Entity given as reference is already queued inside the queue, else the
474         * Entity will not be queued and <code>false</code> will be returned. The
475         * Entity will be stored in the queue until method
476         * <code>remove(Entity e)</code> is called with this specific Entity.
477         * 
478         * @return boolean : Is <code>true</code> if insertion was successful,
479         *         <code>false</code> otherwise (i.e. capacity limit is reached).
480         * @param e
481         *            Entity : The Entity to be added to the queue
482         * @param before
483         *            Entity : The Entity before which the entity e is to be
484         *            inserted
485         */
486        public boolean insertBefore(E e, E before) {
487 
488                if (e == null) {
489                        sendWarning("Can not insert entity into Queue! Command ignored.",
490                                        "Queue : " + getName()
491                                                        + " Method: boolean insertBefore(Entity e, "
492                                                        + "Entity before)",
493                                        "The Entity -e- given as parameter is a null reference!",
494                                        "Check to always have valid references when enqueueing Entities");
495                        return false; // no proper parameter
496                }
497                if (before == null) {
498                        sendWarning(
499                                        "Can not insert entity into Queue! Command ignored.",
500                                        "Queue : " + getName()
501                                                        + " Method: boolean insertBefore(Entity e, "
502                                                        + "Entity before)",
503                                        "The Entity -before- given as parameter is a null reference!",
504                                        "Check to always have valid references when enqueueing Entities");
505                        return false; // no proper parameter
506                }
507 
508                if (!isModelCompatible(e)) {
509                        sendWarning("Can not insert entity into Queue! Command ignored.",
510                                        "Queue : " + getName() + " Method: boolean insertBefore"
511                                                        + "(Entity e, Entity before)",
512                                        "The Entity given as parameter is not compatible to "
513                                                        + "the model this queue belongs to!",
514                                        "Check if your submodels are allowed to mingle with other "
515                                                        + "model's components.");
516                        return false; // not of my model type!!!
517                }
518 
519                if (queueLimit <= length()) {
520 
521                        if (currentlySendDebugNotes()) { 
522                                sendDebugNote("refuses to insert " + e.getQuotedName()
523                                        + " because the " + "capacity limit is reached. Queue:<br>"
524                                        + _ql.toString());
525                        }
526                        
527                        if (currentlySendTraceNotes()) {
528                                sendTraceNote("is refused to be enqueued in "
529                                        + this.getQuotedName() + "because the capacity limit ("
530                                        + getQueueLimit() + ") of this queue is " + "reached");
531                        }
532 
533                        _refused++; // count the refused ones
534 
535                        return false; // capacity limit is reached
536                }
537 
538                boolean successful = _ql.insertBefore(e, before); // that's the point
539 
540                if (currentlySendDebugNotes()) {
541                        sendDebugNote("inserts " + e.getQuotedName() + " before "
542                                        + before.getQuotedName() + "<br>" + _ql.toString());
543                }
544 
545                // produce trace output
546                if (currentlySendTraceNotes()) {
547                        if (e == currentEntity() && currentEntityAll().size() == 1) {
548                                sendTraceNote("inserts itself into " + this.getQuotedName()
549                                                + " before " + before.getName());
550                        } else {
551                                sendTraceNote("inserts " + e.getName() + " into "
552                                                + this.getQuotedName() + " before " + before.getName());
553                        }
554                }
555                
556                return successful;
557 
558        }
559 
560        /**
561         * Returns a boolean value indicating if the queue is empty or if any number
562         * of entities is currently enqueued in it.
563         * 
564         * @return boolean : Is <code>true</code> if the Queue is empty,
565         *         <code>false</code> otherwise
566         */
567        public boolean isEmpty() {
568 
569                return _ql.isEmpty();
570 
571        }
572 
573        /**
574         * Returns the last Entity queued in this queue or <code>null</code> in
575         * case the queue is empty.
576         * 
577         * @return Entity : The last Entity in the queue or <code>null</code>
578         *         if the queue is empty
579         */
580        public E last() {
581 
582                return _ql.last(); // straight design again
583 
584        }
585 
586        /**
587         * Returns the last Entity queued in this queue that applies to the given
588         * condition. The queue is searched from end to front and the first entity
589         * that returns <code>true</code> when the condition is applied to it is
590         * returned. If no Entity applies to the given condition or the queue is
591         * empty, <code>null</code> will be returned.
592         * 
593         * @return Entity : The last Entity queued in this queue applying to
594         *         the given condition or <code>null</code>
595         * @param c
596         *            Condition : The condition that the entity returned must comply
597         *            to
598         */
599        public E last(Condition<Entity> c) {
600 
601                if (c == null) {
602                        sendWarning(
603                                        "Can not insert entity!",
604                                        "Queue : " + getName()
605                                                        + " Method: Entity last(Condition c)",
606                                        "The Condition -c- given as parameter is a null reference!",
607                                        "Check to always have valid references when querying Queues.");
608                        return null; // no proper parameter
609                }
610 
611                if (_ql.isEmpty())
612                        return null; // nobody home to be checked
613                for (E tmp = _ql.last(); tmp != null; tmp = _ql.pred(tmp)) {
614                        if (c.check(tmp))
615                                return tmp;
616                }
617 
618                // if no Entity complies to the condition just return null
619                return null;
620 
621        }
622 
623        /**
624         * Returns the entity enqueued directly before the given Entity in the
625         * queue. If the given Entity is not contained in this queue or is at the
626         * first position thus having no possible predecessor, <code>null</code>
627         * is returned.
628         * 
629         * @return Entity : The Entity directly before the given Entity in
630         *         the queue or <code>null</code>.
631         * @param e
632         *            Entity : An Entity in the queue
633         */
634        public E pred(E e) {
635 
636                if (e == null) {
637                        sendWarning("Can not find predecessor of Entity in Queue!",
638                                        "Queue : " + getName() + " Method: Entity pred(Entity e)",
639                                        "The Entity -e- given as parameter is a null reference!",
640                                        "Check to always have valid references when querying for Entities");
641                        return null; // no proper parameter
642                }
643 
644                return _ql.pred(e);
645 
646        }
647 
648        /**
649         * Returns the entity enqueued before the given Entity in the queue that
650         * also complies to the condition given. If the given Entity is not
651         * contained in this queue or is at the first position thus having no
652         * possible predecessor, <code>null</code> is returned. If no other Entity
653         * before the given one complies to the condition, <code>null</code> is
654         * returned, too.
655         * 
656         * @return Entity : The Entity before the given Entity in the queue
657         *         complying to the condition or <code>null</code>.
658         * @param e
659         *            Entity : An Entity in the queue
660         * @param c
661         *            Condition : The condition that the preceeding Entity has to
662         *            comply to
663         */
664        public E pred(E e, Condition<E> c) {
665 
666                if (e == null) {
667                        sendWarning("Can not find predecessor of Entity in Queue!",
668                                        "Queue : " + getName()
669                                                        + " Method: Entity pred(Entity e, Condition c)",
670                                        "The Entity 'e' given as parameter is a null reference!",
671                                        "Check to always have valid references when querying "
672                                                        + "for Entities");
673                        return null; // no proper parameter
674                }
675 
676                if (c == null) {
677                        sendWarning(
678                                        "Can not return previous Entity complying to condition!",
679                                        "Queue : " + getName()
680                                                        + " Method: Entity pred(Entity e, Condition c)",
681                                        "The Condition 'c' given as parameter is a null reference!",
682                                        "Check to always have valid references when querying Queues.");
683                        return null; // no proper parameter
684                }
685 
686                for (E tmp = pred(e); tmp != null; tmp = pred(tmp)) {
687                        if (c.check(tmp))
688                                return tmp;
689                }
690 
691                return null; // obviously not found here, empty or doesn't comply
692        }
693 
694        /**
695         * Removes the given Entity from the Queue. If the given Entity is not in
696         * the Queue, a warning will be issued but nothing else will be changed.
697         * 
698         * @param e
699         *            Entity : The Entity to be removed
700         */
701        public void remove(E e) {
702 
703                if (e == null) {
704                        sendWarning("Can not remove Entity from Queue!", "Queue : "
705                                        + getName() + " Method:  void remove(Entity e)",
706                                        "The Entity 'e' given as parameter is a null reference!",
707                                        "Check to always have valid references when removing "
708                                                        + "Entities");
709                        return; // no proper parameter
710                }
711                if (!_ql.remove(e)) { // watch out, already removed as a side
712                        // effect!!!
713                        sendWarning("Can not remove Entity from Queue!", "Queue : "
714                                        + getName() + " Method:  void remove(Entity e)",
715                                        "The Entity 'e' given as parameter is not enqueued in this "
716                                                        + "queue!",
717                                        "Make sure the entity is inside the queue you want it to "
718                                                        + "be removed.");
719                        return; // not enqueued here
720                }
721 
722                if (currentlySendDebugNotes()) {
723                        sendDebugNote("remove " + e.getQuotedName() + "<br>"
724                                        + _ql.toString());
725                }
726 
727                // produce trace output
728                if (currentlySendTraceNotes()) {
729                        if (e == currentEntity() && currentEntityAll().size() == 1) {
730                                sendTraceNote("removes itself from " + this.getQuotedName());
731                        } else {
732                                sendTraceNote("removes " + e.getQuotedName() + " from "
733                                                + this.getQuotedName());
734                        }
735                }
736 
737        }
738        
739    /**
740     * Removes the entity queued at the given position.
741     * The first position is 0, the last one length()-1.
742     * 
743     * @return : The method returns <code>true</code> if an <code>Entity</code>
744     *           exists at the given position or <code>false></code> if otherwise.
745     */
746    public boolean remove(int index)  
747    {
748        if (index < 0 || index >= this.length()) return false;
749        
750        E e = get(index);
751        if (e == null) {
752            return false;
753        } else {
754            remove(e);
755            return true;
756        }
757    }   
758 
759        /**
760         * Resets all statistical counters to their default values. The mininum and
761         * maximum length of the queue are set to the current number of queued
762         * objects. The counter for the entities refused to be enqueued will be
763         * reset.
764         */
765        public void reset() {
766 
767                super.reset(); // reset of QueueBased
768 
769                _refused = 0;
770 
771        }
772        
773    /**
774     * Sets the sort order of this Queue to a new value and makes this
775     * Queue use another <code>QueueList</code> with the specified
776     * queueing discipline. Please choose a constant from
777     * <code>QueueBased</code> (<code>QueueBased.FIFO</code>, 
778     * <code>QueueBased.FIFO</code> or <code>QueueBased.Random</code>)
779     * The sort order of a Queue can only be changed if the queue is empty.
780     * 
781     * @param sortOrder
782     *            int : determines the sort order of the underlying
783     *            <code>QueueList</code> implementation (<code>QueueBased.FIFO</code>, 
784     * <code>QueueBased.FIFO</code> or <code>QueueBased.Random</code>)
785     */
786    public void setQueueStrategy(int sortOrder) {
787 
788        // check if the queue is empty
789        if (!isEmpty()) {
790            sendWarning(
791                    "The Queue for which the queueing discipline should be "
792                            + "changed is not empty. The queueing discipline will remain unchanged!",
793                    getClass().getName() + ": " + getQuotedName()
794                            + ", Method: "
795                            + "void setQueueStrategy(int sortOrder)",
796                    "The Queue already contains some entities ordered according a "
797                            + "certain order.",
798                    "Make sure to change the sort order only for an empty ProcessQueue.");
799 
800            return; // ignore that rubbish and just return
801        }
802 
803        // determine the queueing strategy
804        switch (sortOrder) {
805        case QueueBased.FIFO :
806            _ql = new QueueListFifo<E>(); break;
807        case QueueBased.LIFO :
808            _ql = new QueueListLifo<E>(); break;
809        case QueueBased.RANDOM :
810            _ql = new QueueListRandom<E>(); break;
811        default :
812            sendWarning(
813                    "The given sortOrder parameter is negative or too big! "
814                            + "The sort order of the ProcessQueue will remain unchanged!",
815                    getClass().getName() + ": " + getQuotedName()
816                            + ", Method: "
817                            + "void setQueueStrategy(int sortOrder)",
818                    "A valid positive integer number must be provided to "
819                            + "determine the sort order of the queue.",
820                    "Make sure to provide a valid positive integer number "
821                            + "by using the constants in the class QueueBased, like "
822                            + "QueueBased.FIFO, QueueBased.LIFO or QueueBased.RANDOM.");
823            return;
824        }
825        _ql.setQueueBased(this);
826    }
827 
828        /**
829         * Returns the entity enqueued directly after the given Entity in the queue.
830         * If the given Entity is not contained in this queue or is at the last
831         * position thus having no possible successor, <code>null</code> is
832         * returned.
833         * 
834         * @return Entity : The Entity directly after the given Entity in the
835         *         queue or <code>null</code>.
836         * @param e
837         *            Entity : An Entity in the queue
838         */
839        public E succ(E e) {
840 
841                if (e == null) {
842                        sendWarning("Can not find successor of Entity in Queue!",
843                                        "Queue : " + getName() + " Method: Entity succ(Entity e)",
844                                        "The Entity 'e' given as parameter is a null reference!",
845                                        "Check to always have valid references when querying for Entities");
846                        return null; // no proper parameter
847                }
848 
849                return _ql.succ(e);
850 
851        }
852 
853        /**
854         * Returns the entity enqueued after the given Entity in the queue that also
855         * complies to the condition given. If the given Entity is not contained in
856         * this queue or is at the last position thus having no possible successor,
857         * <code>null</code> is returned. If no other Entity after the given one
858         * complies to the condition, <code>null</code> is returned, too.
859         * 
860         * @return Entity : The Entity after the given Entity in the queue
861         *         complying to the condition or <code>null</code>.
862         * @param e
863         *            Entity : An Entity in the queue
864         * @param c
865         *            Condition : The condition that the succeeding Entity has to
866         *            comply to
867         */
868        public E succ(E e, Condition<E> c) {
869 
870                if (e == null) {
871                        sendWarning("Can not find predecessor of Entity in Queue!",
872                                        "Queue : " + getName()
873                                                        + " Method: Entity succ(Entity e, Condition c)",
874                                        "The Entity 'e' given as parameter is a null reference!",
875                                        "Check to always have valid references when querying for Entities");
876                        return null; // no proper parameter
877                }
878 
879                if (c == null) {
880                        sendWarning(
881                                        "Can not return previous Entity complying to condition!",
882                                        "Queue : " + getName()
883                                                        + " Method: Entity succ(Entity e, Condition c)",
884                                        "The Condition 'c' given as parameter is a null reference!",
885                                        "Check to always have valid references when querying Queues.");
886                        return null; // no proper parameter
887                }
888 
889                for (E tmp = succ(e); tmp != null; tmp = succ(tmp)) {
890                        if (c.check(tmp))
891                                return tmp;
892                }
893 
894                return null; // obviously not found here, empty or doesn't comply
895 
896        }
897        
898    /**
899     * Returns the underlying queue implementation, providing access to the
900     * QueueList implementation, e.g. to add PropertyChangeListeners.
901     * 
902     * @return desmoj.core.simulator.QueueList : The underlying queue implementation of this
903     *         Queue.
904     */
905    public QueueList<E> getQueueList() {
906 
907        return _ql; // that's all
908    }
909        
910        
911    /**
912     * Sets the seed of the underlying queue list's pseudo random number generator. 
913     * Useful for queues with random sort order only; to other queues, calling
914     * this method has no effect, resulting in a warning.  
915     * 
916     * @param newSeed
917     *            long : new seed of the underlying queue list's pseudo 
918     *            random number generator
919     */
920    public void setSeed(long newSeed) {
921        if (_ql instanceof QueueListRandom<?>) {
922            ((QueueListRandom<?>) _ql).setSeed(newSeed);
923        } else {
924            sendWarning(
925                    "Cannot set seed of queue!",
926                    "Queue : " + getName()
927                            + " Method: setSeed(long newSeed)",
928                    "The queue does not randomize entries.",
929                    "Make sure to call setSeed(long newSeed) " +
930                            "on queues with <tt>sortOrder == QueueBased.RANDOM</tt> only.");
931        }
932    }
933    
934        
935    /**
936     * Returns an iterator over the entities enqueued.
937     *
938     * @return java.lang.Iterator&lt;E&gt; : An iterator over the entities enqueued.
939     */
940        public Iterator<E> iterator() {
941        return new QueueIterator(this);
942    }
943 
944    /**
945         * Private queue iterator, e.g. required for processing all queue elements in a 
946         * for-each-loop.
947         */
948    private class QueueIterator implements Iterator<E> {
949        
950        Queue<E> clientQ; 
951        E next, lastReturned;
952        
953        public QueueIterator(Queue<E> clientQ) {
954            this.clientQ = clientQ;
955            next = clientQ.first();
956            lastReturned = null;
957        }
958        public boolean hasNext() {
959            return next != null;
960        }
961        public E next() {
962            lastReturned = next;
963            next = clientQ.succ(next);
964            return lastReturned;
965        }
966        public void remove() {
967            clientQ.remove(lastReturned);
968        }
969    }
970}

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