001: /*
002: * Copyright 2003-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.collection;
017:
018: import java.util.Collection;
019: import java.util.Iterator;
020:
021: import org.apache.commons.collections.Predicate;
022:
023: /**
024: * Decorates another <code>Collection</code> to validate that additions
025: * match a specified predicate.
026: * <p>
027: * This collection exists to provide validation for the decorated collection.
028: * It is normally created to decorate an empty collection.
029: * If an object cannot be added to the collection, an IllegalArgumentException is thrown.
030: * <p>
031: * One usage would be to ensure that no null entries are added to the collection.
032: * <pre>Collection coll = PredicatedCollection.decorate(new ArrayList(), NotNullPredicate.INSTANCE);</pre>
033: * <p>
034: * This class is Serializable from Commons Collections 3.1.
035: *
036: * @since Commons Collections 3.0
037: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
038: *
039: * @author Stephen Colebourne
040: * @author Paul Jack
041: */
042: public class PredicatedCollection extends
043: AbstractSerializableCollectionDecorator {
044:
045: /** Serialization version */
046: private static final long serialVersionUID = -5259182142076705162L;
047:
048: /** The predicate to use */
049: protected final Predicate predicate;
050:
051: /**
052: * Factory method to create a predicated (validating) collection.
053: * <p>
054: * If there are any elements already in the collection being decorated, they
055: * are validated.
056: *
057: * @param coll the collection to decorate, must not be null
058: * @param predicate the predicate to use for validation, must not be null
059: * @return a new predicated collection
060: * @throws IllegalArgumentException if collection or predicate is null
061: * @throws IllegalArgumentException if the collection contains invalid elements
062: */
063: public static Collection decorate(Collection coll,
064: Predicate predicate) {
065: return new PredicatedCollection(coll, predicate);
066: }
067:
068: //-----------------------------------------------------------------------
069: /**
070: * Constructor that wraps (not copies).
071: * <p>
072: * If there are any elements already in the collection being decorated, they
073: * are validated.
074: *
075: * @param coll the collection to decorate, must not be null
076: * @param predicate the predicate to use for validation, must not be null
077: * @throws IllegalArgumentException if collection or predicate is null
078: * @throws IllegalArgumentException if the collection contains invalid elements
079: */
080: protected PredicatedCollection(Collection coll, Predicate predicate) {
081: super (coll);
082: if (predicate == null) {
083: throw new IllegalArgumentException(
084: "Predicate must not be null");
085: }
086: this .predicate = predicate;
087: for (Iterator it = coll.iterator(); it.hasNext();) {
088: validate(it.next());
089: }
090: }
091:
092: /**
093: * Validates the object being added to ensure it matches the predicate.
094: * <p>
095: * The predicate itself should not throw an exception, but return false to
096: * indicate that the object cannot be added.
097: *
098: * @param object the object being added
099: * @throws IllegalArgumentException if the add is invalid
100: */
101: protected void validate(Object object) {
102: if (predicate.evaluate(object) == false) {
103: throw new IllegalArgumentException("Cannot add Object '"
104: + object + "' - Predicate rejected it");
105: }
106: }
107:
108: //-----------------------------------------------------------------------
109: /**
110: * Override to validate the object being added to ensure it matches
111: * the predicate.
112: *
113: * @param object the object being added
114: * @return the result of adding to the underlying collection
115: * @throws IllegalArgumentException if the add is invalid
116: */
117: public boolean add(Object object) {
118: validate(object);
119: return getCollection().add(object);
120: }
121:
122: /**
123: * Override to validate the objects being added to ensure they match
124: * the predicate. If any one fails, no update is made to the underlying
125: * collection.
126: *
127: * @param coll the collection being added
128: * @return the result of adding to the underlying collection
129: * @throws IllegalArgumentException if the add is invalid
130: */
131: public boolean addAll(Collection coll) {
132: for (Iterator it = coll.iterator(); it.hasNext();) {
133: validate(it.next());
134: }
135: return getCollection().addAll(coll);
136: }
137:
138: }
|