001: package org.apache.ojb.otm.swizzle;
002:
003: /* Copyright 2003-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.lang.reflect.Array;
019: import java.util.Collection;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023: import org.apache.ojb.broker.Identity;
024: import org.apache.ojb.broker.PersistenceBroker;
025: import org.apache.ojb.broker.cache.ObjectCache;
026: import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
027: import org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl;
028: import org.apache.ojb.broker.core.proxy.SetProxyDefaultImpl;
029: import org.apache.ojb.broker.metadata.ClassDescriptor;
030: import org.apache.ojb.broker.metadata.CollectionDescriptor;
031: import org.apache.ojb.broker.metadata.FieldDescriptor;
032: import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
033: import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
034:
035: public class CopySwizzling implements Swizzling {
036:
037: /**
038: * @see org.apache.ojb.otm.swizzle.Swizzling#swizzle(Object, Object, PersistenceBroker, ObjectCache)
039: */
040: public Object swizzle(Object newObj, Object oldObj,
041: PersistenceBroker pb, ObjectCache cache) {
042: if (newObj == null) // invalidating
043: {
044: return null;
045: }
046:
047: if (oldObj == null) {
048: return newObj;
049: }
050:
051: if (!newObj.getClass().equals(oldObj.getClass())) {
052: System.err
053: .println("Cannot swizzle objects of different classes: "
054: + newObj.getClass()
055: + " and "
056: + oldObj.getClass());
057: return newObj;
058: }
059:
060: ClassDescriptor mif = pb.getClassDescriptor(newObj.getClass());
061: FieldDescriptor[] fieldDescs = mif.getFieldDescriptions();
062:
063: for (int i = 0; i < fieldDescs.length; i++) {
064: FieldDescriptor fd = fieldDescs[i];
065: PersistentField f = fd.getPersistentField();
066: f.set(oldObj, f.get(newObj));
067: }
068:
069: // N:1 relations
070: Iterator iter = mif.getObjectReferenceDescriptors().iterator();
071: ObjectReferenceDescriptor rds;
072: PersistentField field;
073: Object newRelObj;
074: Identity newRelOid;
075: Object oldRelObj;
076:
077: while (iter.hasNext()) {
078: rds = (ObjectReferenceDescriptor) iter.next();
079: field = rds.getPersistentField();
080: newRelObj = field.get(newObj);
081: oldRelObj = field.get(oldObj);
082: if ((newRelObj == null) && (oldRelObj != null)) {
083: field.set(oldObj, null);
084: } else if (newRelObj != null) {
085: newRelOid = new Identity(newRelObj, pb);
086: if ((oldRelObj == null)
087: || !newRelOid
088: .equals(new Identity(oldRelObj, pb))) {
089: // seek for existing old object with the new identity
090: oldRelObj = cache.lookup(newRelOid);
091: if (oldRelObj == null) {
092: throw new IllegalStateException(
093: "Related object not found in the context: "
094: + newRelOid);
095: }
096: field.set(oldObj, oldRelObj);
097: }
098: }
099: }
100:
101: // 1:N relations
102: Iterator collections = mif.getCollectionDescriptors()
103: .iterator();
104: CollectionDescriptor collectionDescriptor;
105:
106: while (collections.hasNext()) {
107: collectionDescriptor = (CollectionDescriptor) collections
108: .next();
109: field = collectionDescriptor.getPersistentField();
110: if (Collection.class.isAssignableFrom(field.getType())) {
111: Collection newCol;
112: Collection oldCol;
113:
114: newCol = (Collection) field.get(newObj);
115: if (newCol == null) {
116: field.set(oldObj, null);
117: continue;
118: }
119:
120: oldCol = (Collection) field.get(oldObj);
121: if (newCol instanceof CollectionProxyDefaultImpl) {
122: CollectionProxyDefaultImpl cp = (CollectionProxyDefaultImpl) newCol;
123: if (newCol instanceof List) {
124: oldCol = new ListProxyDefaultImpl(
125: pb.getPBKey(), cp.getCollectionClass(),
126: cp.getQuery());
127: } else if (newCol instanceof Set) {
128: oldCol = new SetProxyDefaultImpl(pb.getPBKey(),
129: cp.getCollectionClass(), cp.getQuery());
130: } else {
131: oldCol = new CollectionProxyDefaultImpl(pb
132: .getPBKey(), cp.getCollectionClass(),
133: cp.getQuery());
134: }
135: if (!((CollectionProxyDefaultImpl) newCol)
136: .isLoaded()) {
137: field.set(oldObj, oldCol);
138: continue;
139: }
140: oldCol.clear();
141: } else {
142: try {
143: oldCol = (Collection) newCol.getClass()
144: .newInstance();
145: } catch (Exception ex) {
146: System.err
147: .println("Cannot instantiate collection field which is neither Collection nor array: "
148: + field);
149: ex.printStackTrace();
150: return newObj;
151: }
152: }
153: field.set(oldObj, oldCol);
154: for (Iterator it = newCol.iterator(); it.hasNext();) {
155: newRelObj = it.next();
156: newRelOid = new Identity(newRelObj, pb);
157: oldRelObj = cache.lookup(newRelOid);
158: if (oldRelObj == null) {
159: oldRelObj = newRelObj;
160: }
161: oldCol.add(oldRelObj);
162: }
163: } else if (field.getType().isArray()) {
164: Object newArray = field.get(newObj);
165: int length = Array.getLength(newArray);
166: Object oldArray = Array.newInstance(field.getType()
167: .getComponentType(), length);
168:
169: for (int i = 0; i < length; i++) {
170: newRelObj = Array.get(newArray, i);
171: newRelOid = new Identity(newRelObj, pb);
172: oldRelObj = cache.lookup(newRelOid);
173: if (oldRelObj == null) {
174: throw new IllegalStateException(
175: "Related object not found for swizzle: "
176: + newRelOid);
177: }
178: Array.set(oldArray, i, oldRelObj);
179: }
180: field.set(oldObj, oldArray);
181: } else {
182: throw new IllegalStateException(
183: "Cannot swizzle collection field: " + field);
184: }
185: }
186:
187: return oldObj;
188: }
189:
190: /**
191: * @see org.apache.ojb.otm.swizzle.Swizzling#isSameInstance(Object, Object)
192: */
193: public boolean isSameInstance(Object swizzledObject, Object object) {
194: return (swizzledObject == object);
195: }
196:
197: /**
198: * @see org.apache.ojb.otm.swizzle.Swizzling#getRealTarget(Object)
199: */
200: public Object getRealTarget(Object swizzledObject) {
201: return swizzledObject;
202: }
203:
204: }
|