001: /* OperationQueue.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Sep 29, 2007 9:20:26 AM 2007, Created by Dennis.Chen
010: }}IS_NOTE
011:
012: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zkex.zul.impl;
020:
021: import java.util.Collections;
022: import java.util.LinkedList;
023: import java.util.List;
024: import java.util.NoSuchElementException;
025:
026: import org.zkoss.zk.ui.Desktop;
027:
028: /**
029: * A queue for storing {@link Operation} and is thread-safe.
030: * This class is for model sharer developer only, you rarely need to use this class.<br/>
031: *
032: * @author Dennis.Chen
033: * @since 3.0.0
034: */
035: public class OperationQueue {
036:
037: private LinkedList _inner = new LinkedList();
038: private List _listeners = Collections
039: .synchronizedList(new LinkedList());
040:
041: /**
042: * Add a listener to this queue
043: */
044: public void addListener(OperationQueueListener listener) {
045: synchronized (_listeners) {
046: _listeners.add(listener);
047: }
048: }
049:
050: /**
051: * Remove a listener to this queue.
052: */
053: public void removeListener(OperationQueueListener listener) {
054: synchronized (_listeners) {
055: _listeners.remove(listener);
056: }
057: }
058:
059: void fireQueueUnavailable(Desktop desktop) {
060: synchronized (_listeners) {
061: //do not use iterator, some listener will remove it registration when queue is not available
062: OperationQueueListener[] ls = (OperationQueueListener[]) _listeners
063: .toArray(new OperationQueueListener[0]);
064: for (int i = 0; i < ls.length; i++) {
065: ls[i].queueUnavailable(desktop);
066: }
067: }
068: }
069:
070: void clearListener() {
071: synchronized (_listeners) {
072: _listeners.clear();
073: }
074: }
075:
076: /**
077: * Put an operation to queue
078: * @param op the operation.
079: */
080: public void put(Operation op) {
081: synchronized (_inner) {
082: _inner.add(op);
083: }
084: synchronized (this ) {
085: this .notifyAll();
086: }
087: }
088:
089: /**
090: * Get an operation from queue, doesn't remove it.
091: * @return the first operation in queue, null if not such operation.
092: */
093: public Operation element() {
094: try {
095: synchronized (_inner) {
096: if (_inner.size() > 0) {
097: Operation op = (Operation) _inner.getFirst();
098: return op;
099: }
100: return null;
101: }
102: } catch (NoSuchElementException e) {
103: return null;
104: }
105: }
106:
107: /**
108: * Check is there any operation in queue.
109: * @return true if there exist any operation in queue.
110: */
111: public boolean hasElement() {
112: return _inner.size() > 0;
113: }
114:
115: /**
116: * Get an operation from queue, and then remove it.
117: * @return the first operation in queue, null if not such operation.
118: */
119: public Operation next() {
120: try {
121: synchronized (_inner) {
122: if (_inner.size() > 0) {
123: Operation op = (Operation) _inner.getFirst();
124: _inner.removeFirst();
125: return op;
126: }
127: return null;
128: }
129: } catch (NoSuchElementException e) {
130: return null;
131: }
132: }
133:
134: /**
135: * Remove the first operation in queue if exist.
136: */
137: public void remove() {
138: next();
139: }
140:
141: }
|