001: /*
002: * JavuX - Java Component Set
003: * Copyright (c) 2005-2007 Krzysztof A. Sadlocha
004: * e-mail: ksadlocha@programics.com
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library 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 GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package com.javujavu.javux.util;
022:
023: import java.util.Vector;
024:
025: /**
026: * This class implements a sorted table, which maps <code>String</code> keys to <code>Object</code> values. It allows <code>null</code> as a value.
027: * <br>
028: * <b>This class is thread safe.</b>
029: **/
030: public class SortMap {
031: protected final boolean ignoreCase;
032: protected final Vector keys;
033: protected final Vector values;
034:
035: public SortMap() {
036: this .ignoreCase = false;
037: keys = new Vector();
038: values = new Vector();
039: }
040:
041: public SortMap(boolean ignoreCase) {
042: this .ignoreCase = ignoreCase;
043: keys = new Vector();
044: values = new Vector();
045: }
046:
047: private SortMap(SortMap o) {
048: synchronized (o) {
049: ignoreCase = o.ignoreCase;
050: keys = (Vector) o.keys.clone();
051: values = (Vector) o.values.clone();
052: }
053: }
054:
055: public Object clone() {
056: return new SortMap(this );
057: }
058:
059: public synchronized void set(String key, Object value) {
060: int s = 0, e = keys.size(), h = 0, c;
061: String comp;
062: while (s < e) {
063: h = (s + e) / 2;
064: comp = (String) keys.elementAt(h);
065: if (ignoreCase)
066: c = compareIgnoreCase(comp, key);
067: else
068: c = comp.compareTo(key);
069: if (c == 0) {
070: values.setElementAt(value, h);
071: return;
072: }
073: if (c < 0)
074: s = h + 1;
075: else
076: e = h;
077: }
078: keys.insertElementAt(key, s);
079: values.insertElementAt(value, s);
080: }
081:
082: public synchronized int find(String key) {
083: int s = 0, e = keys.size(), h, c;
084: String comp;
085: while (s < e) {
086: h = (s + e) / 2;
087: comp = (String) keys.elementAt(h);
088: if (ignoreCase)
089: c = compareIgnoreCase(comp, key);
090: else
091: c = comp.compareTo(key);
092: if (c == 0) {
093: return h;
094: }
095: if (c < 0)
096: s = h + 1;
097: else
098: e = h;
099: }
100: return -1;
101: }
102:
103: public static int compareIgnoreCase(String s1, String s2) {
104: int n1 = s1.length(), n2 = s2.length();
105: char c1, c2;
106: for (int i = 0; i < n1 && i < n2; i++) {
107: c1 = s1.charAt(i);
108: c2 = s2.charAt(i);
109: if (c1 != c2) {
110: c1 = Character.toUpperCase(c1);
111: c2 = Character.toUpperCase(c2);
112: if (c1 != c2) {
113: c1 = Character.toLowerCase(c1);
114: c2 = Character.toLowerCase(c2);
115: if (c1 != c2) {
116: return c1 - c2;
117: }
118: }
119: }
120: }
121: return n1 - n2;
122: }
123:
124: public synchronized Object get(String key) {
125: int i = find(key);
126: return (i != -1) ? values.elementAt(i) : null;
127: }
128:
129: public synchronized Object remove(int i) {
130: Object ret = values.elementAt(i);
131: values.removeElementAt(i);
132: keys.removeElementAt(i);
133: return ret;
134: };
135:
136: public synchronized Object remove(String key) {
137: int i = find(key);
138: if (i == -1)
139: return null;
140: return remove(i);
141: }
142:
143: public int size() {
144: return keys.size();
145: };
146:
147: public String key(int i) {
148: return (String) keys.elementAt(i);
149: };
150:
151: public Object value(int i) {
152: return values.elementAt(i);
153: };
154:
155: public Vector getValues() {
156: return values;
157: }
158:
159: public Vector getKeys() {
160: return keys;
161: }
162:
163: public void set(int i, Object value) {
164: values.setElementAt(value, i);
165: }
166:
167: public synchronized void removeAllElements() {
168: keys.removeAllElements();
169: values.removeAllElements();
170: }
171:
172: }
|