Coverage Report - org.apache.ojb.broker.metadata.CollectionDescriptor
 
Classes in this File Line Coverage Branch Coverage Complexity
CollectionDescriptor
N/A
N/A
2.15
 
 1  
 package org.apache.ojb.broker.metadata;
 2  
 
 3  
 /* Copyright 2002-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  
 import java.util.Vector;
 22  
 
 23  
 import org.apache.commons.lang.SystemUtils;
 24  
 import org.apache.ojb.broker.PersistenceBrokerException;
 25  
 import org.apache.ojb.broker.accesslayer.QueryCustomizer;
 26  
 
 27  
 
 28  
 /**
 29  
  * mapping Description for member fields that are Collections
 30  
  * <br>
 31  
  * Note: Be careful when use references of this class or caching instances of this class,
 32  
  * because instances could become invalid (see {@link MetadataManager}).
 33  
  *
 34  
  * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
 35  
  * @version $Id: CollectionDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
 36  
  */
 37  
 public class CollectionDescriptor extends ObjectReferenceDescriptor
 38  
 {
 39  
     private static final long serialVersionUID = -8570280662286424937L;
 40  
 
 41  
     /**
 42  
      * Represents the type of the collection, if set to null,
 43  
      * a java.util.Vector will be used.
 44  
      * If set to a valid collection type it will be used to build typed collections.
 45  
      */
 46  
     private Class collectionClass = null;
 47  
     /**
 48  
      * the Collection of orderby Fields
 49  
      */
 50  
     private Collection m_orderby = new ArrayList();
 51  
     /**
 52  
      * For m:n related Classes this is the indirection table.
 53  
      */
 54  
     private String indirectionTable = null;
 55  
     private Vector fksToItemClass = null;
 56  
     private Vector fksToThisClass = null;
 57  
     private String[] fksToItemClassAry;
 58  
     private String[] fksToThisClassAry;
 59  
     private QueryCustomizer m_queryCustomizer;
 60  
     private Boolean m_hasProxyItems;
 61  
 
 62  
     public CollectionDescriptor(ClassDescriptor descriptor)
 63  
     {
 64  
         super(descriptor);
 65  
     }
 66  
 
 67  
     public String[] getFksToThisClass()
 68  
     {
 69  
         if (fksToThisClassAry == null)
 70  
         {
 71  
             fksToThisClassAry = (String[]) fksToThisClass.toArray(
 72  
                     new String[fksToThisClass.size()]);
 73  
         }
 74  
         return fksToThisClassAry;
 75  
     }
 76  
 
 77  
     public void setFksToThisClass(Vector fksToThisClass)
 78  
     {
 79  
         this.fksToThisClass = fksToThisClass;
 80  
         fksToThisClassAry = null;
 81  
     }
 82  
 
 83  
     /**
 84  
      * add a FK column pointing to This Class
 85  
      */
 86  
     public void addFkToThisClass(String column)
 87  
     {
 88  
         if (fksToThisClass == null)
 89  
         {
 90  
             fksToThisClass = new Vector();
 91  
         }
 92  
         fksToThisClass.add(column);
 93  
         fksToThisClassAry = null;
 94  
     }
 95  
 
 96  
     /**
 97  
      * add a FK column pointing to the item Class
 98  
      */
 99  
     public void addFkToItemClass(String column)
 100  
     {
 101  
         if (fksToItemClass == null)
 102  
         {
 103  
             fksToItemClass = new Vector();
 104  
         }
 105  
         fksToItemClass.add(column);
 106  
         fksToItemClassAry = null;
 107  
     }
 108  
 
 109  
     /**
 110  
      * returns the type of the collection.
 111  
      * @return java.lang.Class
 112  
      */
 113  
     public Class getCollectionClass()
 114  
     {
 115  
         return collectionClass;
 116  
     }
 117  
 
 118  
     /**
 119  
      * set the type of the collection
 120  
      * @param c the collection type
 121  
      */
 122  
     public void setCollectionClass(Class c)
 123  
     {
 124  
         collectionClass = c;
 125  
     }
 126  
 
 127  
     /**
 128  
      * Retrieve the classname of the collection.
 129  
      */
 130  
     public String getCollectionClassName()
 131  
     {
 132  
         return collectionClass != null ? collectionClass.getName() : null;
 133  
     }
 134  
 
 135  
     public String getIndirectionTable()
 136  
     {
 137  
         return indirectionTable;
 138  
     }
 139  
 
 140  
     public void setIndirectionTable(String indirectionTable)
 141  
     {
 142  
         this.indirectionTable = indirectionTable;
 143  
     }
 144  
 
 145  
     public String[] getFksToItemClass()
 146  
     {
 147  
         if (fksToItemClassAry == null)
 148  
         {
 149  
             fksToItemClassAry = (String[]) fksToItemClass.toArray(
 150  
                     new String[fksToItemClass.size()]);
 151  
         }
 152  
         return fksToItemClassAry;
 153  
     }
 154  
 
 155  
     public void setFksToItemClass(Vector fksToItemClass)
 156  
     {
 157  
         this.fksToItemClass = fksToItemClass;
 158  
         fksToItemClassAry = null;
 159  
     }
 160  
 
 161  
     public boolean isMtoNRelation()
 162  
     {
 163  
         return (indirectionTable != null);
 164  
     }
 165  
 
 166  
     /**
 167  
      * Adds a field for orderBy
 168  
      * @param  fieldName    The field name to be used
 169  
      * @param  sortAscending    true for ASCENDING, false for DESCENDING
 170  
      */
 171  
     public void addOrderBy(String fieldName, boolean sortAscending)
 172  
     {
 173  
         if (fieldName != null)
 174  
         {
 175  
             m_orderby.add(new FieldHelper(fieldName, sortAscending));
 176  
         }
 177  
     }
 178  
 
 179  
     /**
 180  
      * Returns the orderby Collection of Fields.
 181  
      * @return Collection
 182  
      */
 183  
     public Collection getOrderBy()
 184  
     {
 185  
         return m_orderby;
 186  
     }
 187  
 
 188  
     protected int getCascadeDeleteValue(String cascade)
 189  
     {
 190  
         if(cascade.equalsIgnoreCase("false") && isMtoNRelation())
 191  
         {
 192  
             /*
 193  
             "old" implementation does always delete entries in indirection table for
 194  
             m:n relations. For 1:n relations referenced objects are not touched.
 195  
             */
 196  
             return CASCADE_LINK;
 197  
         }
 198  
         return super.getCascadeDeleteValue(cascade);
 199  
     }
 200  
 
 201  
     /*
 202  
      * @see XmlCapable#toXML()
 203  
      */
 204  
     public String toXML()
 205  
     {
 206  
         RepositoryTags tags = RepositoryTags.getInstance();
 207  
         String eol = SystemUtils.LINE_SEPARATOR;
 208  
 
 209  
         // write opening tag
 210  
         String result = "      " + tags.getOpeningTagNonClosingById(COLLECTION_DESCRIPTOR) + eol;
 211  
 
 212  
         // write attributes
 213  
         // name
 214  
         result       += "        " + tags.getAttribute(FIELD_NAME,this.getAttributeName()) + eol;
 215  
 
 216  
         // collection class is optional
 217  
         if (getCollectionClassName() != null)
 218  
         {
 219  
             result       += "        " + tags.getAttribute(COLLECTION_CLASS,this.getCollectionClassName()) + eol;
 220  
         }
 221  
 
 222  
         // element-class-ref
 223  
          result       += "        " + tags.getAttribute(ITEMS_CLASS,this.getItemClassName()) + eol;
 224  
 
 225  
         // indirection-table is optional
 226  
         if (isMtoNRelation())
 227  
         {
 228  
              result += "        " + tags.getAttribute(INDIRECTION_TABLE,getIndirectionTable()) + eol;
 229  
         }
 230  
 
 231  
         // proxyReference is optional, disabled by default
 232  
         if (isLazy())
 233  
         {
 234  
             result       += "        " + tags.getAttribute(PROXY_REFERENCE,"true") + eol;
 235  
             result       += "        " + tags.getAttribute(PROXY_PREFETCHING_LIMIT, "" + this.getProxyPrefetchingLimit()) + eol;
 236  
         }
 237  
 
 238  
         //reference refresh is optional, disabled by default
 239  
         if (isRefresh())
 240  
         {
 241  
              result       += "        " + tags.getAttribute(REFRESH,"true") + eol;
 242  
         }
 243  
 
 244  
         //auto retrieve
 245  
         result += "        " + tags.getAttribute(AUTO_RETRIEVE, "" + getCascadeRetrieve()) + eol;
 246  
 
 247  
         //auto update
 248  
         result += "        " + tags.getAttribute(AUTO_UPDATE, getCascadeAsString(getCascadingStore())) + eol;
 249  
 
 250  
         //auto delete
 251  
         result += "        " + tags.getAttribute(AUTO_DELETE, getCascadeAsString(getCascadingDelete())) + eol;
 252  
 
 253  
         //otm-dependent is optional, disabled by default
 254  
         if (getOtmDependent())
 255  
         {
 256  
             result += "        " + tags.getAttribute(OTM_DEPENDENT, "true") + eol;
 257  
         }
 258  
 
 259  
         // close opening tag
 260  
         result       += "      >" + eol;
 261  
 
 262  
         // write elements
 263  
          // inverse fk elements
 264  
         for (int i=0;i<getForeignKeyFields().size();i++)
 265  
         {
 266  
         Object obj = getForeignKeyFields().get(i);
 267  
         if (obj instanceof Integer)
 268  
         {
 269  
                 String fkId = obj.toString();
 270  
             result += "        " + tags.getOpeningTagNonClosingById(INVERSE_FK) + " ";
 271  
                 result += tags.getAttribute(FIELD_ID_REF, fkId) + "/>" + eol;
 272  
         }
 273  
         else
 274  
         {
 275  
                 String fk = (String) obj;
 276  
             result += "        " + tags.getOpeningTagNonClosingById(INVERSE_FK) + " ";
 277  
                 result += tags.getAttribute(FIELD_REF, fk) + "/>" + eol;
 278  
         }
 279  
         }
 280  
 
 281  
         // write optional M:N elements
 282  
         // m:n relationship settings, optional
 283  
         if (isMtoNRelation())
 284  
         {
 285  
             // foreign keys to this class
 286  
              for (int i=0;i<getFksToThisClass().length;i++)
 287  
              {
 288  
                 String fkId = getFksToThisClass()[i];
 289  
                 result += "        " + tags.getOpeningTagNonClosingById(FK_POINTING_TO_THIS_CLASS) + " ";
 290  
                 result += tags.getAttribute(COLUMN_NAME, fkId) + "/>" + eol;
 291  
              }
 292  
 
 293  
             // foreign keys to item class
 294  
              for (int i=0;i<getFksToItemClass().length;i++)
 295  
              {
 296  
                 String fkId = getFksToItemClass()[i];
 297  
                 result += "        " + tags.getOpeningTagNonClosingById(FK_POINTING_TO_ITEMS_CLASS) + " ";
 298  
                 result += tags.getAttribute(COLUMN_NAME, fkId) + "/>" + eol;
 299  
              }
 300  
         }
 301  
 
 302  
         // closing tag
 303  
         result       += "      " + tags.getClosingTagById(COLLECTION_DESCRIPTOR) + eol;
 304  
         return result;
 305  
     }
 306  
 
 307  
         /**
 308  
          * @return QueryCustomizer
 309  
          */
 310  
         public QueryCustomizer getQueryCustomizer()
 311  
         {
 312  
                 return m_queryCustomizer;
 313  
         }
 314  
 
 315  
         /**
 316  
          * Sets the queryCustomizer.
 317  
          * @param queryCustomizer The queryCustomizer to set
 318  
          */
 319  
         public void setQueryCustomizer(QueryCustomizer queryCustomizer)
 320  
         {
 321  
                 m_queryCustomizer = queryCustomizer;
 322  
         }
 323  
 
 324  
     public boolean hasProxyItems() throws PersistenceBrokerException
 325  
     {
 326  
         if (m_hasProxyItems == null)
 327  
         {
 328  
             DescriptorRepository repo = getClassDescriptor().getRepository();
 329  
             ClassDescriptor cld = repo.getDescriptorFor(getItemClass());
 330  
             if (cld.getProxyClass() != null)
 331  
             {
 332  
                 m_hasProxyItems = Boolean.TRUE;
 333  
             }
 334  
             else
 335  
             {
 336  
                 Collection extents = cld.getExtentClasses();
 337  
                 m_hasProxyItems = Boolean.FALSE;
 338  
                 for (Iterator it = extents.iterator(); it.hasNext(); )
 339  
                 {
 340  
                     Class ext = (Class) it.next();
 341  
                     ClassDescriptor cldExt = repo.getDescriptorFor(ext);
 342  
                     if (cldExt.getProxyClass() != null)
 343  
                     {
 344  
                         m_hasProxyItems = Boolean.TRUE;
 345  
                         break;
 346  
                     }
 347  
                 }
 348  
             }
 349  
         }
 350  
 
 351  
         return (m_hasProxyItems.booleanValue());
 352  
     }
 353  
 }