/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.db;

import junit.framework.*;

import java.io.*;
import java.util.*;

import net.sourceforge.pain.db.data.*;

/**
 * User: fmike  Date: Aug 26, 2003   Time: 3:30:29 AM
 */
public final class CollectionsTest extends TestCase {


	private PainDB db;

	public CollectionsTest() {
		super("CollectionsTest");
	}

	protected void setUp() throws Exception {
		db = new PainDB(getName() + ".db");
		db.ALLOW_PLAIN_WRITE = true; // allow work without transactions
		db.MANUAL_FLUSH_MODE = true; // commit will not flush (objects stays dirty)

	}

	protected void tearDown() throws Exception {
		if (db != null) {
			File file = new File(db.getDbFileName());
			if (!db.isClosed()) {
				db.forceClose();
			}
			db = null;
			file.delete();
		}
	}

	public void testArrayList1() throws Exception {
		db.beginTransaction();
		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		final DbArrayList list = obj1.getARRAY_LIST();
		_testList1(list, obj2);
		db.commitTransaction();
	}

	public void testLinkedList1() throws Exception {
		db.beginTransaction();
		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		final DbLinkedList list = obj1.getLINKED_LIST();
		_testList1(list, obj2);
		db.commitTransaction();
	}


	private void _testList1(final List list, AllFieldTypesObject obj2) throws IOException {
		list.add(obj2);
		assertTrue(list.contains(obj2));
		assertEquals(1, list.size());
		assertSame(obj2, list.get(0));
		assertEquals(0, list.indexOf(obj2));
		db.commitTransaction();

		db.beginTransaction();
		list.add(obj2);
		list.add(obj2);
		list.add(obj2);
		assertEquals(4, list.size());
		int i = 0;
		for (Iterator it = list.iterator(); it.hasNext(); i++) {
			assertSame(it.next(), obj2);
		}
		assertEquals(4, i);
		i = 0;
		for (Iterator it = list.iterator(); it.hasNext(); i++) {
			assertSame(it.next(), obj2);
		}
		assertEquals(4, i);
		db.commitTransaction();

		db.beginTransaction();
		obj2.delete();
		assertEquals(4, list.size());
		assertTrue(list.contains(null));
		i = 0;
		for (Iterator it = list.iterator(); it.hasNext(); i++) {
			assertNull(it.next());
		}
		assertEquals(4, i);
		list.clear();
		assertTrue(list.isEmpty());
		db.rollbackTransaction();

		db.beginTransaction();
		assertEquals(4, list.size());
		i = 0;
		for (Iterator it = list.iterator(); it.hasNext(); i++) {
			assertSame(it.next(), obj2);
		}
		assertEquals(4, i);
	}

	public void testReferenceSet1() throws Exception {
		db.beginTransaction();
		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		final DbReferenceSet set = obj1.getREFERENCE_SET();
		set.add(obj2);
		assertEquals(1, set.size());
		assertTrue(set.contains(obj2));
		assertTrue(set.remove(obj2));
		assertTrue(set.isEmpty());
		db.commitTransaction();

		db.beginTransaction();
		set.add(obj2);
		set.add(obj1);
		assertEquals(2, set.size());
		set.add(obj2);
		set.add(obj1);
		assertEquals(2, set.size());
		int i = 0;
		for (Iterator it = set.iterator(); it.hasNext(); i++) {
			assertNotNull(it.next());
		}
		assertEquals(2, i);
		obj2.delete();
		assertEquals(set.size(), 1);
		db.commitTransaction();

		db.beginTransaction();
		assertTrue(set.contains(obj1));
		set.clear();
		assertTrue(set.isEmpty());
		db.commitTransaction();
	}

	public void testIntKeyMap1() throws Exception {
		db.beginTransaction();

		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		_testMap1(obj1, obj2, obj1.getINT_KEY_MAP(), new Integer(100), new Integer(200));

		db.commitTransaction();
	}

	public void testStringKeyMap1() throws Exception {
		db.beginTransaction();

		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		AllFieldTypesObject obj2 = new AllFieldTypesObject(db);
		_testMap1(obj1, obj2, obj1.getSTRING_KEY_MAP(), "100", "101");

		db.commitTransaction();
	}

	private void _testMap1(AllFieldTypesObject obj1, AllFieldTypesObject obj2, Map map, Object key1, Object key2) throws Exception {
		map.put(key1, obj2);
		assertEquals(1, map.size());
		assertTrue(map.containsValue(obj2));
		assertTrue(map.containsKey(key1));
		assertEquals(obj2, map.remove(key1));
		assertTrue(map.isEmpty());
		db.commitTransaction();

		db.beginTransaction();
		map.put(key1, obj2);
		map.put(key2, obj1);
		assertEquals(2, map.size());
		map.put(key1, obj2);
		map.put(key2, obj1);
		assertEquals(2, map.size());
		int i = 0;
		for (Iterator it = map.values().iterator(); it.hasNext(); i++) {
			assertNotNull(it.next());
		}
		assertEquals(2, i);
		obj2.delete();
		assertEquals(map.size(), 1);
		db.commitTransaction();

		db.beginTransaction();
		assertTrue(map.containsValue(obj1));
		map.clear();
		assertTrue(map.isEmpty());

	}

