Coverage Report - org.apache.ojb.broker.accesslayer.BasePrefetcher
 
Classes in this File Line Coverage Branch Coverage Complexity
BasePrefetcher
N/A
N/A
1.8
 
 1  
 package org.apache.ojb.broker.accesslayer;
 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.util.ArrayList;
 19  
 import java.util.Collection;
 20  
 import java.util.Iterator;
 21  
 
 22  
 import org.apache.ojb.broker.Identity;
 23  
 import org.apache.ojb.broker.PersistenceBrokerFactory;
 24  
 import org.apache.ojb.broker.core.PersistenceBrokerConfiguration;
 25  
 import org.apache.ojb.broker.core.PersistenceBrokerImpl;
 26  
 import org.apache.ojb.broker.metadata.ClassDescriptor;
 27  
 import org.apache.ojb.broker.metadata.DescriptorRepository;
 28  
 import org.apache.ojb.broker.metadata.FieldDescriptor;
 29  
 import org.apache.ojb.broker.query.Criteria;
 30  
 import org.apache.ojb.broker.query.Query;
 31  
 import org.apache.ojb.broker.query.QueryByCriteria;
 32  
 import org.apache.ojb.broker.query.QueryFactory;
 33  
 import org.apache.ojb.broker.util.configuration.ConfigurationException;
 34  
 import org.apache.ojb.broker.util.logging.Logger;
 35  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 36  
 
 37  
 /**
 38  
  * Abstract Prefetcher.
 39  
  * @author <a href="mailto:olegnitz@apache.org">Oleg Nitz</a>
 40  
  * @version $Id: BasePrefetcher.java,v 1.1 2007-08-24 22:17:30 ewestfal Exp $
 41  
  */
 42  
 public abstract class BasePrefetcher implements RelationshipPrefetcher
 43  
 {
 44  
     /** The numer of columns to query for. */
 45  
     protected static final int IN_LIMIT = getPrefetchInLimit();
 46  
 
 47  
     private Logger logger;
 48  
     private PersistenceBrokerImpl broker;
 49  
     /** Class descriptor for the item type. */ 
 50  
     protected ClassDescriptor itemClassDesc;
 51  
     /** Maximum number of pk's in one query. */ 
 52  
     protected final int pkLimit;
 53  
 
 54  
     /**
 55  
      * Returns the number of column to query for, from the configuration.
 56  
      * 
 57  
      * @return The prefetch limit
 58  
      */
 59  
     private static int getPrefetchInLimit()
 60  
     {
 61  
         try
 62  
         {
 63  
             PersistenceBrokerConfiguration config = (PersistenceBrokerConfiguration) PersistenceBrokerFactory.getConfigurator().getConfigurationFor(null);
 64  
 
 65  
             return config.getSqlInLimit();
 66  
         }
 67  
         catch (ConfigurationException e)
 68  
         {
 69  
             return 200;
 70  
         }
 71  
     }
 72  
 
 73  
     /**
 74  
      * Constructor for BasePrefetcher.
 75  
      */
 76  
     public BasePrefetcher(PersistenceBrokerImpl aBroker, Class anItemClass)
 77  
     {
 78  
         super();
 79  
         broker = aBroker;
 80  
         itemClassDesc = aBroker.getDescriptorRepository().getDescriptorFor(anItemClass);
 81  
         logger = LoggerFactory.getLogger(this.getClass());
 82  
         pkLimit = getPrefetchInLimit() / getItemClassDescriptor().getPkFields().length;
 83  
     }
 84  
 
 85  
     /**
 86  
      * The limit of objects loaded by one SQL query
 87  
      */
 88  
     public int getLimit()
 89  
     {
 90  
         return pkLimit;
 91  
     }
 92  
 
 93  
     /**
 94  
      * associate the batched Children with their owner object <br>
 95  
      */
 96  
     protected abstract void associateBatched(Collection owners, Collection children);
 97  
 
 98  
     /**
 99  
     * @see org.apache.ojb.broker.accesslayer.RelationshipPrefetcher#prefetchRelationship(Collection)
 100  
     */
 101  
     public void prefetchRelationship(Collection owners)
 102  
     {
 103  
         Query queries[];
 104  
         Collection children = new ArrayList();
 105  
 
 106  
         queries = buildPrefetchQueries(owners, children);
 107  
 
 108  
         for (int i = 0; i < queries.length; i++)
 109  
         {
 110  
             Iterator iter = getBroker().getIteratorByQuery(queries[i]);
 111  
             while (iter.hasNext())
 112  
             {
 113  
                 children.add(iter.next());
 114  
             }
 115  
         }
 116  
 
 117  
         // BRJ: performRetrieval of childrens references BEFORE associating with owners
 118  
         // TODO: this is a quick fix ! 
 119  
         getBroker().getReferenceBroker().performRetrievalTasks();
 120  
         
 121  
         associateBatched(owners, children);
 122  
     }
 123  
 
 124  
     
 125  
     protected QueryByCriteria buildPrefetchQuery(Collection ids, FieldDescriptor[] fields)
 126  
     {
 127  
         return buildPrefetchQuery(getItemClassDescriptor().getClassOfObject(), ids, fields);
 128  
     }
 129  
 
 130  
     
 131  
     /**
 132  
      * 
 133  
      * @param ids collection of identities
 134  
      * @param fields
 135  
      * @return
 136  
      */
 137  
     protected Criteria buildPrefetchCriteria(Collection ids, FieldDescriptor[] fields)
 138  
     {
 139  
         if (fields.length == 1)
 140  
         {
 141  
             return buildPrefetchCriteriaSingleKey(ids, fields[0]);
 142  
         }
 143  
         else
 144  
         {
 145  
             return buildPrefetchCriteriaMultipleKeys(ids, fields);
 146  
         }
 147  
         
 148  
     }
 149  
    
 150  
     /**
 151  
      * 
 152  
      * @param clazz
 153  
      * @param ids collection of identities
 154  
      * @param fields
 155  
      * @return
 156  
      */
 157  
     protected QueryByCriteria buildPrefetchQuery(Class clazz, Collection ids, FieldDescriptor[] fields)
 158  
     {
 159  
         return QueryFactory.newQuery(clazz, buildPrefetchCriteria(ids, fields));
 160  
     }
 161  
 
 162  
     /**
 163  
      * Build the Criteria using IN(...) for single keys
 164  
      * @param ids collection of identities
 165  
      * @param field
 166  
      * @return Criteria
 167  
      */
 168  
     private Criteria buildPrefetchCriteriaSingleKey(Collection ids, FieldDescriptor field)
 169  
     {
 170  
         Criteria crit = new Criteria();
 171  
         ArrayList values = new ArrayList(ids.size());
 172  
         Iterator iter = ids.iterator();
 173  
         Identity id;
 174  
 
 175  
         while (iter.hasNext())
 176  
         {
 177  
             id = (Identity) iter.next();
 178  
             values.add(id.getPrimaryKeyValues()[0]);
 179  
         }
 180  
 
 181  
         switch (values.size())
 182  
         {
 183  
             case 0:
 184  
                 break;
 185  
             case 1:
 186  
                 crit.addEqualTo(field.getAttributeName(), values.get(0));
 187  
                 break;
 188  
             default:
 189  
                 // create IN (...) for the single key field
 190  
                 crit.addIn(field.getAttributeName(), values);
 191  
                 break;
 192  
         }
 193  
 
 194  
         return crit;
 195  
     }
 196  
 
 197  
     /**
 198  
      * Build the Criteria using multiple ORs
 199  
      * @param ids collection of identities
 200  
      * @param fields
 201  
      * @return Criteria
 202  
      */
 203  
     private Criteria buildPrefetchCriteriaMultipleKeys(Collection ids, FieldDescriptor fields[])
 204  
     {
 205  
         Criteria crit = new Criteria();
 206  
         Iterator iter = ids.iterator();
 207  
         Object[] val;
 208  
         Identity id;
 209  
 
 210  
         while (iter.hasNext())
 211  
         {
 212  
             Criteria c = new Criteria();
 213  
             id = (Identity) iter.next();
 214  
             val = id.getPrimaryKeyValues();
 215  
             for (int i = 0; i < val.length; i++)
 216  
             {
 217  
                 if (val[i] == null)
 218  
                 {
 219  
                     c.addIsNull(fields[i].getAttributeName());
 220  
                 }
 221  
                 else
 222  
                 {
 223  
                     c.addEqualTo(fields[i].getAttributeName(), val[i]);
 224  
                 }
 225  
             }
 226  
             crit.addOrCriteria(c);
 227  
         }
 228  
 
 229  
         return crit;
 230  
     }
 231  
 
 232  
     /**
 233  
      * Return the DescriptorRepository
 234  
      */
 235  
     protected DescriptorRepository getDescriptorRepository()
 236  
     {
 237  
         return getBroker().getDescriptorRepository();
 238  
     }
 239  
 
 240  
     /**
 241  
      * Returns the ClassDescriptor of the item Class
 242  
      * @return ClassDescriptor
 243  
      */
 244  
     public ClassDescriptor getItemClassDescriptor()
 245  
     {
 246  
         return itemClassDesc;
 247  
     }
 248  
 
 249  
     protected abstract Query[] buildPrefetchQueries(Collection owners, Collection children);
 250  
 
 251  
     /**
 252  
      * Returns the broker.
 253  
      * @return PersistenceBrokerImpl
 254  
      */
 255  
     protected PersistenceBrokerImpl getBroker()
 256  
     {
 257  
         return broker;
 258  
     }
 259  
 
 260  
     /**
 261  
      * Returns the logger.
 262  
      * @return Logger
 263  
      */
 264  
     protected Logger getLogger()
 265  
     {
 266  
         return logger;
 267  
     }
 268  
 }