001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: KeyValueList.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.datastructures;
009:
010: import com.uwyn.rife.tools.Sort;
011: import com.uwyn.rife.tools.StringUtils;
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.Iterator;
015:
016: public class KeyValueList implements Collection, Cloneable {
017: ArrayList<KeyValue> mElements = null;
018:
019: public KeyValueList() {
020: mElements = new ArrayList<KeyValue>();
021: }
022:
023: synchronized public void swap(int position1, int position2) {
024: KeyValue element1 = this .get(position1);
025: KeyValue element2 = this .get(position2);
026:
027: this .add(position1 + 1, element2);
028: this .remove(position1);
029: this .add(position2 + 1, element1);
030: this .remove(position2);
031: }
032:
033: synchronized public void sortKeys() {
034: (new SortKeys()).sort(this , this .size() - 1, true);
035: }
036:
037: private class SortKeys extends Sort {
038: public void swap(Object dataToSort, int position1, int position2) {
039: ((KeyValueList) dataToSort).swap(position1, position2);
040: }
041:
042: public Object elementAt(Object dataToSort, int position) {
043: return ((KeyValueList) dataToSort).get(position).getKey();
044: }
045:
046: public int compare(Object element1, Object element2) {
047: return ((String) element1).compareTo((String) element2);
048: }
049: }
050:
051: synchronized public void sortValues() {
052: (new SortValues()).sort(this , this .size() - 1, true);
053: }
054:
055: private class SortValues extends Sort {
056: public void swap(Object dataToSort, int position1, int position2) {
057: ((KeyValueList) dataToSort).swap(position1, position2);
058: }
059:
060: public Object elementAt(Object dataToSort, int position) {
061: return ((KeyValueList) dataToSort).get(position).getValue();
062: }
063:
064: public int compare(Object element1, Object element2) {
065: return ((String) element1).compareTo((String) element2);
066: }
067: }
068:
069: public String getValue(String key) {
070: KeyValue element = get(key);
071:
072: if (null == element) {
073: return null;
074: } else {
075: return element.getValue();
076: }
077: }
078:
079: public synchronized KeyValue getPrevious(int elementIndex) {
080: if (-1 != elementIndex && elementIndex > 0) {
081: return get(elementIndex - 1);
082: } else {
083: return null;
084: }
085: }
086:
087: public KeyValue getPrevious(String key) {
088: return getPrevious(indexOf(key));
089: }
090:
091: public KeyValue getPrevious(KeyValue element) {
092: return getPrevious(indexOf(element));
093: }
094:
095: public KeyValue getNext(int elementIndex) {
096: if (-1 != elementIndex && elementIndex < size() - 1) {
097: return get(elementIndex + 1);
098: } else {
099: return null;
100: }
101: }
102:
103: public KeyValue getNext(String key) {
104: return getNext(indexOf(key));
105: }
106:
107: public KeyValue getNext(KeyValue element) {
108: return getNext(indexOf(element));
109: }
110:
111: public synchronized Collection<KeyValue> getAll(String key) {
112: ArrayList<KeyValue> matched_elements = new ArrayList<KeyValue>();
113: KeyValue[] element_array = new KeyValue[size()];
114: toArray(element_array);
115: int index = 0;
116: do {
117: index = indexOf(index, key);
118: if (-1 != index) {
119: matched_elements.add(element_array[index]);
120: }
121: } while (-1 != index);
122:
123: if (matched_elements.isEmpty()) {
124: return null;
125: } else {
126: return matched_elements;
127: }
128: }
129:
130: public boolean contains(String key) {
131: if (!mElements.isEmpty()) {
132: for (KeyValue element : mElements) {
133: if (element.getKey().equals(key)) {
134: return true;
135: }
136: }
137: }
138:
139: return false;
140: }
141:
142: public boolean contains(Object keyvalue) {
143: if (null != keyvalue && keyvalue instanceof KeyValue) {
144: return mElements.contains(keyvalue);
145: } else {
146: return false;
147: }
148: }
149:
150: public boolean contains(String key, String value) {
151: return mElements.contains(new KeyValue(key, value));
152: }
153:
154: public boolean contains(KeyValue element) {
155: return mElements.contains(element);
156: }
157:
158: public boolean containsAll(Collection collection) {
159: return mElements.containsAll(collection);
160: }
161:
162: public int indexOf(String key, String value) {
163: return mElements.indexOf(new KeyValue(key, value));
164: }
165:
166: public int indexOf(KeyValue element) {
167: return mElements.indexOf(element);
168: }
169:
170: public synchronized int indexOf(int startIndex, KeyValue element) {
171: if (!mElements.isEmpty()) {
172: for (int i = startIndex; i < mElements.size(); i++) {
173: if (mElements.get(i).equals(element)) {
174: return i;
175: }
176: }
177: }
178:
179: return -1;
180: }
181:
182: public synchronized int indexOf(String key) {
183: return indexOf(0, key);
184: }
185:
186: public synchronized int indexOf(int startIndex, String key) {
187: if (!mElements.isEmpty()) {
188: for (int i = startIndex; i < mElements.size(); i++) {
189: if (mElements.get(i).getKey().equals(key)) {
190: return i;
191: }
192: }
193: }
194:
195: return -1;
196: }
197:
198: public synchronized boolean add(Object element) {
199: if (element instanceof KeyValue) {
200: return add((KeyValue) element);
201: } else {
202: return false;
203: }
204: }
205:
206: public synchronized boolean add(String key, String value) {
207: return mElements.add(new KeyValue(key, value));
208: }
209:
210: public synchronized boolean add(KeyValue element) {
211: return mElements.add(element);
212: }
213:
214: public synchronized boolean add(KeyValueList source) {
215: boolean result = true;
216:
217: for (Object element : source) {
218: if (!add(((KeyValue) element).clone())) {
219: result = false;
220: }
221: }
222:
223: return result;
224: }
225:
226: public synchronized void add(int index, String key, String value) {
227: mElements.add(index, new KeyValue(key, value));
228: }
229:
230: public synchronized void add(int index, KeyValue element) {
231: mElements.add(index, element);
232: }
233:
234: public boolean addAll(Collection collection) {
235: boolean result = true;
236:
237: for (Object element : collection) {
238: if (!add(element)) {
239: result = false;
240: }
241: }
242:
243: return result;
244: }
245:
246: public synchronized void addAfter(KeyValue existingElement,
247: String key, String value) {
248: mElements.add(indexOf(existingElement) + 1, new KeyValue(key,
249: value));
250: }
251:
252: public synchronized void addAfter(KeyValue existingElement,
253: KeyValue newElement) {
254: mElements.add(indexOf(existingElement) + 1, newElement);
255: }
256:
257: public synchronized void addBefore(KeyValue existingElement,
258: String key, String value) {
259: mElements.add(indexOf(existingElement),
260: new KeyValue(key, value));
261: }
262:
263: public synchronized void addBefore(KeyValue existingElement,
264: KeyValue newElement) {
265: mElements.add(indexOf(existingElement), newElement);
266: }
267:
268: public synchronized boolean remove(Object element) {
269: if (element instanceof KeyValue) {
270: return remove((KeyValue) element);
271: } else {
272: return false;
273: }
274: }
275:
276: public synchronized boolean remove(String key, String value) {
277: return mElements.remove(new KeyValue(key, value));
278: }
279:
280: public synchronized boolean remove(KeyValue element) {
281: return mElements.remove(element);
282: }
283:
284: public synchronized void remove(int index) {
285: mElements.remove(index);
286: }
287:
288: public boolean removeAll(Collection collection) {
289: return mElements.removeAll(collection);
290: }
291:
292: public boolean retainAll(Collection collection) {
293: return mElements.retainAll(collection);
294: }
295:
296: public synchronized boolean remove(String key) {
297: if (!mElements.isEmpty()) {
298: for (KeyValue element : mElements) {
299: if (element.getKey().equals(key)) {
300: return mElements.remove(element);
301: }
302: }
303: }
304:
305: return false;
306: }
307:
308: public void clear() {
309: mElements.clear();
310: }
311:
312: public synchronized Object[] toArray() {
313: return mElements.toArray();
314: }
315:
316: public synchronized Object[] toArray(Object anArray[]) {
317: mElements.toArray(anArray);
318:
319: return anArray;
320: }
321:
322: public synchronized String[] getKeysArray() {
323: String[] keys = new String[size()];
324:
325: int i = 0;
326: for (Object key : keys()) {
327: keys[i] = (String) key;
328: i++;
329: }
330:
331: return keys;
332: }
333:
334: public synchronized void trimToSize() {
335: mElements.trimToSize();
336: }
337:
338: public synchronized void ensureCapacity(int minCapacity) {
339: mElements.ensureCapacity(minCapacity);
340: }
341:
342: public int size() {
343: return mElements.size();
344: }
345:
346: public synchronized void setSize(int newSize) {
347: if (size() > newSize) {
348: ArrayList<KeyValue> new_elements = new ArrayList<KeyValue>(
349: newSize);
350: for (int i = 0; i < newSize; i++) {
351: new_elements.set(i, mElements.get(i));
352: }
353: mElements = new_elements;
354: }
355: }
356:
357: public boolean isEmpty() {
358: return mElements.isEmpty();
359: }
360:
361: public synchronized Iterator<KeyValue> iterator() {
362: return mElements.iterator();
363: }
364:
365: public synchronized Collection<String> keys() {
366: ArrayList<String> keys = new ArrayList<String>();
367:
368: for (KeyValue element : mElements) {
369: keys.add(element.getKey());
370: }
371:
372: return keys;
373: }
374:
375: public synchronized Collection<String> values() {
376: ArrayList<String> values = new ArrayList<String>();
377:
378: for (KeyValue element : mElements) {
379: values.add(element.getValue());
380: }
381:
382: return values;
383: }
384:
385: public synchronized KeyValue get(int index) {
386: return mElements.get(index);
387: }
388:
389: public synchronized KeyValue get(String key) {
390: int index = indexOf(key);
391:
392: if (-1 == index) {
393: return null;
394: } else {
395: return get(index);
396: }
397: }
398:
399: public synchronized KeyValue first() {
400: return mElements.get(0);
401: }
402:
403: public synchronized KeyValue last() {
404: return mElements.get(size() - 1);
405: }
406:
407: public synchronized void set(int index, String key, String value) {
408: mElements.set(index, new KeyValue(key, value));
409: }
410:
411: public synchronized void set(int index, KeyValue element) {
412: mElements.set(index, element);
413: }
414:
415: public synchronized KeyValueList clone() {
416: KeyValueList new_object = null;
417: try {
418: new_object = (KeyValueList) super .clone();
419:
420: if (null != new_object.mElements) {
421: new_object.mElements = (ArrayList<KeyValue>) mElements
422: .clone();
423:
424: for (int i = 0; i < mElements.size(); i++) {
425: new_object.mElements.set(i, mElements.get(i)
426: .clone());
427: }
428: }
429: } catch (CloneNotSupportedException e) {
430: new_object = null;
431: }
432:
433: return new_object;
434: }
435:
436: public String toHtml() {
437: StringBuilder html = new StringBuilder();
438:
439: if (!mElements.isEmpty()) {
440: for (KeyValue element : mElements) {
441: html.append("<B>").append(
442: StringUtils.encodeHtml(element.getKey()))
443: .append("</B> = "").append(
444: StringUtils.encodeHtml(element
445: .getValue())).append(
446: ""<BR>\n");
447: }
448: }
449:
450: return html.toString();
451: }
452:
453: public String toString() {
454: StringBuilder output = new StringBuilder();
455:
456: if (!mElements.isEmpty()) {
457: for (KeyValue element : mElements) {
458: output.append(element.getValue()).append(" ");
459: }
460: }
461:
462: return output.toString();
463: }
464:
465: public String toStringVerbose() {
466: StringBuilder html = new StringBuilder();
467:
468: if (!mElements.isEmpty()) {
469: for (KeyValue element : mElements) {
470: html.append(element.getKey()).append(" = \"").append(
471: element.getValue()).append("\"\n");
472: }
473: }
474:
475: return html.toString();
476: }
477: }
|