	public void testStringSet1() throws Exception {
		db.beginTransaction();
		AllFieldTypesObject obj1 = new AllFieldTypesObject(db);
		final DbStringSet set = obj1.getSTRING_SET();
		final String str1 = "some string 1";
		final String str2 = "some string 2";
		set.add(str1);
		assertEquals(1, set.size());
		assertTrue(set.contains(str1));
		assertTrue(set.remove(str1));
		assertTrue(set.isEmpty());
		db.commitTransaction();

		db.beginTransaction();
		set.add(str1);
		set.add(str2);
		assertEquals(2, set.size());
		set.add(str1);
		set.add(str2);
		assertEquals(2, set.size());
		int i = 0;
		for (Iterator it = set.iterator(); it.hasNext(); i++) {
			assertNotNull(it.next());
		}
		assertEquals(2, i);
		db.commitTransaction();

		db.beginTransaction();
		assertTrue(set.contains(str1));
		set.clear();
		assertTrue(set.isEmpty());
		db.commitTransaction();
	}

	public void testStringSetIterator1() throws Exception {
		db.beginTransaction();
		_testSetIterator1(new AllFieldTypesObject(db).getSTRING_SET(), "v1", "v2", "v3", "v4", "v5");
		db.commitTransaction();
	}

	public void testReferenceSetIterator1() throws Exception {
		db.beginTransaction();
		_testSetIterator1(new AllFieldTypesObject(db).getREFERENCE_SET(), new AllFieldTypesObject(db), new AllFieldTypesObject(db), new AllFieldTypesObject(db), new AllFieldTypesObject(db), new AllFieldTypesObject(db));
		db.commitTransaction();
	}

	private void _testSetIterator1(Set set, Object v1, Object v2, Object v3, Object v4, Object v5) throws IOException {
		set.add(v1);
		set.add(v2);
		set.add(v3);
		set.add(v4);
		set.add(v5);
		assertEquals(set.size(), 5);
		db.commitTransaction();

		db.beginTransaction();
		int i = 0;
		for (Iterator it = set.iterator(); it.hasNext(); i++) {
			it.next();
			if (i == 1 || i == 2) {
				it.remove();
			}
		}
		assertEquals(i, 5);
		assertEquals(set.size(), 3);
		db.rollbackTransaction();

		db.beginTransaction();
		assertEquals(set.size(), 5);
	}

	public void testMapInterface1() throws IOException {
		db.beginTransaction();
		AllFieldTypesObject obj = new AllFieldTypesObject(db);
		Object values[] = new Object[20];
		Object[] keys = new Object[values.length];
		for (int i = 0; i < values.length; i++) {
			values[i] = new AllFieldTypesObject(db);
			keys[i] = "" + i;
		}
		_testMapInterface(obj.getSTRING_KEY_MAP(), keys, values);


		for (int i = 0; i < values.length; i++) {
			keys[i] = "" + i;
			values[i] = "value" + i;
		}
		_testMapInterface(obj.getSTRING_MAP(), keys, values);


		for (int i = 0; i < values.length; i++) {
			values[i] = new AllFieldTypesObject(db);
			keys[i] = new Integer(i);
		}
		_testMapInterface(obj.getINT_KEY_MAP(), keys, values);
		db.commitTransaction();
	}

	private void _testMapInterface(Map map, Object[] keys, Object[] values) {
		for (int i = 0; i < keys.length; i++) {
			map.put(keys[i], values[i]);
		}
		assertEquals(map.size(), keys.length);
		assertFalse(map.isEmpty());
		for (int i = 0; i < keys.length; i++) {
			assertTrue(map.containsKey(keys[i]));
			assertTrue(map.containsValue(values[i]));
			assertEquals(map.get(keys[i]), values[i]);
			assertEquals(map.remove(keys[i]), values[i]);
			assertEquals(keys.length - 1, map.size());
			assertNull(map.put(keys[i], values[i]));
			assertEquals(keys.length, map.size());
		}

		map.clear();
		assertTrue(map.isEmpty());
	}

