Coverage Report - org.apache.ojb.otm.swizzle.CopySwizzling
 
Classes in this File Line Coverage Branch Coverage Complexity
CopySwizzling
N/A
N/A
11.333
 
 1  
 package org.apache.ojb.otm.swizzle;
 2  
 
 3  
 /* Copyright 2003-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.lang.reflect.Array;
 19  
 import java.util.Collection;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Set;
 23  
 import org.apache.ojb.broker.Identity;
 24  
 import org.apache.ojb.broker.PersistenceBroker;
 25  
 import org.apache.ojb.broker.cache.ObjectCache;
 26  
 import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl;
 27  
 import org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl;
 28  
 import org.apache.ojb.broker.core.proxy.SetProxyDefaultImpl;
 29  
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 30  
 import org.apache.ojb.broker.metadata.CollectionDescriptor;
 31  
 import org.apache.ojb.broker.metadata.FieldDescriptor;
 32  
 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
 33  
 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
 34  
 
 35  
 public class CopySwizzling implements Swizzling
 36  
 {
 37  
 
 38  
     /**
 39  
      * @see org.apache.ojb.otm.swizzle.Swizzling#swizzle(Object, Object, PersistenceBroker, ObjectCache)
 40  
      */
 41  
     public Object swizzle(Object newObj, Object oldObj, PersistenceBroker pb,
 42  
                           ObjectCache cache)
 43  
     {
 44  
         if (newObj == null) // invalidating
 45  
         {
 46  
             return null;
 47  
         }
 48  
 
 49  
         if (oldObj == null)
 50  
         {
 51  
             return newObj;
 52  
         }
 53  
 
 54  
         if (!newObj.getClass().equals(oldObj.getClass()))
 55  
         {
 56  
             System.err.println("Cannot swizzle objects of different classes: "
 57  
                     + newObj.getClass() + " and " + oldObj.getClass());
 58  
             return newObj;
 59  
         }
 60  
 
 61  
         ClassDescriptor mif = pb.getClassDescriptor(newObj.getClass());
 62  
         FieldDescriptor[] fieldDescs = mif.getFieldDescriptions();
 63  
 
 64  
         for (int i = 0; i < fieldDescs.length; i++)
 65  
         {
 66  
             FieldDescriptor fd = fieldDescs[i];
 67  
             PersistentField f = fd.getPersistentField();
 68  
             f.set(oldObj, f.get(newObj));
 69  
         }
 70  
 
 71  
         // N:1 relations
 72  
         Iterator iter = mif.getObjectReferenceDescriptors().iterator();
 73  
         ObjectReferenceDescriptor rds;
 74  
         PersistentField field;
 75  
         Object newRelObj;
 76  
         Identity newRelOid;
 77  
         Object oldRelObj;
 78  
 
 79  
         while (iter.hasNext())
 80  
         {
 81  
             rds = (ObjectReferenceDescriptor) iter.next();
 82  
             field = rds.getPersistentField();
 83  
             newRelObj = field.get(newObj);
 84  
             oldRelObj = field.get(oldObj);
 85  
             if ((newRelObj == null) && (oldRelObj != null))
 86  
             {
 87  
                 field.set(oldObj, null);
 88  
             }
 89  
             else if (newRelObj != null)
 90  
             {
 91  
                 newRelOid = new Identity(newRelObj, pb);
 92  
                 if ((oldRelObj == null) ||
 93  
                         !newRelOid.equals(new Identity(oldRelObj, pb)))
 94  
                 {
 95  
                     // seek for existing old object with the new identity
 96  
                     oldRelObj = cache.lookup(newRelOid);
 97  
                     if (oldRelObj == null)
 98  
                     {
 99  
                         throw new IllegalStateException("Related object not found in the context: " + newRelOid);
 100  
                     }
 101  
                     field.set(oldObj, oldRelObj);
 102  
                 }
 103  
             }
 104  
         }
 105  
 
 106  
         // 1:N relations
 107  
         Iterator collections = mif.getCollectionDescriptors().iterator();
 108  
         CollectionDescriptor collectionDescriptor;
 109  
 
 110  
         while (collections.hasNext())
 111  
         {
 112  
             collectionDescriptor = (CollectionDescriptor) collections.next();
 113  
             field = collectionDescriptor.getPersistentField();
 114  
             if (Collection.class.isAssignableFrom(field.getType()))
 115  
             {
 116  
                 Collection newCol;
 117  
                 Collection oldCol;
 118  
 
 119  
                 newCol = (Collection) field.get(newObj);
 120  
                 if (newCol == null)
 121  
                 {
 122  
                     field.set(oldObj, null);
 123  
                     continue;
 124  
                 }
 125  
 
 126  
                 oldCol = (Collection) field.get(oldObj);
 127  
                 if (newCol instanceof CollectionProxyDefaultImpl)
 128  
                 {
 129  
                     CollectionProxyDefaultImpl cp = (CollectionProxyDefaultImpl) newCol;
 130  
                     if (newCol instanceof List)
 131  
                     {
 132  
                         oldCol = new ListProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
 133  
                     }
 134  
                     else if (newCol instanceof Set)
 135  
                     {
 136  
                         oldCol = new SetProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
 137  
                     }
 138  
                     else
 139  
                     {
 140  
                         oldCol = new CollectionProxyDefaultImpl(pb.getPBKey(), cp.getCollectionClass(), cp.getQuery());
 141  
                     }
 142  
                     if (!((CollectionProxyDefaultImpl) newCol).isLoaded())
 143  
                     {
 144  
                         field.set(oldObj, oldCol);
 145  
                         continue;
 146  
                     }
 147  
                     oldCol.clear();
 148  
                 }
 149  
                 else
 150  
                 {
 151  
                     try
 152  
                     {
 153  
                         oldCol = (Collection) newCol.getClass().newInstance();
 154  
                     }
 155  
                     catch (Exception ex)
 156  
                     {
 157  
                         System.err.println("Cannot instantiate collection field which is neither Collection nor array: " + field);
 158  
                         ex.printStackTrace();
 159  
                         return newObj;
 160  
                     }
 161  
                 }
 162  
                 field.set(oldObj, oldCol);
 163  
                 for (Iterator it = newCol.iterator(); it.hasNext(); )
 164  
                 {
 165  
                     newRelObj = it.next();
 166  
                     newRelOid = new Identity(newRelObj, pb);
 167  
                     oldRelObj = cache.lookup(newRelOid);
 168  
                     if (oldRelObj == null)
 169  
                     {
 170  
                         oldRelObj = newRelObj;
 171  
                     }
 172  
                     oldCol.add(oldRelObj);
 173  
                 }
 174  
             }
 175  
             else if (field.getType().isArray())
 176  
             {
 177  
                 Object newArray = field.get(newObj);
 178  
                 int length = Array.getLength(newArray);
 179  
                 Object oldArray =
 180  
                         Array.newInstance(field.getType().getComponentType(), length);
 181  
 
 182  
                 for (int i = 0; i < length; i++)
 183  
                 {
 184  
                     newRelObj = Array.get(newArray, i);
 185  
                     newRelOid = new Identity(newRelObj, pb);
 186  
                     oldRelObj = cache.lookup(newRelOid);
 187  
                     if (oldRelObj == null)
 188  
                     {
 189  
                         throw new IllegalStateException("Related object not found for swizzle: " + newRelOid);
 190  
                     }
 191  
                     Array.set(oldArray, i, oldRelObj);
 192  
                 }
 193  
                 field.set(oldObj, oldArray);
 194  
             }
 195  
             else
 196  
             {
 197  
                 throw new IllegalStateException("Cannot swizzle collection field: " + field);
 198  
             }
 199  
         }
 200  
 
 201  
         return oldObj;
 202  
     }
 203  
 
 204  
     /**
 205  
      * @see org.apache.ojb.otm.swizzle.Swizzling#isSameInstance(Object, Object)
 206  
      */
 207  
     public boolean isSameInstance(Object swizzledObject, Object object)
 208  
     {
 209  
         return (swizzledObject == object);
 210  
     }
 211  
 
 212  
     /**
 213  
      * @see org.apache.ojb.otm.swizzle.Swizzling#getRealTarget(Object)
 214  
      */
 215  
     public Object getRealTarget(Object swizzledObject)
 216  
     {
 217  
         return swizzledObject;
 218  
     }
 219  
 
 220  
 }