001: package org.apache.ojb.broker;
002:
003: import java.util.ArrayList;
004: import java.util.Iterator;
005: import java.util.List;
006:
007: import org.apache.commons.lang.builder.ToStringBuilder;
008: import org.apache.ojb.broker.metadata.ClassDescriptor;
009: import org.apache.ojb.broker.metadata.CollectionDescriptor;
010: import org.apache.ojb.junit.PBTestCase;
011:
012: /* Copyright 2002-2005 The Apache Software Foundation
013: *
014: * Licensed under the Apache License, Version 2.0 (the "License");
015: * you may not use this file except in compliance with the License.
016: * You may obtain a copy of the License at
017: *
018: * http://www.apache.org/licenses/LICENSE-2.0
019: *
020: * Unless required by applicable law or agreed to in writing, software
021: * distributed under the License is distributed on an "AS IS" BASIS,
022: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
023: * See the License for the specific language governing permissions and
024: * limitations under the License.
025: */
026:
027: /**
028: * Realize object tree via m:n relation.
029: *
030: * IMPORTANT NOTE: The global runtime metadata changes made by this test case
031: * are NOT recommended in multithreaded environments, because they are global
032: * and each thread will be affected.
033: *
034: * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
035: * @version $Id: M2NGraphTest.java,v 1.2.2.3 2005/12/21 22:31:23 tomdz Exp $
036: */
037: public class M2NGraphTest extends PBTestCase {
038: public static void main(String[] args) {
039: String[] arr = { M2NGraphTest.class.getName() };
040: junit.textui.TestRunner.main(arr);
041: }
042:
043: public void tearDown() throws Exception {
044: changeRelationMetadata("children", true,
045: CollectionDescriptor.CASCADE_NONE,
046: CollectionDescriptor.CASCADE_NONE, false);
047: changeRelationMetadata("parents", true,
048: CollectionDescriptor.CASCADE_NONE,
049: CollectionDescriptor.CASCADE_NONE, false);
050: super .tearDown();
051: }
052:
053: /**
054: * All stuff is done by OJB
055: */
056: public void testAddNewChild_1() throws Exception {
057: changeRelationMetadata("children", true,
058: CollectionDescriptor.CASCADE_OBJECT,
059: CollectionDescriptor.CASCADE_OBJECT, false);
060: changeRelationMetadata("parents", true,
061: CollectionDescriptor.CASCADE_OBJECT,
062: CollectionDescriptor.CASCADE_OBJECT, false);
063:
064: String postfix = "_testAddNewChild_1_"
065: + System.currentTimeMillis();
066:
067: Node nodeA = new Node("nodeA" + postfix);
068: Node nodeB = new Node("nodeB" + postfix);
069: Node nodeB2 = new Node("nodeB2" + postfix);
070: Node nodeC = new Node("nodeC" + postfix);
071:
072: //===============================================
073: broker.beginTransaction();
074: nodeA.addChildNode(nodeB);
075: nodeA.addChildNode(nodeB2);
076: nodeB.addChildNode(nodeC);
077: broker.store(nodeA);
078: broker.commitTransaction();
079: //===============================================
080:
081: Identity oidA = new Identity(nodeA, broker);
082: Identity oidB = new Identity(nodeB, broker);
083: Identity oidC = new Identity(nodeC, broker);
084:
085: broker.clearCache();
086:
087: // get the stored stuff
088: Node retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
089: assertNotNull("Verifying the nodeB was retrieved",
090: retrievednodeB);
091: assertEquals(
092: "verify the retrieved nodeB has 1 parent (the nodeA)",
093: 1, retrievednodeB.getParents().size());
094: Node retrievednodeA = (Node) retrievednodeB.getParents().get(0);
095: assertEquals("verify the nodeA was stored", nodeA.getName(),
096: retrievednodeA.getName());
097: assertNotNull(retrievednodeA.getChildren());
098: assertEquals(
099: "verify the retrieved nodeA has 2 childs (the nodeB)",
100: 2, retrievednodeA.getChildren().size());
101: for (Iterator i = retrievednodeA.getChildren().iterator(); i
102: .hasNext();) {
103: Node b = (Node) i.next();
104: //this next test fails because the child is null
105: assertNotNull("Verifying nodeA's children are not null", b);
106: assertTrue("verify, child is the nodeBx", nodeB.getName()
107: .equals(b.getName())
108: || nodeB2.getName().equals(b.getName()));
109: }
110: assertNotNull(retrievednodeB.getChildren());
111: assertEquals(1, retrievednodeB.getChildren().size());
112: assertNotNull(nodeC.getName(), ((Node) retrievednodeB
113: .getChildren().get(0)).getName());
114:
115: // get the stored stuff vice versa
116: retrievednodeA = (Node) broker.getObjectByIdentity(oidA);
117: assertNotNull(retrievednodeA);
118: assertNotNull(retrievednodeA.getChildren());
119: assertEquals(2, retrievednodeA.getChildren().size());
120: retrievednodeB = (Node) retrievednodeA.getChildren().get(0);
121: assertNotNull(retrievednodeB);
122: assertNotNull(retrievednodeB.getParents());
123: assertEquals(1, retrievednodeB.getParents().size());
124:
125: broker.clearCache();
126: retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
127: //===============================================
128: broker.beginTransaction();
129: broker.delete(nodeB);
130: broker.commitTransaction();
131: //===============================================
132:
133: retrievednodeA = (Node) broker.getObjectByIdentity(oidA);
134: retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
135: Node retrievednodeC = (Node) broker.getObjectByIdentity(oidC);
136:
137: // complete hierachy will be deleted
138: assertNull(retrievednodeA);
139: assertNull(retrievednodeB);
140: assertNull(retrievednodeC);
141: }
142:
143: /**
144: * Autoretrieve is true, update/delete is done by hand
145: */
146: public void testAddNewChild_2() throws Exception {
147: changeRelationMetadata("children", true,
148: CollectionDescriptor.CASCADE_NONE,
149: CollectionDescriptor.CASCADE_NONE, false);
150: changeRelationMetadata("parents", true,
151: CollectionDescriptor.CASCADE_NONE,
152: CollectionDescriptor.CASCADE_NONE, false);
153:
154: String postfix = "_testAddNewChild_2_"
155: + System.currentTimeMillis();
156:
157: Node nodeA = new Node("nodeA" + postfix);
158: Node nodeB = new Node("nodeB" + postfix);
159: Node nodeB2 = new Node("nodeB2" + postfix);
160: Node nodeC = new Node("nodeC" + postfix);
161:
162: //===============================================
163: broker.beginTransaction();
164: nodeA.addChildNode(nodeB);
165: nodeA.addChildNode(nodeB2);
166: nodeB.addChildNode(nodeC);
167:
168: //store nodeA first
169: broker.store(nodeA);
170: //then store the nodeB
171: broker.store(nodeB);
172: broker.store(nodeB2);
173: broker.store(nodeC);
174: //make A the parent of B because they are not linked in the code automatically
175: broker.serviceBrokerHelper().link(nodeA, true);
176: // broker.serviceBrokerHelper().link(nodeB, true);
177: // this will not work, because nodeB already linked by nodeA
178: // so better specify the field to be link
179: broker.serviceBrokerHelper().link(nodeB, "children", true);
180: broker.commitTransaction();
181: //===============================================
182:
183: Identity oidA = new Identity(nodeA, broker);
184: Identity oidB = new Identity(nodeB, broker);
185: Identity oidC = new Identity(nodeC, broker);
186:
187: broker.clearCache();
188:
189: // get the stored stuff
190: Node retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
191:
192: assertNotNull("Verifying the nodeB was retrieved",
193: retrievednodeB);
194: assertEquals(
195: "verify the retrieved nodeB has 1 parent (the nodeA)",
196: 1, retrievednodeB.getParents().size());
197:
198: Node retrievednodeA = (Node) retrievednodeB.getParents().get(0);
199:
200: assertEquals("verify the nodeA was stored", nodeA.getName(),
201: retrievednodeA.getName());
202: assertNotNull(retrievednodeA.getChildren());
203: assertEquals(
204: "verify the retrieved nodeA has 2 childs (the nodeB)",
205: 2, retrievednodeA.getChildren().size());
206: for (Iterator i = retrievednodeA.getChildren().iterator(); i
207: .hasNext();) {
208: Node b = (Node) i.next();
209: //this next test fails because the child is null
210: assertNotNull("Verifying nodeA's children are not null", b);
211: assertTrue("verify, child is the nodeBx", nodeB.getName()
212: .equals(b.getName())
213: || nodeB2.getName().equals(b.getName()));
214: }
215: assertNotNull(retrievednodeB.getChildren());
216: assertEquals(1, retrievednodeB.getChildren().size());
217: assertNotNull(nodeC.getName(), ((Node) retrievednodeB
218: .getChildren().get(0)).getName());
219:
220: // get the stored stuff vice versa
221: retrievednodeA = (Node) broker.getObjectByIdentity(oidA);
222: assertNotNull(retrievednodeA);
223: assertNotNull(retrievednodeA.getChildren());
224: assertEquals(2, retrievednodeA.getChildren().size());
225: retrievednodeB = (Node) retrievednodeA.getChildren().get(0);
226: assertNotNull(retrievednodeB);
227: assertNotNull(retrievednodeB.getParents());
228: assertEquals(1, retrievednodeB.getParents().size());
229:
230: broker.clearCache();
231: retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
232: // cascade delete is not set and we only want to delete node B
233: //===============================================
234: broker.beginTransaction();
235: broker.serviceBrokerHelper().unlink(nodeB);
236: broker.delete(nodeB);
237: broker.commitTransaction();
238: //===============================================
239:
240: retrievednodeA = (Node) broker.getObjectByIdentity(oidA);
241: retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
242: Node retrievednodeC = (Node) broker.getObjectByIdentity(oidC);
243:
244: // only nodeB should be deleted
245: assertNotNull(retrievednodeA);
246: assertNull(retrievednodeB);
247: assertNotNull(retrievednodeC);
248: }
249:
250: /**
251: * Do all work manually
252: */
253: public void testAddNewChild_3() throws Exception {
254: changeRelationMetadata("children", false,
255: CollectionDescriptor.CASCADE_NONE,
256: CollectionDescriptor.CASCADE_NONE, false);
257: changeRelationMetadata("parents", false,
258: CollectionDescriptor.CASCADE_NONE,
259: CollectionDescriptor.CASCADE_NONE, false);
260:
261: String postfix = "_testAddNewChild_3_"
262: + System.currentTimeMillis();
263:
264: Node nodeA = new Node("nodeA" + postfix);
265: Node nodeB = new Node("nodeB" + postfix);
266: Node nodeC = new Node("nodeC" + postfix);
267:
268: //===============================================
269: broker.beginTransaction();
270: nodeA.addChildNode(nodeB);
271: nodeB.addChildNode(nodeC);
272: //store nodeA first
273: broker.store(nodeA);
274: //then store the nodeB
275: broker.store(nodeB);
276: broker.store(nodeC);
277: //make A the parent of B because they are not linked in the code automatically
278: broker.serviceBrokerHelper().link(nodeA, "children", true);
279: broker.serviceBrokerHelper().link(nodeB, "children", true);
280: broker.commitTransaction();
281: //===============================================
282:
283: Identity oidA = new Identity(nodeA, broker);
284: Identity oidB = new Identity(nodeB, broker);
285:
286: broker.clearCache();
287:
288: // get the stored stuff
289: Node retrievednodeB = (Node) broker.getObjectByIdentity(oidB);
290: assertNotNull("Verifying the nodeB was retrieved",
291: retrievednodeB);
292: assertEquals(nodeB.getName(), retrievednodeB.getName());
293: //===============================================
294: broker.retrieveReference(retrievednodeB, "parents");
295: assertEquals(
296: "verify the retrieved nodeB has 1 parent (the nodeA)",
297: 1, retrievednodeB.getParents().size());
298: Node retrievednodeA = (Node) retrievednodeB.getParents().get(0);
299: //===============================================
300: broker.retrieveReference(retrievednodeA, "children");
301: assertEquals("verify the nodeA was stored", nodeA.getName(),
302: retrievednodeA.getName());
303: assertNotNull(retrievednodeA.getChildren());
304: assertEquals(
305: "verify the retrieved nodeA has 1 child (the nodeB)",
306: 1, retrievednodeA.getChildren().size());
307: for (Iterator i = retrievednodeA.getChildren().iterator(); i
308: .hasNext();) {
309: Node b = (Node) i.next();
310: //this next test fails because the child is null
311: assertNotNull("Verifying nodeA's children are not null", b);
312: assertEquals(
313: "verify, using hashcode, that the nodeAs child is the nodeB",
314: retrievednodeB.getName(), b.getName());
315: }
316: //===============================================
317: broker.retrieveReference(retrievednodeB, "children");
318: assertNotNull(retrievednodeB.getChildren());
319: assertEquals(1, retrievednodeB.getChildren().size());
320: assertNotNull(nodeC.getName(), ((Node) retrievednodeB
321: .getChildren().get(0)).getName());
322:
323: // get the stored stuff vice versa
324: retrievednodeA = (Node) broker.getObjectByIdentity(oidA);
325: broker.retrieveReference(retrievednodeA, "children");
326: assertNotNull(retrievednodeA);
327: assertNotNull(retrievednodeA.getChildren());
328: assertEquals(1, retrievednodeA.getChildren().size());
329: retrievednodeB = (Node) retrievednodeA.getChildren().get(0);
330: assertNotNull(retrievednodeB);
331: broker.retrieveReference(retrievednodeB, "parents");
332: assertNotNull(retrievednodeB.getParents());
333: assertEquals(1, retrievednodeB.getParents().size());
334: }
335:
336: void changeRelationMetadata(String field, boolean autoRetrieve,
337: int autoUpdate, int autoDelete, boolean proxy) {
338: ClassDescriptor cld = broker.getClassDescriptor(Node.class);
339: CollectionDescriptor cod = cld
340: .getCollectionDescriptorByName(field);
341: cod.setLazy(proxy);
342: cod.setCascadeRetrieve(autoRetrieve);
343: cod.setCascadingStore(autoUpdate);
344: cod.setCascadingDelete(autoDelete);
345: }
346:
347: //=========================================
348: // test classes
349: //=========================================
350: public static class Node {
351: private Integer id;
352: private String name;
353: private List children;
354: private List parents;
355:
356: public Node() {
357: }
358:
359: public Node(String name) {
360: this .name = name;
361: }
362:
363: public Integer getId() {
364: return id;
365: }
366:
367: public void setId(Integer id) {
368: this .id = id;
369: }
370:
371: public String getName() {
372: return name;
373: }
374:
375: public void setName(String name) {
376: this .name = name;
377: }
378:
379: public void addChildNode(Node child) {
380: // Cannot add same child twice
381: if (!getChildren().contains(child)) {
382: getChildren().add(child);
383: if (!child.getParents().contains(this )) {
384: child.getParents().add(this );
385: }
386: }
387: }
388:
389: // public void addParentNode(Node parent)
390: // {
391: // if(! getParents().contains(parent))
392: // {
393: // getParents().add(parent);
394: // if(!parent.getChildren().contains(this))
395: // {
396: // parent.getChildren().add(this);
397: // }
398: // }
399: // }
400:
401: public void removeChild(Node child) {
402: getChildren().remove(child);
403: child.getParents().remove(this );
404: }
405:
406: public List getParents() {
407: if (parents == null) {
408: parents = new ArrayList();
409: }
410: return parents;
411: }
412:
413: public void setParents(List parents) {
414: this .parents = parents;
415: }
416:
417: public List getChildren() {
418: if (children == null) {
419: children = new ArrayList();
420: }
421: return children;
422: }
423:
424: public void setChildren(List children) {
425: this .children = children;
426: }
427:
428: public String toString() {
429: return new ToStringBuilder(this ).append("id", id).append(
430: "name", name).append("children",
431: children != null ? children.size() : 0).append(
432: "parents", parents != null ? parents.size() : 0)
433: .toString();
434: }
435:
436: public boolean equals(Object ref) {
437: if (ref == null || !(ref instanceof Node)) {
438: return false;
439: } else {
440: return (getId() != null ? getId().equals(
441: ((Node) ref).getId()) : false);
442: }
443: }
444: }
445: }
|