001: /*
002: * $Header: /cvsroot/webman-cms/source/webman/com/teamkonzept/lib/TKHashtable.java,v 1.5 2000/05/22 15:01:19 careck Exp $
003: *
004: */
005: package com.teamkonzept.lib;
006:
007: import java.util.*;
008:
009: /**
010: Erweitert Hashtable um Methode zur Bearbeitung verschachtelter Hashtables
011: */
012:
013: public class TKHashtable extends Hashtable {
014:
015: /**
016: Erzeugt leere Hashtable.
017: */
018: public TKHashtable() {
019: }
020:
021: /**
022: Erzeugt leere Hashtable.
023: */
024: public TKHashtable(int initialCapacity) {
025: super (initialCapacity);
026: }
027:
028: /**
029: Erzeugt vorgefüllte Hashtable.
030: @param ein key-value Paar
031: */
032: public TKHashtable(Object key, Object val) {
033: put(key, val);
034: }
035:
036: /**
037: Erzeugt vorgefüllte Hashtable.
038: @param init Array von key,value-Paaren
039: */
040: public TKHashtable(Object init[][]) {
041: super (init.length);
042: for (int n = 0; n < init.length; n++) {
043: put(init[n][0], init[n][1]);
044: }
045: }
046:
047: /**
048: Überprüft, ob es in einem verschachtelten Hash einen bestimmten Eintrag gibt.
049: @param keyList Liste von Hashkeys, über die die Verschachtelung durchlaufen wird.
050: */
051: public boolean containsKey(Object keyList[]) {
052: return get(keyList) != null;
053: }
054:
055: /**
056: Liefert einen Eintrag aus einem verschachtelten Hash.
057: @param keyList Liste von Hashkeys, über die die Verschachtelung durchlaufen wird.
058: @return Wert, bzw. null falls kein entsprechender Eintrag existiert.
059: */
060: public Object get(Object keyList[]) {
061: Object curr = this ;
062: for (int i = 0; i < keyList.length; i++) {
063: if (curr instanceof Hashtable
064: && ((Hashtable) curr).containsKey(keyList[i])) {
065: curr = ((Hashtable) curr).get(keyList[i]);
066: } else {
067: return null;
068: }
069: }
070: return curr;
071: }
072:
073: /**
074: Setzt einen Eintrag in einem verschachtelten Hash.
075: @param keyList Liste von Hashkeys, über die die Verschachtelung durchlaufen wird.
076: @param val zu setzender Wert
077: @return der durch put überschriebene Wert, bzw. null falls Eintrag noch nicht existiert hat.
078: */
079: public Object put(Object keyList[], Object val) {
080: Object curr = this ;
081: int toScan = keyList.length - 1;
082: for (int i = 0; i < toScan; i++) {
083: Object key = keyList[i];
084: Object next = ((Hashtable) curr).get(key);
085: if ((next == null) || !(next instanceof Hashtable)) {
086: next = new TKHashtable();
087: ((Hashtable) curr).put(key, next);
088: }
089: curr = next;
090: }
091: return ((Hashtable) curr).put(keyList[toScan], val);
092: }
093:
094: /**
095: Erweitert den Hash um ein (key,value)-Paar. Das Erweitern geschieht
096: nach folgenden Regeln:
097: <UL>
098: <LI> Kommt der key noch nicht im Hash vor, wird das neue (Key,Value)-Paar eingetragen
099: <LI> Bei in beiden Objekten vorkommenden Keys werden deren Values miteinander verbunden.
100: Dabei gelten folgende Regeln:
101: <UL>
102: <LI>Ist einer der beiden Werte ein TKNull-Objekt so wird er ignoriert.
103: <LI>Sind beide Values Hashtables werden sie durch concat verbunden
104: <LI>Andernfalls wird eine Liste mit den beiden Values erzeugt. Bereits bestehende
105: Listenvalues werden aufgelöst und nur deren Elemente in die neue Liste
106: übernommen.
107: </UL>
108: </UL>
109: */
110: public void extend(Object key, Object val) {
111: Object oldVal = get(key);
112:
113: if (oldVal == null || oldVal instanceof TKNull) {
114: put(key, val);
115: } else if (!(val instanceof TKNull)) {
116: if ((val instanceof Hashtable)
117: && (oldVal instanceof TKHashtable)) {
118: ((TKHashtable) oldVal).concat((Hashtable) val);
119: } else if (oldVal instanceof TKVector) {
120: ((TKVector) oldVal).concat(val);
121: } else if (val instanceof TKVector) {
122: TKVector newVal = (TKVector) ((TKVector) val).clone();
123: newVal.insertElementAt(oldVal, 0);
124: put(key, newVal);
125: } else {
126: Object[] newValDef = { oldVal, val };
127: if (oldVal != val
128: && (oldVal.getClass() != val.getClass() || !oldVal
129: .equals(val))) {
130: put(key, new TKVector(newValDef));
131: }
132: }
133: }
134: }
135:
136: /**
137: Fügt alle Elemente einer anderen Hashtable per extend-Aufrufe dem Objekt hinzu.
138: @param hash hinzuzufügende Hashtable.
139: */
140: public void concat(Hashtable hash) {
141:
142: Enumeration keys = hash.keys();
143:
144: while (keys.hasMoreElements()) {
145: Object key = keys.nextElement();
146: extend(key, hash.get(key));
147: }
148: }
149:
150: /**
151: Fügt alle Elemente einer anderen Hashtable hinzu, falls der entsprechende
152: key noch nicht in der Hashtable enthalten ist.
153: @param hash hinzuzufügende Hashtable.
154: */
155: public void merge(Hashtable hash) {
156:
157: Enumeration keys = hash.keys();
158:
159: while (keys.hasMoreElements()) {
160: Object key = keys.nextElement();
161: if (!containsKey(key)) {
162: put(key, hash.get(key));
163: }
164: }
165: }
166:
167: /**
168: Erzeugt einen String, der den Hash in perl-Notation enthält
169: */
170:
171: public String toPerlString() {
172: return toPerlString(0, true);
173: }
174:
175: /**
176: Erzeugt einen String, der den Hash in perl-Notation enthält
177: */
178:
179: public String toPerlString(int indentCount, boolean withNewline) {
180: String result = "";
181: String indent = "";
182: if (withNewline) {
183: for (int i = 0; i <= indentCount; i++)
184: indent += " ";
185: }
186:
187: Enumeration keys = keys();
188:
189: while (keys.hasMoreElements()) {
190: Object val, key;
191:
192: key = keys.nextElement();
193: val = get(key);
194: result += indent
195: + "'"
196: + key.toString()
197: + "'=>"
198: + (val instanceof TKHashtable ? ((TKHashtable) val)
199: .toPerlString(indentCount + 1, withNewline)
200: : (val instanceof TKVector ? ((TKVector) val)
201: .toPerlString(indentCount + 1,
202: withNewline)
203: : "'" + val.toString() + "'"))
204: + (keys.hasMoreElements() ? "," : "")
205: + (withNewline ? "\n" : "");
206: }
207: return "{" + (withNewline ? "\n" : "") + result + indent + "}";
208:
209: }
210:
211: /**
212: Erzeugt eine neue Hashtable, die die Verknüpfung von zwei Hashtables enthält. Die
213: übergebenen Hashtables bleiben unverändert.
214: @param h1 Quell-Hash.
215: @param h2 hinzuzufügender Hash
216: @return neuer Hash der h1.concat(h2) enthät
217: */
218: public static TKHashtable concat(TKHashtable h1, TKHashtable h2) {
219: if (h1 == null) {
220: if (h2 == null) {
221: return null;
222: }
223: return (TKHashtable) h2.clone();
224: }
225: TKHashtable res = (TKHashtable) h1.clone();
226: res.concat(h2);
227: return res;
228: }
229:
230: /**
231: Erzeugt eine neue Hashtable, die die Verknüpfung von zwei Hashtables enthält. Die
232: übergebenen Hashtables bleiben unverändert.
233: @param h1 Quell-Hash.
234: @param h2 hinzuzufügender Hash
235: @return neuer Hash der h1.concat(h2) enthät
236: */
237: public static TKHashtable merge(TKHashtable h1, TKHashtable h2) {
238: if (h1 == null) {
239: if (h2 == null) {
240: return null;
241: }
242: return (TKHashtable) h2.clone();
243: }
244: TKHashtable res = (TKHashtable) h1.clone();
245: res.merge(h2);
246: return res;
247: }
248: }
|