KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cayenne > util > DeepMergeOperation


1 /*****************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  ****************************************************************/

19
20 package org.apache.cayenne.util;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import org.apache.cayenne.CayenneRuntimeException;
29 import org.apache.cayenne.ObjectContext;
30 import org.apache.cayenne.ObjectId;
31 import org.apache.cayenne.Persistent;
32 import org.apache.cayenne.reflect.AttributeProperty;
33 import org.apache.cayenne.reflect.ClassDescriptor;
34 import org.apache.cayenne.reflect.PropertyVisitor;
35 import org.apache.cayenne.reflect.ToManyProperty;
36 import org.apache.cayenne.reflect.ToOneProperty;
37
38 /**
39  * An operation that performs object graph deep merge, terminating merge at unresolved
40  * nodes.
41  *
42  * @since 1.2
43  * @author Andrus Adamchik
44  */

45 public class DeepMergeOperation {
46
47     protected ObjectContext context;
48     protected Map JavaDoc seen;
49
50     public DeepMergeOperation(ObjectContext context) {
51         this.context = context;
52         this.seen = new HashMap JavaDoc();
53     }
54
55     public void reset() {
56         seen.clear();
57     }
58
59     public Object JavaDoc merge(Object JavaDoc object, ClassDescriptor descriptor) {
60         if (!(object instanceof Persistent)) {
61             throw new CayenneRuntimeException("Expected Persistent, got: " + object);
62         }
63
64         final Persistent source = (Persistent) object;
65         ObjectId id = source.getObjectId();
66
67         // sanity check
68
if (id == null) {
69             throw new CayenneRuntimeException("Server returned an object without an id: "
70                     + source);
71         }
72
73         Object JavaDoc seenTarget = seen.get(id);
74         if (seenTarget != null) {
75             return seenTarget;
76         }
77
78         final Persistent target = context.localObject(id, source);
79         seen.put(id, target);
80
81         descriptor = descriptor.getSubclassDescriptor(source.getClass());
82         descriptor.visitProperties(new PropertyVisitor() {
83
84             public boolean visitToOne(ToOneProperty property) {
85
86                 if (!property.isFault(source)) {
87                     Object JavaDoc destinationSource = property.readProperty(source);
88
89                     Object JavaDoc destinationTarget = destinationSource != null ? merge(
90                             destinationSource,
91                             property.getTargetDescriptor()) : null;
92
93                     Object JavaDoc oldTarget = property.isFault(target) ? null : property
94                             .readProperty(target);
95                     property.writePropertyDirectly(target, oldTarget, destinationTarget);
96                 }
97
98                 return true;
99             }
100
101             public boolean visitToMany(ToManyProperty property) {
102                 if (!property.isFault(source)) {
103                     Collection JavaDoc collection = (Collection JavaDoc) property.readProperty(source);
104
105                     Collection JavaDoc targetCollection = new ArrayList JavaDoc(collection.size());
106
107                     Iterator JavaDoc it = collection.iterator();
108                     while (it.hasNext()) {
109                         Object JavaDoc destinationSource = it.next();
110                         Object JavaDoc destinationTarget = destinationSource != null ? merge(
111                                 destinationSource,
112                                 property.getTargetDescriptor()) : null;
113
114                         targetCollection.add(destinationTarget);
115                     }
116
117                     property.writePropertyDirectly(target, null, targetCollection);
118                 }
119
120                 return true;
121             }
122
123             public boolean visitAttribute(AttributeProperty property) {
124                 return true;
125             }
126         });
127
128         return target;
129     }
130 }
131
Popular Tags