001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * KeyedQueue.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.util;
030:
031: import java.io.Serializable;
032: import java.util.HashMap;
033: import java.util.LinkedList;
034:
035: /**
036: * A keyed queue is a hashtable like structure which will store a certain number of
037: * elements. If the defined element size is exceeded, the firstly stored element gets
038: * removed.
039: *
040: * @author Thomas Morgner
041: */
042: public class KeyedQueue implements Serializable, Cloneable {
043: /**
044: * Ordered storage for the queued items.
045: */
046: private LinkedList list;
047:
048: /**
049: * Keyed storage for the queued items.
050: */
051: private HashMap table;
052:
053: /**
054: * The maximum number of items in the queue.
055: */
056: private int limit;
057:
058: /**
059: * Creates a KeyedQueue with an initial limit of 10 items.
060: */
061: public KeyedQueue() {
062: this (10);
063: }
064:
065: /**
066: * Creates a KeyedQueue with an initial limit if <code>limit</code> items.
067: *
068: * @param limit the maximum number of items.
069: */
070: public KeyedQueue(final int limit) {
071: table = new HashMap();
072: list = new LinkedList();
073: setLimit(limit);
074: }
075:
076: /**
077: * Defines the maximal number of elements in the queue.
078: *
079: * @param limit the maximum number of items.
080: */
081: public void setLimit(final int limit) {
082: if (limit < 0) {
083: throw new IllegalArgumentException(
084: "Limit must be at least 0.");
085: }
086: this .limit = limit;
087: }
088:
089: /**
090: * Returns the maximum number of elements in the queue.
091: *
092: * @return the maximum number of elements in the queue.
093: */
094: public int getLimit() {
095: return limit;
096: }
097:
098: /**
099: * Adds a new key/value pair to the queue. If the pair is already contained in the list,
100: * it is moved to the first position so that is gets removed last.
101: *
102: * @param key the key.
103: * @param ob the value.
104: */
105: public void put(final Object key, final Object ob) {
106: if (key == null) {
107: throw new NullPointerException("Key must not be null");
108: }
109: if (ob == null) {
110: throw new NullPointerException("Value must not be null");
111: }
112:
113: final Object oldval = table.put(key, ob);
114: if (oldval != null) {
115: list.remove(oldval);
116: }
117: list.add(ob);
118:
119: if (getLimit() != 0 && list.size() > getLimit()) {
120: removeLast();
121: }
122: }
123:
124: /**
125: * Queries the queue for the value stored under the given key.
126: *
127: * @param key the key.
128: * @return the value.
129: */
130: public Object get(final Object key) {
131: if (key == null) {
132: throw new NullPointerException("Key must not be null");
133: }
134:
135: return table.get(key);
136: }
137:
138: /**
139: * Removes the entry stored under the given key.
140: *
141: * @param key the key.
142: */
143: public void remove(final Object key) {
144: if (key == null) {
145: throw new NullPointerException();
146: }
147: table.remove(key);
148: list.remove(key);
149: }
150:
151: /**
152: * Removes the last element in the queue.
153: */
154: public void removeLast() {
155: final Object o = list.getLast();
156: table.remove(o);
157: list.remove(o);
158: }
159:
160: /**
161: * Removes all elements in the queue.
162: */
163: public void clear() {
164: table.clear();
165: list.clear();
166: }
167:
168: /**
169: * Clones the queue.
170: *
171: * @return a clone.
172: *
173: * @throws CloneNotSupportedException this should never happen.
174: */
175: public Object clone() throws CloneNotSupportedException {
176: final KeyedQueue q = (KeyedQueue) super .clone();
177: q.list = (LinkedList) list.clone();
178: q.table = (HashMap) table.clone();
179: return q;
180: }
181:
182: }
|