KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > types > resources > BaseResourceCollectionContainer


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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 package org.apache.tools.ant.types.resources;
19
20 import java.io.File JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Stack JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27
28 import org.apache.tools.ant.Project;
29 import org.apache.tools.ant.BuildException;
30 import org.apache.tools.ant.types.DataType;
31 import org.apache.tools.ant.types.ResourceCollection;
32
33 /**
34  * Base class for ResourceCollections that nest multiple ResourceCollections.
35  * @since Ant 1.7
36  */

37 public abstract class BaseResourceCollectionContainer
38     extends DataType implements ResourceCollection, Cloneable JavaDoc {
39     private List JavaDoc rc = new ArrayList JavaDoc();
40     private Collection JavaDoc coll = null;
41     private boolean cache = true;
42
43     /**
44      * Set whether to cache collections.
45      * @param b boolean cache flag.
46      */

47     public synchronized void setCache(boolean b) {
48         cache = b;
49     }
50
51     /**
52      * Learn whether to cache collections. Default is <code>true</code>.
53      * @return boolean cache flag.
54      */

55     public synchronized boolean isCache() {
56         return cache;
57     }
58
59     /**
60      * Clear the container.
61      * @throws BuildException on error.
62      */

63     public synchronized void clear() throws BuildException {
64         if (isReference()) {
65             throw noChildrenAllowed();
66         }
67         rc.clear();
68         FailFast.invalidate(this);
69         coll = null;
70         setChecked(false);
71     }
72
73     /**
74      * Add a ResourceCollection to the container.
75      * @param c the ResourceCollection to add.
76      * @throws BuildException on error.
77      */

78     public synchronized void add(ResourceCollection c) throws BuildException {
79         if (isReference()) {
80             throw noChildrenAllowed();
81         }
82         if (c == null) {
83             return;
84         }
85         rc.add(c);
86         FailFast.invalidate(this);
87         coll = null;
88         setChecked(false);
89     }
90
91     /**
92      * Add the Collection of ResourceCollections to the container.
93      * @param c the Collection whose elements to add.
94      * @throws BuildException on error.
95      */

96     public synchronized void addAll(Collection JavaDoc c) throws BuildException {
97         if (isReference()) {
98             throw noChildrenAllowed();
99         }
100         try {
101             for (Iterator JavaDoc i = c.iterator(); i.hasNext();) {
102                 add((ResourceCollection) i.next());
103             }
104         } catch (ClassCastException JavaDoc e) {
105             throw new BuildException(e);
106         }
107     }
108
109     /**
110      * Fulfill the ResourceCollection contract. The Iterator returned
111      * will throw ConcurrentModificationExceptions if ResourceCollections
112      * are added to this container while the Iterator is in use.
113      * @return a "fail-fast" Iterator.
114      */

115     public final synchronized Iterator JavaDoc iterator() {
116         if (isReference()) {
117             return ((BaseResourceCollectionContainer) getCheckedRef()).iterator();
118         }
119         dieOnCircularReference();
120         return new FailFast(this, cacheCollection().iterator());
121     }
122
123     /**
124      * Fulfill the ResourceCollection contract.
125      * @return number of elements as int.
126      */

127     public synchronized int size() {
128         if (isReference()) {
129             return ((BaseResourceCollectionContainer) getCheckedRef()).size();
130         }
131         dieOnCircularReference();
132         return cacheCollection().size();
133     }
134
135     /**
136      * Fulfill the ResourceCollection contract.
137      * @return whether this is a filesystem-only resource collection.
138      */

139     public synchronized boolean isFilesystemOnly() {
140         if (isReference()) {
141             return ((BaseResourceCollectionContainer) getCheckedRef()).isFilesystemOnly();
142         }
143         dieOnCircularReference();
144         //first the easy way, if all children are filesystem-only, return true:
145
boolean goEarly = true;
146         for (Iterator JavaDoc i = rc.iterator(); goEarly && i.hasNext();) {
147             goEarly &= ((ResourceCollection) i.next()).isFilesystemOnly();
148         }
149         if (goEarly) {
150             return true;
151         }
152         /* now check each Resource in case the child only
153            lets through files from any children IT may have: */

154         for (Iterator JavaDoc i = cacheCollection().iterator(); i.hasNext();) {
155             if (!(i.next() instanceof FileResource)) {
156                 return false;
157             }
158         }
159         return true;
160     }
161
162     /**
163      * Overrides the version of DataType to recurse on all DataType
164      * child elements that may have been added.
165      * @param stk the stack of data types to use (recursively).
166      * @param p the project to use to dereference the references.
167      * @throws BuildException on error.
168      */

169     protected synchronized void dieOnCircularReference(Stack JavaDoc stk, Project p)
170         throws BuildException {
171         if (isChecked()) {
172             return;
173         }
174         if (isReference()) {
175             super.dieOnCircularReference(stk, p);
176         } else {
177             for (Iterator JavaDoc i = rc.iterator(); i.hasNext();) {
178                 Object JavaDoc o = i.next();
179                 if (o instanceof DataType) {
180                     stk.push(o);
181                     invokeCircularReferenceCheck((DataType) o, stk, p);
182                     stk.pop();
183                 }
184             }
185             setChecked(true);
186         }
187     }
188
189     /**
190      * Get the nested ResourceCollections.
191      * @return List.
192      */

193     protected final synchronized List JavaDoc getResourceCollections() {
194         dieOnCircularReference();
195         return Collections.unmodifiableList(rc);
196     }
197
198     /**
199      * Template method for subclasses to return a Collection object of Resources.
200      * @return Collection.
201      */

202     protected abstract Collection JavaDoc getCollection();
203
204     /**
205      * Implement clone. The set of nested resource
206      * collections is shallowly cloned.
207      * @return a cloned instance.
208      */

209     public Object JavaDoc clone() {
210         try {
211             BaseResourceCollectionContainer c
212                 = (BaseResourceCollectionContainer) super.clone();
213             c.rc = new ArrayList JavaDoc(rc);
214             c.coll = null;
215             return c;
216         } catch (CloneNotSupportedException JavaDoc e) {
217             throw new BuildException(e);
218         }
219    }
220
221     /**
222      * Format this BaseResourceCollectionContainer as a String.
223      * @return a descriptive <code>String</code>.
224      */

225     public synchronized String JavaDoc toString() {
226         if (isReference()) {
227             return getCheckedRef().toString();
228         }
229         if (cacheCollection().size() == 0) {
230             return "";
231         }
232         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
233         for (Iterator JavaDoc i = coll.iterator(); i.hasNext();) {
234             if (sb.length() > 0) {
235                 sb.append(File.pathSeparatorChar);
236             }
237             sb.append(i.next());
238         }
239         return sb.toString();
240     }
241
242     private synchronized Collection JavaDoc cacheCollection() {
243         if (coll == null || !isCache()) {
244             coll = getCollection();
245         }
246         return coll;
247     }
248
249 }
250
Popular Tags