001: /*
002: * Copyright 2004 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: MapWidget.java,v 1.2 2004/03/22 04:58:13 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.test;
012:
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.Map;
016: import java.util.Map.Entry;
017: import javax.jdo.InstanceCallbacks;
018: import javax.jdo.JDOHelper;
019: import javax.jdo.PersistenceManager;
020: import junit.framework.Assert;
021:
022: public class MapWidget extends Widget implements InstanceCallbacks {
023: private Map normalMap = new HashMap();
024: private Map normalObjectMap = new HashMap();
025: private Map inverseMap = new HashMap();
026: private int numWidgets = 0;
027: private int numValueWidgets = 0;
028:
029: public MapWidget() {
030: }
031:
032: public Map getNormalMap() {
033: return normalMap;
034: }
035:
036: public Map getNormalObjectMap() {
037: return normalObjectMap;
038: }
039:
040: public Map getInverseMap() {
041: return inverseMap;
042: }
043:
044: public int getNumWidgets() {
045: return numWidgets;
046: }
047:
048: public int getNumValueWidgets() {
049: return numValueWidgets;
050: }
051:
052: public Object[] getSCOFieldValues() {
053: return new Object[] { normalMap, normalObjectMap, inverseMap };
054: }
055:
056: public Object clone() {
057: MapWidget mw = (MapWidget) super .clone();
058:
059: /* Do a deep clone of all the maps. */
060: mw.normalMap = new HashMap();
061: mw.normalObjectMap = new HashMap();
062: mw.inverseMap = new HashMap();
063:
064: Iterator i = normalMap.entrySet().iterator();
065:
066: while (i.hasNext()) {
067: Entry e = (Entry) i.next();
068: String ks = (String) e.getKey();
069: Widget v = (Widget) clone(e.getValue());
070:
071: Integer ki = new Integer(v.getIntField());
072:
073: mw.normalMap.put(ks, v);
074: mw.normalObjectMap.put(ki, v);
075:
076: if (v instanceof ValueWidget) {
077: ValueWidget vw = (ValueWidget) v;
078:
079: vw.setOwner(mw);
080: mw.inverseMap.put(ki, vw);
081: }
082: }
083:
084: return mw;
085: }
086:
087: /**
088: * Fills all of the object's fields with random data values.
089: */
090:
091: public void fillRandom() {
092: fillRandom(r.nextInt(5));
093: }
094:
095: public void fillRandom(int numWidgets) {
096: fillRandom(numWidgets, false);
097: }
098:
099: /**
100: * Fills the collection fields with the given number of random Widget
101: * objects.
102: */
103:
104: public void fillRandom(int numWidgets, boolean includeMapWidgets) {
105: super .fillRandom();
106:
107: /*
108: * Clear normalMap iteratively in order to test remove().
109: */
110: Iterator i = normalMap.entrySet().iterator();
111:
112: while (i.hasNext()) {
113: Entry e = (Entry) i.next();
114: Object skey = e.getKey();
115: Widget val = (Widget) e.getValue();
116:
117: i.remove();
118:
119: Integer ikey = new Integer(val.getIntField());
120:
121: Assert
122: .assertFalse(
123: "normalMap.containsKey() did not return false after removing existing key",
124: normalMap.containsKey(skey));
125: Assert
126: .assertTrue(
127: "normalObjectMap.remove() did not return non-null after removing existing key",
128: normalObjectMap.remove(ikey) != null);
129: Assert
130: .assertTrue(
131: "normalObjectMap.remove() did not return null attempting to remove non-existent key",
132: normalObjectMap.remove(ikey) == null);
133:
134: if (JDOHelper.isPersistent(this )) {
135: JDOHelper.getPersistenceManager(this ).deletePersistent(
136: val);
137:
138: Assert.assertFalse(
139: "inverseMap should not contain deleted value",
140: inverseMap.containsValue(val));
141: } else if (val instanceof ValueWidget)
142: Assert
143: .assertTrue(
144: "inverseMap.remove() did not return non-null after removing existing key",
145: inverseMap.remove(ikey) != null);
146: }
147:
148: Assert.assertTrue("normalMap should have been empty", normalMap
149: .isEmpty());
150: Assert.assertTrue("normalObjectMap should have been empty",
151: normalObjectMap.isEmpty());
152: Assert.assertTrue("inverseMap should have been empty",
153: inverseMap.isEmpty());
154:
155: /*
156: * Fill up normalMap and normalObjectMap with random Widget objects of
157: * random types. Any ValueWidget objects are added to inverseMap as
158: * well.
159: */
160: this .numWidgets = numWidgets;
161: numValueWidgets = 0;
162:
163: while (numWidgets-- > 0) {
164: Widget val;
165:
166: switch (r.nextInt(includeMapWidgets ? 7 : 6)) {
167: case 0:
168: default:
169: val = new Widget();
170: break;
171: case 1:
172: val = new DateWidget();
173: break;
174: case 2:
175: val = new StringWidget();
176: break;
177: case 3:
178: val = new BinaryWidget();
179: break;
180: case 4:
181: val = new ValueWidget();
182: break;
183: case 5:
184: val = new FloatWidget();
185: break;
186: case 6:
187: val = new MapWidget();
188: break;
189: }
190:
191: Integer key;
192:
193: do {
194: val.fillRandom();
195: key = new Integer(val.getIntField());
196: } while (normalObjectMap.containsKey(key));
197:
198: normalMap.put("K" + key, val);
199: normalObjectMap.put(key, val);
200:
201: if (val instanceof ValueWidget) {
202: inverseMap.put(key, val);
203:
204: if (!JDOHelper.isPersistent(this ))
205: ((ValueWidget) val).setKey(key);
206:
207: ++numValueWidgets;
208: }
209: }
210:
211: validate();
212: }
213:
214: private void validate() {
215: Assert.assertEquals("numWidgets != normalMap.size(): " + this ,
216: numWidgets, normalMap.size());
217: Assert.assertEquals("numWidgets != normalObjectMap.size(): "
218: + this , numWidgets, normalObjectMap.size());
219: Assert.assertEquals("numValueWidgets != inverseMap.size(): "
220: + this , numValueWidgets, inverseMap.size());
221: Assert.assertTrue(
222: "normalMap does not contain all values of inverseMap: "
223: + this , normalMap.values().containsAll(
224: inverseMap.values()));
225: Assert.assertTrue(
226: "normalObjectMap does not contain all values of inverseMap: "
227: + this , normalObjectMap.values().containsAll(
228: inverseMap.values()));
229: }
230:
231: /**
232: * Indicates whether some other object is "equal to" this one. By comparing
233: * against an original copy of the object, <code>compareTo()</code> can be
234: * used to verify that the object has been written to a database and read
235: * back correctly.
236: *
237: * @param obj the reference object with which to compare
238: *
239: * @return <code>true</code> if this object is equal to the obj argument;
240: * <code>false</code> otherwise.
241: */
242:
243: public boolean compareTo(Object obj) {
244: validate();
245:
246: if (obj == this )
247: return true;
248:
249: if (!(obj instanceof MapWidget) || !super .compareTo(obj))
250: return false;
251:
252: MapWidget w = (MapWidget) obj;
253:
254: w.validate();
255:
256: return compareMap(normalMap, w.normalMap)
257: && compareMap(normalObjectMap, w.normalObjectMap)
258: && compareMap(inverseMap, w.inverseMap);
259: }
260:
261: /**
262: * Returns a string representation for this object. All of the field
263: * values are included in the string for debugging purposes.
264: *
265: * @return a string representation for this object.
266: */
267:
268: public String toString() {
269: StringBuffer s = new StringBuffer(super .toString());
270:
271: s.append(" normalMap = ").append(normalMap);
272: s.append('\n');
273: s.append(" normalObjectMap = ").append(normalObjectMap);
274: s.append('\n');
275: s.append(" inverseMap = ").append(inverseMap);
276: s.append('\n');
277: s.append(" numWidgets = ").append(numWidgets);
278: s.append('\n');
279: s.append(" numValueWidgets = ").append(numValueWidgets);
280: s.append('\n');
281:
282: return s.toString();
283: }
284:
285: public void jdoPostLoad() {
286: }
287:
288: public void jdoPreClear() {
289: }
290:
291: public void jdoPreStore() {
292: }
293:
294: public void jdoPreDelete() {
295: PersistenceManager myPM = JDOHelper.getPersistenceManager(this );
296: Object[] values = normalMap.values().toArray();
297:
298: normalMap.clear();
299: normalObjectMap.clear();
300:
301: myPM.deletePersistentAll(values);
302:
303: if (!inverseMap.isEmpty())
304: throw new RuntimeException(
305: "Entries still left in inverseMap");
306: }
307: }
|