001: /*
002: * (C) Copyright 2003 Nabh Information Systems, Inc.
003: *
004: * All copyright notices regarding Nabh's products MUST remain
005: * intact in the scripts and in the outputted HTML.
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package com.nabhinc.util;
023:
024: /**
025: * A helper class that implements a queue.
026: *
027: * @author Padmanabh Dabke
028: * (c) 2003 Nabh Information Systems, Inc. All Rights Reserved.
029: */
030: public class Queue implements java.io.Serializable {
031:
032: /**
033: * Comment for <code>serialVersionUID</code>
034: */
035: private static final long serialVersionUID = 3834595391759923253L;
036:
037: /**
038: * First element in the queue
039: */
040: protected QElement qFirst = null;
041:
042: /**
043: * Last element in the queue
044: */
045: protected QElement qLast = null;
046:
047: /**
048: * Flag indicating whether this queue is open
049: * or has been closed.
050: */
051: protected boolean qClosed = false;
052:
053: /**
054: * Number of elements in the queue
055: */
056: protected int qLength = 0;
057:
058: /**
059: * Create an empty queue
060: */
061: public Queue() {
062: }
063:
064: /**
065: * Create a queue with one element.
066: * @param o The first element in the queue
067: */
068: public Queue(java.io.Serializable o) {
069: qFirst = new QElement(0, o);
070: qLast = qFirst;
071: }
072:
073: /**
074: * Add a new element to the queue
075: * @param o Element to be added
076: */
077: public synchronized void addObject(java.io.Serializable o) {
078: qLength++;
079: if (qFirst == null) {
080: qFirst = new QElement(0, o);
081: qLast = qFirst;
082: } else {
083: qLast = qLast.addObject(0, o);
084: }
085: notifyAll();
086: }
087:
088: /**
089: * Adds a new element to the queue
090: * @param o Element to be added
091: */
092: public synchronized void addObject(java.io.Serializable o, int index) {
093: qLength++;
094:
095: if (qFirst == null) {
096: qFirst = new QElement(index, o);
097: qLast = qFirst;
098: } else {
099: qLast = qLast.addObject(index, o);
100: }
101: notifyAll();
102: }
103:
104: /**
105: * Closes the queue and notifies all listeners.
106: */
107: public synchronized void close() {
108: //System.out.println("Closing queue.");
109: qClosed = true;
110: notifyAll();
111:
112: }
113:
114: /**
115: * Empties the queue and returns all queue elements.
116: * @return All objects in the queue
117: */
118: public synchronized java.io.Serializable[] emptyQueue() {
119: java.io.Serializable[] ret = getObjects();
120: qFirst = null;
121: qLast = null;
122: qLength = 0;
123: return ret;
124: }
125:
126: /**
127: * Get the number of elements in the queue.
128: * @return Queue length
129: */
130: public int getLength() {
131: return qLength;
132: }
133:
134: /**
135: * Returns all objects in the queue without emptying it.
136: * @return All objects in the queue
137: */
138: public synchronized java.io.Serializable[] getObjects() {
139: int i = 0;
140: QElement q = qFirst;
141: while (q != null) {
142: i++;
143: q = q.next;
144: }
145:
146: java.io.Serializable[] elems = new java.io.Serializable[i];
147:
148: i = 0;
149: q = qFirst;
150: while (q != null) {
151: elems[i] = q.data;
152: i++;
153: q = q.next;
154: }
155:
156: return elems;
157: }
158:
159: /**
160: * Test if the queue has any elements.
161: * @return true if the queue is not empty.
162: */
163: public boolean hasData() {
164: return (qFirst != null);
165: }
166:
167: /**
168: * Test if the queue is empty
169: * @return true if the queue is empty
170: */
171: public boolean isEmpty() {
172: return (qFirst == null);
173: }
174:
175: /**
176: * Do nothing method
177: * @param o Element to be added
178: */
179: public int persistObject(java.io.Serializable o) throws Exception {
180: return 0;
181: }
182:
183: /**
184: * Removes an element from the queue. If the queue is empty, blocks
185: * until addObject notifies it.
186: * @return Removed element
187: */
188: public synchronized java.io.Serializable removeObject()
189: throws InterruptedException {
190:
191: while (qFirst == null && (!qClosed))
192: wait();
193:
194: if (qFirst == null)
195: return null;
196:
197: QElement q = qFirst;
198: if (qFirst.equals(qLast)) {
199: qFirst = null;
200: qLast = null;
201: } else {
202: qFirst = qFirst.next;
203: }
204:
205: qLength--;
206: return q.data;
207: }
208:
209: /**
210: * Removes an element from the queue. If the queue is empty, blocks
211: * until addObject notifies it.
212: * @return Removed element
213: */
214: public java.io.Serializable removeObjectWithoutBlocking()
215: throws InterruptedException {
216:
217: if (qFirst == null)
218: return null;
219:
220: QElement q = qFirst;
221: if (qFirst.equals(qLast)) {
222: qFirst = null;
223: qLast = null;
224: } else {
225: qFirst = qFirst.next;
226: }
227:
228: qLength--;
229: return q.data;
230: }
231:
232: /**
233: * Waits till the queue has at least one value or the
234: * queue is closed.
235: * @return true if the queue is non-empty, false if it
236: * has been closed.
237: */
238: public synchronized boolean waitForValue()
239: throws InterruptedException {
240:
241: while (qFirst == null && (!qClosed))
242: wait();
243:
244: if (qFirst == null)
245: return false;
246: else
247: return true;
248:
249: }
250: }
|