Clover coverage report - Drools - 2.0-rc2
Coverage timestamp: Wed May 11 2005 07:12:26 BST
file stats: LOC: 561   Methods: 23
NCLOC: 226   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
CompositeCollection.java 21.4% 26.9% 21.7% 24.5%
coverage coverage
 1    /*
 2    * Copyright 2001-2004 The Apache Software Foundation
 3    *
 4    * Licensed under the Apache License, Version 2.0 (the "License");
 5    * you may not use this file except in compliance with the License.
 6    * You may obtain a copy of the License at
 7    *
 8    * http://www.apache.org/licenses/LICENSE-2.0
 9    *
 10    * Unless required by applicable law or agreed to in writing, software
 11    * distributed under the License is distributed on an "AS IS" BASIS,
 12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13    * See the License for the specific language governing permissions and
 14    * limitations under the License.
 15    */
 16    package org.drools.util;
 17   
 18    import java.lang.reflect.Array;
 19    import java.util.ArrayList;
 20    import java.util.Arrays;
 21    import java.util.Collection;
 22    import java.util.Collections;
 23    import java.util.Iterator;
 24   
 25    /**
 26    * Decorates a collection of other collections to provide a single unified view.
 27    * <p>
 28    * Changes made to this collection will actually be made on the decorated
 29    * collection. Add and remove operations require the use of a pluggable
 30    * strategy. If no strategy is provided then add and remove are unsupported.
 31    *
 32    * @since Commons Collections 3.0
 33    * @version $Revision: 1.5 $ $Date: 2004/12/06 01:30:38 $
 34    *
 35    * @author Brian McCallister
 36    * @author Stephen Colebourne
 37    * @author Phil Steitz
 38    */
 39    public class CompositeCollection
 40    implements
 41    Collection
 42    {
 43   
 44    /** CollectionMutator to handle changes to the collection */
 45    protected CollectionMutator mutator;
 46   
 47    /** Collections in the composite */
 48    protected Collection[] all;
 49   
 50    /**
 51    * Create an empty CompositeCollection.
 52    */
 53  24 public CompositeCollection()
 54    {
 55  24 super( );
 56  24 this.all = new Collection[0];
 57    }
 58   
 59    /**
 60    * Create a Composite Collection with only coll composited.
 61    *
 62    * @param coll
 63    * a collection to decorate
 64    */
 65  0 public CompositeCollection(Collection coll)
 66    {
 67  0 this( );
 68  0 this.addComposited( coll );
 69    }
 70   
 71    /**
 72    * Create a CompositeCollection with colls as the initial list of composited
 73    * collections.
 74    *
 75    * @param colls
 76    * an array of collections to decorate
 77    */
 78  0 public CompositeCollection(Collection[] colls)
 79    {
 80  0 this( );
 81  0 this.addComposited( colls );
 82    }
 83   
 84    // -----------------------------------------------------------------------
 85    /**
 86    * Gets the size of this composite collection.
 87    * <p>
 88    * This implementation calls <code>size()</code> on each collection.
 89    *
 90    * @return total number of elements in all contained containers
 91    */
 92  47 public int size()
 93    {
 94  47 int size = 0;
 95  47 for ( int i = this.all.length - 1; i >= 0; i-- )
 96    {
 97  47 size += this.all[i].size( );
 98    }
 99  47 return size;
 100    }
 101   
 102    /**
 103    * Checks whether this composite collection is empty.
 104    * <p>
 105    * This implementation calls <code>isEmpty()</code> on each collection.
 106    *
 107    * @return true if all of the contained collections are empty
 108    */
 109  0 public boolean isEmpty()
 110    {
 111  0 for ( int i = this.all.length - 1; i >= 0; i-- )
 112    {
 113  0 if ( this.all[i].isEmpty( ) == false )
 114    {
 115  0 return false;
 116    }
 117    }
 118  0 return true;
 119    }
 120   
 121    /**
 122    * Checks whether this composite collection contains the object.
 123    * <p>
 124    * This implementation calls <code>contains()</code> on each collection.
 125    *
 126    * @param obj
 127    * the object to search for
 128    * @return true if obj is contained in any of the contained collections
 129    */
 130  0 public boolean contains(Object obj)
 131    {
 132  0 for ( int i = this.all.length - 1; i >= 0; i-- )
 133    {
 134  0 if ( this.all[i].contains( obj ) )
 135    {
 136  0 return true;
 137    }
 138    }
 139  0 return false;
 140    }
 141   
 142    /**
 143    * Gets an iterator over all the collections in this composite.
 144    * <p>
 145    * This implementation uses an <code>IteratorChain</code>.
 146    *
 147    * @return an <code>IteratorChain</code> instance which supports
 148    * <code>remove()</code>. Iteration occurs over contained
 149    * collections in the order they were added, but this behavior
 150    * should not be relied upon.
 151    * @see IteratorChain
 152    */
 153  0 public Iterator iterator()
 154    {
 155  0 if ( this.all.length == 0 )
 156    {
 157  0 return Collections.EMPTY_LIST.iterator( );
 158    }
 159  0 IteratorChain chain = new IteratorChain( );
 160  0 for ( int i = 0; i < this.all.length; ++i )
 161    {
 162  0 chain.addIterator( this.all[i].iterator( ) );
 163    }
 164  0 return chain;
 165    }
 166   
 167    /**
 168    * Returns an array containing all of the elements in this composite.
 169    *
 170    * @return an object array of all the elements in the collection
 171    */
 172  0 public Object[] toArray()
 173    {
 174  0 final Object[] result = new Object[this.size( )];
 175  0 int i = 0;
 176  0 for ( Iterator it = this.iterator( ); it.hasNext( ); i++ )
 177    {
 178  0 result[i] = it.next( );
 179    }
 180  0 return result;
 181    }
 182   
 183    /**
 184    * Returns an object array, populating the supplied array if possible. See
 185    * <code>Collection</code> interface for full details.
 186    *
 187    * @param array
 188    * the array to use, populating if possible
 189    * @return an array of all the elements in the collection
 190    */
 191  23 public Object[] toArray(Object[] array)
 192    {
 193  23 int size = this.size( );
 194  23 Object[] result;
 195  23 if ( array.length >= size )
 196    {
 197  23 result = array;
 198    }
 199    else
 200    {
 201  0 result = (Object[]) Array.newInstance( array.getClass( ).getComponentType( ),
 202    size );
 203    }
 204   
 205  23 int offset = 0;
 206  23 for ( int i = 0; i < this.all.length; ++i )
 207    {
 208  23 for ( Iterator it = this.all[i].iterator( ); it.hasNext( ); )
 209    {
 210  821 result[offset++] = it.next( );
 211    }
 212    }
 213  23 if ( result.length > size )
 214    {
 215  5 result[size] = null;
 216    }
 217  23 return result;
 218    }
 219   
 220    /**
 221    * Adds an object to the collection, throwing UnsupportedOperationException
 222    * unless a CollectionMutator strategy is specified.
 223    *
 224    * @param obj
 225    * the object to add
 226    * @return true if the collection was modified
 227    * @throws UnsupportedOperationException
 228    * if CollectionMutator hasn't been set
 229    * @throws UnsupportedOperationException
 230    * if add is unsupported
 231    * @throws ClassCastException
 232    * if the object cannot be added due to its type
 233    * @throws NullPointerException
 234    * if the object cannot be added because its null
 235    * @throws IllegalArgumentException
 236    * if the object cannot be added
 237    */
 238  0 public boolean add(Object obj)
 239    {
 240  0 if ( this.mutator == null )
 241    {
 242  0 throw new UnsupportedOperationException( "add() is not supported on CompositeCollection without a CollectionMutator strategy" );
 243    }
 244  0 return this.mutator.add( this,
 245    this.all,
 246    obj );
 247    }
 248   
 249    /**
 250    * Removes an object from the collection, throwing
 251    * UnsupportedOperationException unless a CollectionMutator strategy is
 252    * specified.
 253    *
 254    * @param obj
 255    * the object being removed
 256    * @return true if the collection is changed
 257    * @throws UnsupportedOperationException
 258    * if removed is unsupported
 259    * @throws ClassCastException
 260    * if the object cannot be removed due to its type
 261    * @throws NullPointerException
 262    * if the object cannot be removed because its null
 263    * @throws IllegalArgumentException
 264    * if the object cannot be removed
 265    */
 266  0 public boolean remove(Object obj)
 267    {
 268  0 if ( this.mutator == null )
 269    {
 270  0 throw new UnsupportedOperationException( "remove() is not supported on CompositeCollection without a CollectionMutator strategy" );
 271    }
 272  0 return this.mutator.remove( this,
 273    this.all,
 274    obj );
 275    }
 276   
 277    /**
 278    * Checks whether this composite contains all the elements in the specified
 279    * collection.
 280    * <p>
 281    * This implementation calls <code>contains()</code> for each element in
 282    * the specified collection.
 283    *
 284    * @param coll
 285    * the collection to check for
 286    * @return true if all elements contained
 287    */
 288  0 public boolean containsAll(Collection coll)
 289    {
 290  0 for ( Iterator it = coll.iterator( ); it.hasNext( ); )
 291    {
 292  0 if ( this.contains( it.next( ) ) == false )
 293    {
 294  0 return false;
 295    }
 296    }
 297  0 return true;
 298    }
 299   
 300    /**
 301    * Adds a collection of elements to this collection, throwing
 302    * UnsupportedOperationException unless a CollectionMutator strategy is
 303    * specified.
 304    *
 305    * @param coll
 306    * the collection to add
 307    * @return true if the collection was modified
 308    * @throws UnsupportedOperationException
 309    * if CollectionMutator hasn't been set
 310    * @throws UnsupportedOperationException
 311    * if add is unsupported
 312    * @throws ClassCastException
 313    * if the object cannot be added due to its type
 314    * @throws NullPointerException
 315    * if the object cannot be added because its null
 316    * @throws IllegalArgumentException
 317    * if the object cannot be added
 318    */
 319  0 public boolean addAll(Collection coll)
 320    {
 321  0 if ( this.mutator == null )
 322    {
 323  0 throw new UnsupportedOperationException( "addAll() is not supported on CompositeCollection without a CollectionMutator strategy" );
 324    }
 325  0 return this.mutator.addAll( this,
 326    this.all,
 327    coll );
 328    }
 329   
 330    /**
 331    * Removes the elements in the specified collection from this composite
 332    * collection.
 333    * <p>
 334    * This implementation calls <code>removeAll</code> on each collection.
 335    *
 336    * @param coll
 337    * the collection to remove
 338    * @return true if the collection was modified
 339    * @throws UnsupportedOperationException
 340    * if removeAll is unsupported
 341    */
 342  0 public boolean removeAll(Collection coll)
 343    {
 344  0 if ( coll.isEmpty( ) )
 345    {
 346  0 return false;
 347    }
 348   
 349  0 boolean changed = false;
 350  0 for ( int i = this.all.length - 1; i >= 0; i-- )
 351    {
 352  0 changed |= this.all[i].removeAll( coll );
 353    }
 354  0 return changed;
 355    }
 356   
 357    /**
 358    * Retains all the elements in the specified collection in this composite
 359    * collection, removing all others.
 360    * <p>
 361    * This implementation calls <code>retainAll()</code> on each collection.
 362    *
 363    * @param coll
 364    * the collection to remove
 365    * @return true if the collection was modified
 366    * @throws UnsupportedOperationException
 367    * if retainAll is unsupported
 368    */
 369  0 public boolean retainAll(final Collection coll)
 370    {
 371  0 boolean changed = false;
 372  0 for ( int i = this.all.length - 1; i >= 0; i-- )
 373    {
 374  0 changed = (this.all[i].retainAll( coll ) || changed);
 375    }
 376  0 return changed;
 377    }
 378   
 379    /**
 380    * Removes all of the elements from this collection .
 381    * <p>
 382    * This implementation calls <code>clear()</code> on each collection.
 383    *
 384    * @throws UnsupportedOperationException
 385    * if clear is unsupported
 386    */
 387  0 public void clear()
 388    {
 389  0 for ( int i = 0; i < this.all.length; ++i )
 390    {
 391  0 this.all[i].clear( );
 392    }
 393    }
 394   
 395    // -----------------------------------------------------------------------
 396    /**
 397    * Specify a CollectionMutator strategy instance to handle changes.
 398    *
 399    * @param mutator
 400    * the mutator to use
 401    */
 402  0 public void setMutator(CollectionMutator mutator)
 403    {
 404  0 this.mutator = mutator;
 405    }
 406   
 407    /**
 408    * Add these Collections to the list of collections in this composite
 409    *
 410    * @param comps
 411    * Collections to be appended to the composite
 412    */
 413  24 public void addComposited(Collection[] comps)
 414    {
 415  24 ArrayList list = new ArrayList( Arrays.asList( this.all ) );
 416  24 list.addAll( Arrays.asList( comps ) );
 417  24 all = (Collection[]) list.toArray( new Collection[list.size( )] );
 418    }
 419   
 420    /**
 421    * Add an additional collection to this composite.
 422    *
 423    * @param c
 424    * the collection to add
 425    */
 426  24 public void addComposited(Collection c)
 427    {
 428  24 this.addComposited( new Collection[]{c} );
 429    }
 430   
 431    /**
 432    * Add two additional collections to this composite.
 433    *
 434    * @param c
 435    * the first collection to add
 436    * @param d
 437    * the second collection to add
 438    */
 439  0 public void addComposited(Collection c,
 440    Collection d)
 441    {
 442  0 this.addComposited( new Collection[]{c, d} );
 443    }
 444   
 445    /**
 446    * Removes a collection from the those being decorated in this composite.
 447    *
 448    * @param coll
 449    * collection to be removed
 450    */
 451  0 public void removeComposited(Collection coll)
 452    {
 453  0 ArrayList list = new ArrayList( this.all.length );
 454  0 list.addAll( Arrays.asList( this.all ) );
 455  0 list.remove( coll );
 456  0 this.all = (Collection[]) list.toArray( new Collection[list.size( )] );
 457    }
 458   
 459    /**
 460    * Returns a new collection containing all of the elements
 461    *
 462    * @return A new ArrayList containing all of the elements in this composite.
 463    * The new collection is <i>not </i> backed by this composite.
 464    */
 465  0 public Collection toCollection()
 466    {
 467  0 return new ArrayList( this );
 468    }
 469   
 470    /**
 471    * Gets the collections being decorated.
 472    *
 473    * @return Unmodifiable collection of all collections in this composite.
 474    */
 475  0 public Collection getCollections()
 476    {
 477  0 return Collections.unmodifiableList( Arrays.asList( this.all ) );
 478    }
 479   
 480    // -----------------------------------------------------------------------
 481    /**
 482    * Pluggable strategy to handle changes to the composite.
 483    */
 484    public interface CollectionMutator
 485    {
 486   
 487    /**
 488    * Called when an object is to be added to the composite.
 489    *
 490    * @param composite
 491    * the CompositeCollection being changed
 492    * @param collections
 493    * all of the Collection instances in this
 494    * CompositeCollection
 495    * @param obj
 496    * the object being added
 497    * @return true if the collection is changed
 498    * @throws UnsupportedOperationException
 499    * if add is unsupported
 500    * @throws ClassCastException
 501    * if the object cannot be added due to its type
 502    * @throws NullPointerException
 503    * if the object cannot be added because its null
 504    * @throws IllegalArgumentException
 505    * if the object cannot be added
 506    */
 507    public boolean add(CompositeCollection composite,
 508    Collection[] collections,
 509    Object obj);
 510   
 511    /**
 512    * Called when a collection is to be added to the composite.
 513    *
 514    * @param composite
 515    * the CompositeCollection being changed
 516    * @param collections
 517    * all of the Collection instances in this
 518    * CompositeCollection
 519    * @param coll
 520    * the collection being added
 521    * @return true if the collection is changed
 522    * @throws UnsupportedOperationException
 523    * if add is unsupported
 524    * @throws ClassCastException
 525    * if the object cannot be added due to its type
 526    * @throws NullPointerException
 527    * if the object cannot be added because its null
 528    * @throws IllegalArgumentException
 529    * if the object cannot be added
 530    */
 531    public boolean addAll(CompositeCollection composite,
 532    Collection[] collections,
 533    Collection coll);
 534   
 535    /**
 536    * Called when an object is to be removed to the composite.
 537    *
 538    * @param composite
 539    * the CompositeCollection being changed
 540    * @param collections
 541    * all of the Collection instances in this
 542    * CompositeCollection
 543    * @param obj
 544    * the object being removed
 545    * @return true if the collection is changed
 546    * @throws UnsupportedOperationException
 547    * if removed is unsupported
 548    * @throws ClassCastException
 549    * if the object cannot be removed due to its type
 550    * @throws NullPointerException
 551    * if the object cannot be removed because its null
 552    * @throws IllegalArgumentException
 553    * if the object cannot be removed
 554    */
 555    public boolean remove(CompositeCollection composite,
 556    Collection[] collections,
 557    Object obj);
 558   
 559    }
 560   
 561    }