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

COVERAGE SUMMARY FOR SOURCE FILE [QueueListStandard.java]

nameclass, %method, %block, %line, %
QueueListStandard.java0%   (0/1)0%   (0/20)0%   (0/504)0%   (0/191)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class QueueListStandard0%   (0/1)0%   (0/20)0%   (0/504)0%   (0/191)
QueueListStandard (): void 0%   (0/1)0%   (0/13)0%   (0/4)
checkProcess (SimProcess): boolean 0%   (0/1)0%   (0/25)0%   (0/14)
contains (Entity): boolean 0%   (0/1)0%   (0/15)0%   (0/8)
first (): Entity 0%   (0/1)0%   (0/11)0%   (0/3)
get (Entity): int 0%   (0/1)0%   (0/5)0%   (0/1)
get (int): Entity 0%   (0/1)0%   (0/41)0%   (0/13)
getAbbreviation (): String 0%   (0/1)0%   (0/3)0%   (0/1)
insertAfter (Entity, Entity): boolean 0%   (0/1)0%   (0/51)0%   (0/22)
insertBefore (Entity, Entity): boolean 0%   (0/1)0%   (0/49)0%   (0/22)
isEmpty (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
last (): Entity 0%   (0/1)0%   (0/11)0%   (0/3)
pred (Entity): Entity 0%   (0/1)0%   (0/35)0%   (0/11)
propertyChange (PropertyChangeEvent): void 0%   (0/1)0%   (0/44)0%   (0/16)
remove (Entity): boolean 0%   (0/1)0%   (0/47)0%   (0/23)
remove (int): boolean 0%   (0/1)0%   (0/33)0%   (0/12)
removeFirst (): boolean 0%   (0/1)0%   (0/16)0%   (0/8)
removeLast (): boolean 0%   (0/1)0%   (0/16)0%   (0/8)
sendWarning (String, String, String, String): void 0%   (0/1)0%   (0/12)0%   (0/3)
succ (Entity): Entity 0%   (0/1)0%   (0/35)0%   (0/11)
toString (): String 0%   (0/1)0%   (0/38)0%   (0/7)

1package desmoj.core.simulator;
2 
3import java.beans.PropertyChangeListener;
4import java.util.HashMap;
5import java.util.LinkedList;
6import desmoj.core.simulator.Entity;
7import desmoj.core.simulator.QueueBased;
8 
9/**
10 * Is the class summing up all the collective implementation of different
11 * queueing strategies for a queue list. It provides all the basic methods
12 * for inserting objects in a queue, retrieving objects from a queue and getting
13 * basic informations about the queue. It is used in many kinds of queue
14 * implementations e.g. in the classes <code>QueueListFifo</code> and
15 * <code>QueueListLifo</code>.
16 * 
17 * @see QueueBased
18 * @see Queue
19 * @see ProcessQueue
20 * @see QueueListFifo
21 * @see QueueListLifo
22 * 
23 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
24 * @author Justin Neumann
25 * @author based upon ideas from Tim Lechler, Soenke Claassen, Johannes Goebel
26 * 
27 * Licensed under the Apache License, Version 2.0 (the "License");
28 * you may not use this file except in compliance with the License. You
29 * may obtain a copy of the License at
30 * http://www.apache.org/licenses/LICENSE-2.0
31 *
32 * Unless required by applicable law or agreed to in writing, software
33 * distributed under the License is distributed on an "AS IS"
34 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
35 * or implied. See the License for the specific language governing
36 * permissions and limitations under the License.
37 *
38 */
39public abstract class QueueListStandard<E extends Entity> extends QueueList<E> implements PropertyChangeListener  {
40 
41        /**
42         * An abbreviation to identify the sort of queueing discipline (like FIFO or
43         * LIFO or ...)
44         */
45        protected java.lang.String abbreviation;
46 
47        /**
48         * Uses the java.util.LinkedList for implementation
49         */
50        protected java.util.LinkedList<E> queuelist;
51        
52 
53        /**
54         * Constructs an empty <code>QueueList</code> with no reference to its
55         * client QueueBased. This no-arg constructor is necessary to instantiate an
56         * object of this class by calling the
57         * <code>java.lang.Class.newInstance()</code> method. The reference to the
58         * QueueBased object making use of this queue-functionality must be provided
59         * later by calling the setQueueBased() method. The initial length is always
60         * zero.
61         */
62        public QueueListStandard()
63        {
64                
65                super();
66                
67                //the here used java.LinkedList
68                queuelist = new LinkedList<E>();
69                
70                //the here used java.WeakHashMap
71                timemap = new HashMap<E,TimeInstant>();
72 
73        }
74        
75        /**
76         * Checks whether the process using the QueueList is a valid SimProcess.
77         * 
78         * @return boolean : Returns whether the sim-process is valid or not.
79         * @param proc
80         *            desmoj.SimProcess : Is this SimProcess a valid one?
81         */
82        protected boolean checkProcess(SimProcess proc) {
83 
84                if (proc == null) // if proc is a null pointer instead of a process
85                {
86                        sendWarning("A non existing process was stored in a queue. "
87                                        + "The attempted action is ignored!",
88                                        "QueueListStandardFifo, Method: first(); called by Class: Stock, Method: "
89                                                        + "store(long n) or retrieve(long n)",
90                                        "The process is only a null pointer.",
91                                        "Make sure that only real SimProcesses are stored in a queue.");
92                        return false;
93                }
94 
95                if (!getQueueBased().isModelCompatible(proc)) // if proc is not
96                // modelcompatible
97                {
98                        sendWarning(
99                                        "The process trying to use a QueueList object does not "
100                                                        + "belong to this model. The attempted action is ignored!",
101                                        "QueueListStandardFifo, Method: first(); called by Class: Stock, Method: "
102                                                        + "store(long n) or retrieve(long n)",
103                                        "The process is not modelcompatible.",
104                                        "Make sure that processes are using only queues within their model.");
105                        return false;
106                }
107 
108                return true;
109        }
110        
111        /**
112         * Returns true if the given Entity is contained in the list, false
113         * otherwise.
114         * 
115         * @return boolean : True if the given Entity is contained in the list,
116         *         false otherwise
117         * @param e
118         *            Entity : The Entity assumed to be in the list
119         */
120        public boolean contains(E e) {
121 
122                if (e == null) { // check for nullreference
123                        sendWarning(
124                                        "Can not check if the given Entity is contained in QueueListStandardFifo. "
125                                                        + "Command ignored!",
126                                        "Class: QueueListStandardFifo Method: boolean contains(Entity e).",
127                                        "The Entity reference given as parameter is a null reference.",
128                                        "Be sure to only use valid references.");
129                        return false;
130                }
131 
132                return queuelist.contains(e);
133 
134        }
135        
136        /**
137         * Returns the first entity stored in the list. If the queue is empty,
138         * <code>null</code> is returned.
139         * 
140         * @return Entity : The first entity in the list or <code>null</code> if
141         *         list is empty
142         */
143    public E first() {
144        if (queuelist.isEmpty()) {
145            return null;
146        } else { 
147            return queuelist.getFirst();
148        }
149    }
150 
151        /**
152         * Returns the position of the named <code>Entity</code>.
153         * The first position is 0, the last one size()-1.
154         * 
155         * @return : The position of the <code>Entity</code> or <code>-1</code> if no such exists.
156         */
157        public int get(E element) 
158        {
159                
160                return queuelist.indexOf(element);
161                        
162        }
163 
164        /**
165         * Returns the <code>Entity</code> queued at the named position.
166         * The first position is 0, the last one size()-1.
167         * 
168         * @return Entity : The <code>Entity</code> at the position of
169         *         <code>int</code> or <code>null</code> if no such position exists.
170         */
171        public E get(int index)  {
172                
173                // check if there are elements queued
174                if (isEmpty()) {
175                        sendWarning("Can not remove Entity. Command ignored.",
176                                        "Class: QueueListStandardFifo Method: boolean remove(Entity e).",
177                                        "The Queue is empty, no Entities are contained.",
178                                        "Check if an entity is enqueued by calling method "
179                                                        + "contains(Entity e).");
180                        return null;
181                }
182                
183                if ((index > this.size()-1) | (index < 0)) 
184                {
185                        sendWarning("Can not retrieve index. Command ignored.",
186                                        "Class: QueueListStandard Method: Entity get(int index).",
187                                        "The index of the method is out of the list range.",
188                                        "Check correct position in queue.");
189                        return null;
190                }
191                
192                return queuelist.get(index);
193                
194        }
195        
196        /**
197         * Returns an abbreviation as a String to identify the sort of queueing
198         * discipline (like FIFO or LIFO or ...). Is used to display the queueing
199         * discipline in the report of the QueueBased objects.
200         * 
201         * @return java.lang.String : An abbreviation to identify the sort of
202         *         queueing discipline (like FIFO or LIFO or ...)
203         */
204        public String getAbbreviation()
205        {
206 
207                return abbreviation;
208        }
209 
210        /**
211         * Adds a new Entity to the QueueList. Entities are inserted according
212         * to their priority in descending order. The highest priority Entity will
213         * always be first in the queue. Entities with same priority are inserted in
214         * specified order.
215         * 
216         * Do not forget to call the <code>statisticalInsert()</code> and
217         * to set the queue for each entity as you define this method.
218         * 
219         * @param e
220         *            Entity : The Entity to add to the QueueList
221         */
222        abstract public void insert(E e);
223 
224        /**
225         * Inserts the given "e" after the position of "which" in the QueueList.
226         * Returns true if "e" is inserted correctly after "which". If the list is
227         * empty or the referenced "which" is not contained, the "e" will not be
228         * inserted and false is returned.
229         * 
230         * @return boolean : Is <code>true</code> if inserted correctly,
231         *         <code>false</code> otherwise
232         * @param e
233         *            Entity : The Entity to be inserted
234         * @param which
235         *            Entity : The referenced Entity that the given "e" has to be
236         *            inserted after
237         */
238        boolean insertAfter(E e, E which) {
239 
240                if (e == null) { // check for null reference
241                        sendWarning("Can not insert entity. Command ignored.",
242                                        "Class 'QueueListStandardFifo' Method: boolean insertAfter(Entity e, "
243                                                        + "Entity which).",
244                                        "The Entity reference 'e' given as parameter is a null "
245                                                        + "reference.",
246                                        "Be sure to only use valid references.");
247                        return false;
248                }
249 
250                if (which == null) { // check for null reference
251                        sendWarning("Can not insert entity. Command ignored.",
252                                        "Class 'QueueListStandardFifo' Method: boolean insertAfter(Entity e, "
253                                                        + "Entity which).",
254                                        "The Entity reference 'which' given as parameter is a null "
255                                                        + "reference.",
256                                        "Be sure to only use valid references.");
257                        return false;
258                }
259 
260                if (contains(e)) { // entity must not be contained twice in the queue
261                        sendWarning("Can not insert entity. Command ignored.",
262                                        "Class 'QueueListStandardFifo' Method: boolean insertAfter(Entity e, "
263                                                        + "Entity which).",
264                                        "The Entity 'e' given as parameter is already enqueued.",
265                                        "Make sure the entity is not enqueued here by calling "
266                                                        + "method 'contains(Entity e)'.");
267                        return false;
268                }
269 
270                queuelist.add(queuelist.indexOf(which)+1,e); // is adding the entity
271                e.addQueueBased(this.clientQ); // sets entity's queue as this queued
272                
273                statisticalInsert(e); // for statistics
274                
275                return true; // inserted
276 
277        }
278 
279        /**
280         * Inserts the given "e" before the position of "which" in the
281         * QueueList. Returns true if "e" is inserted correctly after "which".
282         * If the list is empty or the referenced "which" is not contained, the "e"
283         * will not be inserted and false is returned.
284         * 
285         * @return boolean : Is <code>true</code> if inserted correctly,
286         *         <code>false</code> otherwise
287         * @param e
288         *            Entity : The Entity to be inserted
289         * @param which
290         *            Entity : The referenced Entity that the given "e" has to be
291         *            inserted before
292         */
293        boolean insertBefore(E e, E which) {
294 
295                if (e == null) { // check for null reference
296                        sendWarning("Can not insert entity. Command ignored.",
297                                        "Class 'QueueListStandardFifo' Method: insertBefore(Entity e, "
298                                                        + "Entity which).",
299                                        "The Entity reference 'e' given as parameter is a null "
300                                                        + "reference.",
301                                        "Be sure to only use valid references.");
302                        return false;
303                }
304 
305                if (which == null) { // check for null reference
306                        sendWarning("Can not insert entity. Command ignored.",
307                                        "Class 'QueueListStandardFifo' Method: insertBefore(Entity e, "
308                                                        + "Entity which).",
309                                        "The Entity reference 'which' given as parameter is a null "
310                                                        + "reference.",
311                                        "Be sure to only use valid references.");
312                        return false;
313                }
314 
315                if (contains(e)) { // entity must not be contained twice in queue
316                        sendWarning("Can not insert entity. Command ignored.",
317                                        "Class 'QueueListStandardFifo' Method: insertBefore(Entity e, "
318                                                        + "Entity which).",
319                                        "The Entity 'e' given as parameter is already enqueued.",
320                                        "Make sure the entity is not enqueued here by calling "
321                                                        + "method 'contains(Entity e)'.");
322                        return false;
323                }
324 
325                queuelist.add(queuelist.indexOf(which),e); // add on top as the rest is being shifted
326                e.addQueueBased(this.clientQ); // sets entity's queue as this queued
327                
328                statisticalInsert(e); // for statistics
329                
330                return true; // inserted
331 
332        }
333 
334        /**
335         * Returns <code>true</code>, if no elements are inside the
336         * <code>QueueList</code>,<code>false</code> otherwise
337         * 
338         * @return boolean : true, if no elements are inside the
339         *         <code>QueueList</code>, false otherwise
340         */
341        public boolean isEmpty() {
342 
343                return queuelist.isEmpty();
344 
345        }
346 
347        /**
348         * Returns the last Entity stored in the QueueList. If the QueueList
349         * is empty, <code>null</code> is returned.
350         * 
351         * @return Entity : The last Entity in the list or <code>null</code> if
352         *         QueueList is empty
353         */
354        public E last() {
355        if (queuelist.isEmpty()) {
356            return null;
357        } else { 
358            return queuelist.getLast();
359        }
360    }
361 
362        /**
363         * Returns the predecessor to the given Entity in the QueueList. If
364         * there is no predecessor or no Entity, <code>null</code> is returned.
365         * 
366         * @return Entity : The Entity before the given parameter in the
367         *         QueueList or <code>null</code> if e has no predecessor in
368         *         the QueueList or Entity parameter 'e' itself is not contained
369         * @param e
370         *            Entity : The Entity contained in the QueueList whose
371         *            predecessor will be returned.
372         */
373        E pred(E e)
374        {
375 
376                if (e == null) // check for null reference
377                { 
378                        sendWarning("Can not return predecessor Entity. Command ignored.",
379                                        "Class: QueueListStandardFifo Method: Entity pred (Entity e).",
380                                        "The Entity reference 'e' given as parameter is a null "
381                                                        + "reference.",
382                                        "Check if Entity 'e' is enqueued using method "
383                                                        + "'QueueListStandardFifo.contains(e)'.");
384                        return null;
385                }
386                
387                if (!this.contains(e)) // check for element contained
388                { 
389                        return null;
390                }
391                
392                if (e.equals(queuelist.getFirst())) // check for first element
393                {
394                        return null;
395                }
396 
397                return queuelist.get(queuelist.indexOf(e)-1);
398 
399        }
400 
401        /**
402         * This method will be called every time the Stock (the number of available
403         * units) has changed.
404         * 
405         * @param evt
406         *            java.beans.PropertyChangeEvent : The event specifying the
407         *            property that has changed ans its old and new value.
408         */
409        public void propertyChange(java.beans.PropertyChangeEvent evt) {
410 
411                // check if the property expected has changed
412                if (evt.getPropertyName() == "avail") {
413                        // check if anybody is in the queue
414                        if (!isEmpty()) {
415                                // get the first process in the queue
416                                SimProcess next = (SimProcess) first();
417 
418                                // check if the process is not a null pointer or is not
419                                // modelcompatible
420                                if (!checkProcess(next)) {
421                                        return;
422                                } // just return
423 
424                                // is the process scheduled already?
425                                if (next.isScheduled()) {
426                                        next.skipTraceNote(); // do not tell in the trace, that we
427                                        // ...
428                                        next.cancel(); // get the process from the event-list
429                                }
430 
431                                // remember if the process is blocked
432                                boolean wasBlocked = next.isBlocked();
433 
434                                // invalidate the block for a moment
435                                if (wasBlocked) {
436                                        next.setBlocked(false);
437                                }
438 
439                                next.skipTraceNote(); // do not tell in the trace, that we ...
440                                next.activateAfter(getQueueBased().current()); // schedule this
441                                // process
442                                // right after the current
443 
444                                // set the block back
445                                if (wasBlocked) {
446                                        next.setBlocked(true);
447                                }
448                        } // end if isEmpty()
449                } // end if propertyName == available
450 
451        }
452 
453        /**
454         * Removes the first occurrence of the given Entity from the QueueList. Checks if the given
455         * Entity to be removed does apply to all restrictions on this operation.
456         * These are :
457         * <ul>
458         * <li>The given reference to an entity must not be <code>null</code>
459         * </li>
460         * <li>This QueueList must not be empty, otherwise there's nothing to
461         * remove</li>
462         * If all these restrictions apply, <code>true</code> is returned and the
463         * Entity is removed, otherwise <code>false</code> is the return value
464         * because the given Entity could not be removed since one of the
465         * restrictions above was not met.
466         * 
467         * @return boolean : Is <code>true</code> if the given Entity is contained
468         *         in the QueueList, <code>false</code> otherwise
469         * @param e
470         *            Entity : The Entity to be removed from the QueueList
471         */
472        public boolean remove(E e) {
473 
474                if (e == null) { // check for null reference
475                        sendWarning(
476                                        "Can not remove Entity. Command ignored.",
477                                        "Class: QueueListStandardFifo Method: boolean remove(Entity e).",
478                                        "The Entity reference given as parameter is a null reference.",
479                                        "Be sure to only use valid references.");
480                        return false;
481                }
482 
483                // check if anything can be removed at all
484                if (isEmpty()) {
485                        sendWarning("Can not remove Entity. Command ignored.",
486                                        "Class: QueueListStandardFifo Method: boolean remove(Entity e).",
487                                        "The Queue is empty, no Entities are contained.",
488                                        "Check if an entity is enqueued by calling method "
489                                                        + "contains(Entity e).");
490                        return false;
491                }
492                
493                if (!this.contains(e)) { // check for element
494                        sendWarning("Can not return predecessor Entity. Command ignored.",
495                                        "Class: QueueListStandardFifo Method: Entity remove (Entity e).",
496                                        "The Entity reference 'e' given as parameter is not contained "
497                                                        + "reference.",
498                                        "Insert e first.");
499                        return false;
500                }
501 
502                //remove the first occurring Entity using the java.util.LinkedList
503                queuelist.remove(e);
504                e.removeQueueBased(this.clientQ); // remove entity's queue note
505                
506                statisticalRemove(e); // remove for statistics
507                
508                return true; // job done
509 
510        }
511        
512        /**
513         * Removes the <code>Entity</code> queued at the named position.
514         * The first position is 0, the last one size()-1.
515         * 
516         * @return : The method returns <code>true</code> as the <code>Entity</code>
517         *                          was deleted or <code>false></code> if otherwise.
518         */
519        public boolean remove(int index) 
520        {
521                if (!this.contains(this.get(index))) { // check for element
522                        sendWarning("Can not return predecessor Entity. Command ignored.",
523                                        "Class: QueueListStandardFifo Method: Entity remove (int index).",
524                                        "The Entity reference 'e' given as parameter is not contained "
525                                                        + "reference.",
526                                        "Insert element first.");
527                        return false;
528                }
529                
530                
531                E e = queuelist.remove(index);
532                
533                if (e == null) // if nothing has been removed
534                {
535                        return false;
536                }
537                e.removeQueueBased(this.clientQ); // remove entity's queue note
538                
539                statisticalRemove(e); // remove for statistics
540                
541                return true;
542                
543        }
544 
545        /**
546         * Removes the first entity from this QueueList and returns
547         * <code>true</code> if it was removed successfully. If the QueueList
548         * is empty, <code>false</code> is returned.
549         * 
550         * @return boolean : Is <code>true</code>, if the first element has been
551         *         removed successfully, <code>false</code> if the QueueList
552         *         happened to be empty.
553         */
554        boolean removeFirst() {
555 
556                if (isEmpty()) {
557                        sendWarning(
558                                        "Can not remove first entity in queue. Command ignored.",
559                                        "Class: QueueListStandardFifo Method: boolean removeFirst().",
560                                        "The queue is empty, thus no Entity can be removed.",
561                                        "Check if any Entity 'e' is enqueued using method "
562                                                        + "'QueueListStandardFifo.contains(e)'.");
563                        return false; // nothing from nothing leaves nothing
564                }
565                
566                return remove(first()); // delegate to remove()
567 
568        }
569 
570        /**
571         * Removes the last Entity from the QueueList and returns
572         * <code>true</code> if it was removed successfully. If the QueueList
573         * is empty, <code>false</code> is returned.
574         * 
575         * @return boolean : Is <code>true</code>, if the last element has been
576         *         removed successfully, <code>false</code> if the QueueList
577         *         happened to be empty
578         */
579        boolean removeLast() {
580 
581                if (isEmpty()) {
582                        sendWarning(
583                                        "Can not remove last Entity in queue. Command ignored.",
584                                        "Class: QueueListStandardFifo Method: boolean removeLast().",
585                                        "The queue is empty, thus no Entity can be removed.",
586                                        "Check if any Entity 'e' is enqueued using method "
587                                                        + "'QueueListStandardFifo.contains(e)'.");
588                        return false; // nothing from nothing leaves nothing
589                }
590 
591                return remove(last()); // delegate to remove()
592 
593        }
594 
595        /**
596         * Sends a warning to the error output by forwarding it to the associated
597         * QueueBased's <code>sendwarning</code> method. Warnings are sent only if
598         * the QueueBased's flag for queue implementation warnings is set to
599         * <code>true</code>.
600         * 
601         * @param description
602         *            java.lang.String : describing the error
603         * @param location
604         *            java.lang.String : describing the location the error occurred
605         * @param reason
606         *            java.lang.String : describing the possible cause for this
607         *            error
608         * @param prevention
609         *            java.lang.String : telling what to do to prevent this error
610         * @see QueueBased
611         */
612        void sendWarning(String description, String location, String reason,
613                        String prevention) {
614 
615                if (clientQ.qImpWarn()) {
616                        clientQ.sendWarning(description, location, reason, prevention);
617                }
618 
619        }
620 
621        /**
622         * Returns the successor to the given Entity in the QueueList. If there
623         * is no successor or no Entity in the QueueList, <code>null</code> is
624         * returned.
625         * 
626         * @return Entity : The Entity before the given parameter in the
627         *         QueueList or <code>null</code> if the given Entity
628         *         parameter 'e' has no successor in the QueueList or e itself
629         *         is not contained in the QueueList
630         * @param e
631         *            Entity : The Entity contained in the QueueList
632         */
633        public E succ(E e) 
634        {
635 
636                if (e == null) // check for null reference
637                { 
638                        sendWarning("Can not return successing Entity. Command ignored.",
639                                        "Class: QueueListStandardFifo Method: Entity succ (Entity e).",
640                                        "The Entity reference 'e' given as parameter is a null "
641                                                        + "reference.",
642                                        "Check if Entity 'e' is enqueued using method "
643                                                        + "'QueueListStandardFifo.contains(e)'.");
644                        return null;
645                }
646                
647                if (!this.contains(e)) // check for element contained
648                { 
649                        return null;
650                }
651                
652                if (e.equals(queuelist.getLast())) // check for last element
653                {
654                        return null;
655                }
656 
657                return queuelist.get(queuelist.indexOf(e)+1);
658 
659        }
660 
661        /**
662         * Returns a string representation of the QueueList. The string is built
663         * by concatenating all string representations of the contained entities,
664         * calling their <code>toString()</code> methods.
665         * 
666         * @return java.lang.String : The string representation of the QueueList
667         */
668        public String toString() 
669        {
670                String s = "";
671                
672                for (int i = 0; i<this.size();i++)
673                {
674                        Entity e = this.queuelist.get(i);
675                        s = s + i + ":[" + e + "]<br>";
676                }
677                
678                if(isEmpty())
679                {
680                        s = "-";
681                }
682                
683                return s;
684 
685        }
686        
687}

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