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

COVERAGE SUMMARY FOR SOURCE FILE [ProcessQueue.java]

nameclass, %method, %block, %line, %
ProcessQueue.java0%   (0/2)0%   (0/31)0%   (0/1272)0%   (0/365)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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