001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.db4ounit.common.reflect.custom;
022:
023: import com.db4o.foundation.*;
024: import com.db4o.foundation.io.Path4;
025: import com.db4o.internal.*;
026:
027: import db4ounit.*;
028:
029: /**
030: * This test case serves two purposes:
031: *
032: * 1) testing the reflector API
033: * 2) documenting a common use case for the reflector API which is adapting an external
034: * data model to db4o's internal OO based mechanism.
035: *
036: * See CustomReflector, CustomClassRepository, CustomClass, CustomField and CustomUidField
037: * for details.
038: *
039: */
040: public class CustomReflectorTestCase implements TestCase, TestLifeCycle {
041:
042: private static final String CAT_CLASS = "Cat";
043: private static final String[] CAT_FIELD_NAMES = new String[] {
044: "name", "troubleMakingScore" };
045: private static final String[] CAT_FIELD_TYPES = new String[] {
046: "string", "int" };
047:
048: private static final String PERSON_CLASS = "Person";
049: private static final String[] PERSON_FIELD_NAMES = new String[] { "name" };
050: private static final String[] PERSON_FIELD_TYPES = new String[] { "string" };
051:
052: private static final PersistentEntry[] CAT_ENTRIES = {
053: new PersistentEntry(CAT_CLASS, "0", new Object[] {
054: "Biro-Biro", new Integer(9) }),
055: new PersistentEntry(CAT_CLASS, "1", new Object[] {
056: "Samira", new Integer(4) }),
057: new PersistentEntry(CAT_CLASS, "2", new Object[] { "Ivo",
058: new Integer(2) }), };
059:
060: private static final PersistentEntry[] PERSON_ENTRIES = {
061: new PersistentEntry(PERSON_CLASS, "10",
062: new Object[] { "Eric Idle" }),
063: new PersistentEntry(PERSON_CLASS, "11",
064: new Object[] { "John Cleese" }), };
065:
066: PersistenceContext _context;
067: Db4oPersistenceProvider _provider;
068:
069: public void setUp() {
070: purge();
071:
072: initializeContext();
073: initializeProvider();
074:
075: createEntryClass(CAT_CLASS, CAT_FIELD_NAMES, CAT_FIELD_TYPES);
076: createIndex(CAT_CLASS, CAT_FIELD_NAMES[0]);
077: restartProvider();
078:
079: createEntryClass(PERSON_CLASS, PERSON_FIELD_NAMES,
080: PERSON_FIELD_TYPES);
081: restartProvider();
082:
083: insertEntries();
084: restartProvider();
085: }
086:
087: public void testUpdate() {
088: PersistentEntry entry = new PersistentEntry(CAT_CLASS,
089: CAT_ENTRIES[0].uid, new Object[] { "Birinho",
090: new Integer(10) });
091: update(entry);
092: restartProvider();
093:
094: //exerciseSelectByField(entry, CAT_FIELD_NAMES);
095:
096: PersistentEntry[] expected = copy(CAT_ENTRIES);
097: expected[0] = entry;
098: assertEntries(expected, selectAll(CAT_CLASS));
099: }
100:
101: public void testSelectAll() {
102:
103: assertEntries(PERSON_ENTRIES, selectAll(PERSON_CLASS));
104: assertEntries(CAT_ENTRIES, selectAll(CAT_CLASS));
105: }
106:
107: public void testSelectByField() {
108:
109: exerciseSelectByField(CAT_ENTRIES, CAT_FIELD_NAMES);
110: exerciseSelectByField(PERSON_ENTRIES, PERSON_FIELD_NAMES);
111: }
112:
113: public void testSelectByFields() {
114:
115: PersistentEntry existing = CAT_ENTRIES[0];
116: PersistentEntry newEntry = new PersistentEntry(CAT_CLASS,
117: existing.uid, new Object[] { existing.fieldValues[0],
118: new Integer(10) });
119: insert(newEntry);
120:
121: Iterator4 found = selectByField(existing.className,
122: CAT_FIELD_NAMES[0], existing.fieldValues[0]);
123: assertEntries(new PersistentEntry[] { existing, newEntry },
124: found);
125:
126: assertSingleEntry(existing, select(existing.className,
127: CAT_FIELD_NAMES, existing.fieldValues));
128: assertSingleEntry(newEntry, select(newEntry.className,
129: CAT_FIELD_NAMES, newEntry.fieldValues));
130:
131: }
132:
133: public void testDropIndex() {
134:
135: dropIndex(CAT_CLASS, CAT_FIELD_NAMES[0]);
136:
137: FieldMetadata field = fieldMetadata(CAT_CLASS,
138: CAT_FIELD_NAMES[0]);
139: Assert.isFalse(field.hasIndex());
140: }
141:
142: public void testFieldIndex() {
143:
144: FieldMetadata field0 = fieldMetadata(CAT_CLASS,
145: CAT_FIELD_NAMES[0]);
146: Assert.isTrue(field0.hasIndex());
147:
148: FieldMetadata field1 = fieldMetadata(CAT_CLASS,
149: CAT_FIELD_NAMES[1]);
150: Assert.isFalse(field1.hasIndex());
151: }
152:
153: private FieldMetadata fieldMetadata(String className,
154: String fieldName) {
155: ClassMetadata meta = classMetadataForName(className);
156: FieldMetadata field0 = meta.fieldMetadataForName(fieldName);
157: return field0;
158: }
159:
160: private void update(PersistentEntry entry) {
161: _provider.update(_context, entry);
162: }
163:
164: private void assertEntries(PersistentEntry[] expected,
165: Iterator4 actual) {
166: Collection4 checklist = new Collection4(actual);
167: Assert.areEqual(expected.length, checklist.size());
168: for (int i = 0; i < expected.length; ++i) {
169: PersistentEntry e = expected[i];
170: PersistentEntry a = entryByUid(checklist.iterator(), e.uid);
171: if (a != null) {
172: assertEqualEntries(e, a);
173: checklist.remove(a);
174: }
175: }
176: Assert.isTrue(checklist.isEmpty(), checklist.toString());
177: }
178:
179: private PersistentEntry entryByUid(Iterator4 iterator, Object uid) {
180: while (iterator.moveNext()) {
181: PersistentEntry e = (PersistentEntry) iterator.current();
182: if (uid.equals(e.uid)) {
183: return e;
184: }
185: }
186: return null;
187: }
188:
189: private ClassMetadata classMetadataForName(String className) {
190: ObjectContainerBase container = (ObjectContainerBase) _provider
191: .dataContainer(_context);
192: return container.classMetadataForReflectClass(container
193: .reflector().forName(className));
194: }
195:
196: private void exerciseSelectByField(PersistentEntry[] entries,
197: String[] fieldNames) {
198: for (int i = 0; i < entries.length; ++i) {
199: exerciseSelectByField(entries[i], fieldNames);
200: }
201: }
202:
203: private void exerciseSelectByField(PersistentEntry expected,
204: String[] fieldNames) {
205: for (int i = 0; i < fieldNames.length; ++i) {
206: Iterator4 found = selectByField(expected.className,
207: fieldNames[i], expected.fieldValues[i]);
208: assertSingleEntry(expected, found);
209: }
210: }
211:
212: private void assertSingleEntry(PersistentEntry expected,
213: Iterator4 found) {
214: Assert.isTrue(found.moveNext(), "Expecting entry '" + expected
215: + "'");
216: PersistentEntry actual = (PersistentEntry) found.current();
217: assertEqualEntries(expected, actual);
218: Assert.isFalse(found.moveNext(), "Expecting only '" + expected
219: + "'");
220: }
221:
222: private void initializeContext() {
223: _context = new PersistenceContext(dataFile());
224: }
225:
226: private void initializeProvider() {
227: _provider = new Db4oPersistenceProvider();
228: _provider.initContext(_context);
229: }
230:
231: private void insertEntries() {
232: insertEntries(CAT_ENTRIES);
233: insertEntries(PERSON_ENTRIES);
234: }
235:
236: private void insertEntries(PersistentEntry[] entries) {
237: PersistentEntry entry = new PersistentEntry(null, null, null);
238: for (int i = 0; i < entries.length; ++i) {
239: entry.className = entries[i].className;
240: entry.uid = entries[i].uid;
241: entry.fieldValues = entries[i].fieldValues;
242: // reuse entries so the provider can't assume
243: // anything about identity
244: insert(entry);
245: }
246: }
247:
248: private void assertEqualEntries(PersistentEntry expected,
249: PersistentEntry actual) {
250: Assert.areEqual(expected.className, actual.className);
251: Assert.areEqual(expected.uid, actual.uid);
252: ArrayAssert.areEqual(expected.fieldValues, actual.fieldValues);
253: }
254:
255: private Iterator4 selectByField(String className, String fieldName,
256: Object fieldValue) {
257: return select(className, new String[] { fieldName },
258: new Object[] { fieldValue });
259: }
260:
261: private Iterator4 select(String className, String[] fieldNames,
262: Object[] fieldValues) {
263: return select(new PersistentEntryTemplate(className,
264: fieldNames, fieldValues));
265: }
266:
267: private Iterator4 selectAll(String className) {
268: return select(className, new String[0], new Object[0]);
269: }
270:
271: private Iterator4 select(PersistentEntryTemplate template) {
272: return _provider.select(_context, template);
273: }
274:
275: private void insert(PersistentEntry entry) {
276: _provider.insert(_context, entry);
277: }
278:
279: private void createIndex(String className, String fieldName) {
280: _provider.createIndex(_context, className, fieldName);
281: }
282:
283: private void dropIndex(String className, String fieldName) {
284: _provider.dropIndex(_context, className, fieldName);
285: }
286:
287: private void createEntryClass(String className,
288: String[] fieldNames, String[] fieldTypes) {
289: _provider.createEntryClass(_context, className, fieldNames,
290: fieldTypes);
291: }
292:
293: public void tearDown() {
294: shutdownProvider(true);
295: _context = null;
296: }
297:
298: private void shutdownProvider(boolean purge) {
299: if (_provider != null)
300: _provider.closeContext(_context);
301: if (purge)
302: purge();
303: _provider = null;
304: }
305:
306: void purge() {
307: new Db4oPersistenceProvider().purge(dataFile());
308: }
309:
310: void restartProvider() {
311: shutdownProvider(false);
312: initializeProvider();
313: }
314:
315: private String dataFile() {
316: return Path4.combine(Path4.getTempPath(),
317: "CustomReflector.db4o");
318: }
319:
320: private PersistentEntry[] copy(PersistentEntry[] entries) {
321: PersistentEntry[] clone = new PersistentEntry[entries.length];
322: System.arraycopy(entries, 0, clone, 0, clone.length);
323: return clone;
324: }
325:
326: }
|