KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > lang > Sequence


1 /*
2  $Id: Sequence.java,v 1.3 2004/02/24 23:03:48 jstrachan Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11     statements and notices. Redistributions must also contain a
12     copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15     above copyright notice, this list of conditions and the
16     following disclaimer in the documentation and/or other
17     materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20     products derived from this Software without prior written
21     permission of The Codehaus. For written permission,
22     please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25     nor may "groovy" appear in their names without prior written
26     permission of The Codehaus. "groovy" is a registered
27     trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30     http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46 package groovy.lang;
47
48 import java.util.ArrayList JavaDoc;
49 import java.util.Collection JavaDoc;
50 import java.util.Iterator JavaDoc;
51 import java.util.List JavaDoc;
52
53 import org.codehaus.groovy.runtime.InvokerHelper;
54
55 /**
56  * Represents a sequence of objects which represents zero or many instances of
57  * of objects of a given type. The type can be ommitted in which case any type of
58  * object can be added.
59  *
60  * @author <a HREF="mailto:james@coredevelopers.net">James Strachan</a>
61  * @version $Revision: 1.3 $
62  */

63 public class Sequence extends ArrayList JavaDoc implements GroovyObject {
64
65     private MetaClass metaClass = InvokerHelper.getMetaClass(this);
66     private Class JavaDoc type;
67     private int hashCode;
68
69     public Sequence() {
70         this(null);
71     }
72
73     public Sequence(Class JavaDoc type) {
74         this.type = type;
75     }
76
77     public Sequence(Class JavaDoc type, List JavaDoc content) {
78         super(content.size());
79         this.type = type;
80         addAll(content);
81     }
82
83     /**
84      * Sets the contents of this sequence to that
85      * of the given collection.
86      */

87     public void set(Collection JavaDoc collection) {
88         checkCollectionType(collection);
89         clear();
90         addAll(collection);
91     }
92     
93     public boolean equals(Object JavaDoc that) {
94         if (that instanceof Tuple) {
95             return equals(that);
96         }
97         return false;
98     }
99
100     public boolean equals(Sequence that) {
101         if (size() == that.size()) {
102             for (int i = 0; i < size(); i++) {
103                 if (!InvokerHelper.compareEqual(this.get(i), that.get(i))) {
104                     return false;
105                 }
106             }
107             return true;
108         }
109         return false;
110     }
111
112     public int hashCode() {
113         if (hashCode == 0) {
114             for (int i = 0; i < size(); i++) {
115                 Object JavaDoc value = get(i);
116                 int hash = (value != null) ? value.hashCode() : 0xbabe;
117                 hashCode ^= hash;
118             }
119             if (hashCode == 0) {
120                 hashCode = 0xbabe;
121             }
122         }
123         return hashCode;
124     }
125
126     public int minimumSize() {
127         return 0;
128     }
129
130     /**
131      * @return the type of the elements in the sequence or null if there is no
132      * type constraint on this sequence
133      */

134     public Class JavaDoc type() {
135         return type;
136     }
137     
138     public void add(int index, Object JavaDoc element) {
139         checkType(element);
140         hashCode = 0;
141         super.add(index, element);
142     }
143
144     public boolean add(Object JavaDoc element) {
145         checkType(element);
146         hashCode = 0;
147         return super.add(element);
148     }
149
150     public boolean addAll(Collection JavaDoc c) {
151         checkCollectionType(c);
152         hashCode = 0;
153         return super.addAll(c);
154     }
155
156     public boolean addAll(int index, Collection JavaDoc c) {
157         checkCollectionType(c);
158         hashCode = 0;
159         return super.addAll(index, c);
160     }
161
162     public void clear() {
163         hashCode = 0;
164         super.clear();
165     }
166
167     public Object JavaDoc remove(int index) {
168         hashCode = 0;
169         return super.remove(index);
170     }
171
172     protected void removeRange(int fromIndex, int toIndex) {
173         hashCode = 0;
174         super.removeRange(fromIndex, toIndex);
175     }
176
177     public Object JavaDoc set(int index, Object JavaDoc element) {
178         hashCode = 0;
179         return super.set(index, element);
180     }
181
182     // GroovyObject interface
183
//-------------------------------------------------------------------------
184
public Object JavaDoc invokeMethod(String JavaDoc name, Object JavaDoc args) {
185         try {
186         return getMetaClass().invokeMethod(this, name, args);
187         }
188         catch (MissingMethodException e) {
189             // lets apply the method to each item in the collection
190
List JavaDoc answer = new ArrayList JavaDoc(size());
191             for (Iterator JavaDoc iter = iterator(); iter.hasNext(); ) {
192                 Object JavaDoc element = iter.next();
193                 Object JavaDoc value = InvokerHelper.invokeMethod(element, name, args);
194                 answer.add(value);
195             }
196             return answer;
197         }
198     }
199
200     public Object JavaDoc getProperty(String JavaDoc property) {
201         return getMetaClass().getProperty(this, property);
202     }
203
204     public void setProperty(String JavaDoc property, Object JavaDoc newValue) {
205         getMetaClass().setProperty(this, property, newValue);
206     }
207
208     public MetaClass getMetaClass() {
209         return metaClass;
210     }
211
212     public void setMetaClass(MetaClass metaClass) {
213         this.metaClass = metaClass;
214     }
215
216     // Implementation methods
217
//-------------------------------------------------------------------------
218

219     /**
220      * Checks that each member of the given collection are of the correct
221      * type
222      */

223     protected void checkCollectionType(Collection JavaDoc c) {
224         if (type != null) {
225             for (Iterator JavaDoc iter = c.iterator(); iter.hasNext(); ) {
226                 Object JavaDoc element = iter.next();
227                 checkType(element);
228             }
229         }
230     }
231
232
233     /**
234      * Checks that the given object instance is of the correct type
235      * otherwise a runtime exception is thrown
236      */

237     protected void checkType(Object JavaDoc object) {
238         if (object == null) {
239             throw new NullPointerException JavaDoc("Sequences cannot contain null, use a List instead");
240         }
241         if (type != null) {
242             if (!type.isInstance(object)) {
243                 throw new IllegalArgumentException JavaDoc(
244                     "Invalid type of argument for sequence of type: "
245                         + type.getName()
246                         + " cannot add object: "
247                         + object);
248             }
249         }
250     }
251 }
Popular Tags