	public void testIterator1() throws IOException {
		db.beginTransaction();

		// int key map
		Map intMap1 = new AllFieldTypesObject(db).getINT_KEY_MAP();
		Map intMap2 = new AllFieldTypesObject(db).getINT_KEY_MAP();
		Map stringKeyMap1 = new AllFieldTypesObject(db).getSTRING_KEY_MAP();
		Map stringKeyMap2 = new AllFieldTypesObject(db).getSTRING_KEY_MAP();
		List llist = new AllFieldTypesObject(db).getLINKED_LIST();
		List alist = new AllFieldTypesObject(db).getARRAY_LIST();
		Set refSet = new AllFieldTypesObject(db).getREFERENCE_SET();
		Set stringSet = new AllFieldTypesObject(db).getSTRING_SET();
		Map stringMap1 = new AllFieldTypesObject(db).getSTRING_MAP();
		Map stringMap2 = new AllFieldTypesObject(db).getSTRING_MAP();


		for (int i = 0; i < 20; i++) {
			intMap1.put(new Integer(i), new AllFieldTypesObject(db));
			intMap2.put(new Integer(i), new AllFieldTypesObject(db));

			stringKeyMap1.put("" + i, new AllFieldTypesObject(db));
			stringKeyMap2.put("" + i, new AllFieldTypesObject(db));

			stringMap1.put("" + i, "value-" + i);
			stringMap2.put("" + i, "value+" + i);


			llist.add(new AllFieldTypesObject(db));
			alist.add(new AllFieldTypesObject(db));

			refSet.add(new AllFieldTypesObject(db));
			stringSet.add("" + i);
		}

		_testIterator1(stringKeyMap1.values().iterator());
		_testIterator1(stringKeyMap2.keySet().iterator());


		_testIterator1(stringMap1.values().iterator());
		_testIterator1(stringMap2.keySet().iterator());

		_testIterator1(intMap1.values().iterator());
		_testIterator1(intMap2.keySet().iterator());

		_testIterator1(llist.iterator());
		_testIterator1(alist.iterator());

		_testIterator1(refSet.iterator());
		_testIterator1(stringSet.iterator());

		db.commitTransaction();
	}

	private void _testIterator1(Iterator it) {
		while (it.hasNext()) {
			assertNotNull(it.next());
			it.remove();
		}
	}


	public void testIterator2() throws IOException {
		db.beginTransaction();

		// int key map
		Map intMap1 = new AllFieldTypesObject(db).getINT_KEY_MAP();
		Map intMap2 = new AllFieldTypesObject(db).getINT_KEY_MAP();
		Map stringKeyMap1 = new AllFieldTypesObject(db).getSTRING_KEY_MAP();
		Map stringKeyMap2 = new AllFieldTypesObject(db).getSTRING_KEY_MAP();
		Map stringMap1 = new AllFieldTypesObject(db).getSTRING_MAP();
		Map stringMap2 = new AllFieldTypesObject(db).getSTRING_MAP();

		List llist = new AllFieldTypesObject(db).getLINKED_LIST();
		List alist = new AllFieldTypesObject(db).getARRAY_LIST();
		Set refSet = new AllFieldTypesObject(db).getREFERENCE_SET();
		Set stringSet = new AllFieldTypesObject(db).getSTRING_SET();

		final int N = 20;
		for (int i = 0; i < N; i++) {
			intMap1.put(new Integer(i), new AllFieldTypesObject(db));
			intMap2.put(new Integer(i), new AllFieldTypesObject(db));

			stringKeyMap1.put("" + i, new AllFieldTypesObject(db));
			stringKeyMap2.put("" + i, new AllFieldTypesObject(db));

			stringMap1.put("" + i, "value-" + i);
			stringMap2.put("" + i, "value+" + i);

			llist.add(new AllFieldTypesObject(db));
			alist.add(new AllFieldTypesObject(db));

			refSet.add(new AllFieldTypesObject(db));
			stringSet.add("" + i);
		}

		_testIterator2(stringMap1.values());
		_testIterator2(stringMap2.keySet());

		_testIterator2(stringKeyMap1.values());
		_testIterator2(stringKeyMap2.keySet());

		_testIterator2(intMap1.values());
		_testIterator2(intMap2.keySet());

		_testIterator2(llist);
		_testIterator2(alist);

		_testIterator2(refSet);
		_testIterator2(stringSet);

		db.commitTransaction();
	}

	private void _testIterator2(Collection c) {
		int i = 0;
		while (!c.isEmpty()) {
			for (Iterator it = c.iterator(); it.hasNext(); i++) {
				assertNotNull(it.next());
				if (i % 3 == 0) {
					it.remove();
				}
			}
		}
	}

	public void testIteratorBUG1() throws IOException {
		db.beginTransaction();
		Map map = new AllFieldTypesObject(db).getINT_KEY_MAP();
		for (int i = 0; i < 7; i++) {
			map.put(new Integer(i), new AllFieldTypesObject(db));
		}
		int i = 0;
		for (Iterator it = map.values().iterator(); it.hasNext(); i++) {
			it.next();
			if (i == 0 || i == 3 || i == 4 || i == 6) {
				it.remove();
			}
		}

		for (Iterator it = map.values().iterator(); it.hasNext(); i++) {
			DbObject obj = (DbObject) it.next();
			assertFalse(obj.isDeleted());
			it.remove();
		}
		assertTrue(map.isEmpty());
		db.commitTransaction();
	}

}