source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/types/PatternSet.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 16.7 KB
Line 
1/*
2 * Copyright 2000-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 */
17
18package org.apache.tools.ant.types;
19
20import java.io.BufferedReader;
21import java.io.File;
22import java.io.FileReader;
23import java.io.IOException;
24import java.util.Enumeration;
25import java.util.Stack;
26import java.util.StringTokenizer;
27import java.util.Vector;
28import org.apache.tools.ant.BuildException;
29import org.apache.tools.ant.Project;
30
31/**
32 * Named collection of include/exclude tags.
33 *
34 * <p>Moved out of MatchingTask to make it a standalone object that
35 * could be referenced (by scripts for example).
36 *
37 */
38public class PatternSet extends DataType implements Cloneable {
39 private Vector includeList = new Vector();
40 private Vector excludeList = new Vector();
41 private Vector includesFileList = new Vector();
42 private Vector excludesFileList = new Vector();
43
44 /**
45 * inner class to hold a name on list. "If" and "Unless" attributes
46 * may be used to invalidate the entry based on the existence of a
47 * property (typically set thru the use of the Available task).
48 */
49 public class NameEntry {
50 private String name;
51 private String ifCond;
52 private String unlessCond;
53
54 /**
55 * Sets the name pattern.
56 *
57 * @param name The pattern string.
58 */
59 public void setName(String name) {
60 this.name = name;
61 }
62
63 /**
64 * Sets the if attribute. This attribute and the "unless"
65 * attribute are used to validate the name, based in the
66 * existence of the property.
67 *
68 * @param cond A property name. If this property is not
69 * present, the name is invalid.
70 */
71 public void setIf(String cond) {
72 ifCond = cond;
73 }
74
75 /**
76 * Sets the unless attribute. This attribute and the "if"
77 * attribute are used to validate the name, based in the
78 * existence of the property.
79 *
80 * @param cond A property name. If this property is
81 * present, the name is invalid.
82 */
83 public void setUnless(String cond) {
84 unlessCond = cond;
85 }
86
87 /**
88 * @return the name attribute.
89 */
90 public String getName() {
91 return name;
92 }
93
94 /**
95 * This validates the name - checks the if and unless
96 * properties.
97 *
98 * @param p the current project, used to check the presence or
99 * absence of a property.
100 * @return the name attribute or null if the "if" or "unless"
101 * properties are not/are set.
102 */
103 public String evalName(Project p) {
104 return valid(p) ? name : null;
105 }
106
107 private boolean valid(Project p) {
108 if (ifCond != null && p.getProperty(ifCond) == null) {
109 return false;
110 } else if (unlessCond != null && p.getProperty(unlessCond) != null) {
111 return false;
112 }
113 return true;
114 }
115
116 /**
117 * @return a printable form of this object.
118 */
119 public String toString() {
120 if (name == null) {
121 throw new BuildException(
122 "Missing attribute \"name\" for a pattern");
123 }
124 StringBuffer buf = new StringBuffer(name);
125 if ((ifCond != null) || (unlessCond != null)) {
126 buf.append(":");
127 String connector = "";
128
129 if (ifCond != null) {
130 buf.append("if->");
131 buf.append(ifCond);
132 connector = ";";
133 }
134 if (unlessCond != null) {
135 buf.append(connector);
136 buf.append("unless->");
137 buf.append(unlessCond);
138 }
139 }
140
141 return buf.toString();
142 }
143 }
144
145 /**
146 * Creates a new <code>PatternSet</code> instance.
147 */
148 public PatternSet() {
149 super();
150 }
151
152 /**
153 * Makes this instance in effect a reference to another PatternSet
154 * instance.
155 *
156 * <p>You must not set another attribute or nest elements inside
157 * this element if you make it a reference.</p>
158 * @param r the reference to another patternset.
159 * @throws BuildException on error.
160 */
161 public void setRefid(Reference r) throws BuildException {
162 if (!includeList.isEmpty() || !excludeList.isEmpty()) {
163 throw tooManyAttributes();
164 }
165 super.setRefid(r);
166 }
167
168 /**
169 * This is a patternset nested element.
170 *
171 * @param p a configured patternset nested element.
172 */
173 public void addConfiguredPatternset(PatternSet p) {
174 if (isReference()) {
175 throw noChildrenAllowed();
176 }
177
178 String[] nestedIncludes = p.getIncludePatterns(getProject());
179 String[] nestedExcludes = p.getExcludePatterns(getProject());
180
181 if (nestedIncludes != null) {
182 for (int i = 0; i < nestedIncludes.length; i++) {
183 createInclude().setName(nestedIncludes[i]);
184 }
185 }
186
187 if (nestedExcludes != null) {
188 for (int i = 0; i < nestedExcludes.length; i++) {
189 createExclude().setName(nestedExcludes[i]);
190 }
191 }
192 }
193
194 /**
195 * add a name entry on the include list
196 * @return a nested include element to be configured.
197 */
198 public NameEntry createInclude() {
199 if (isReference()) {
200 throw noChildrenAllowed();
201 }
202 return addPatternToList(includeList);
203 }
204
205 /**
206 * add a name entry on the include files list
207 * @return a nested includesfile element to be configured.
208 */
209 public NameEntry createIncludesFile() {
210 if (isReference()) {
211 throw noChildrenAllowed();
212 }
213 return addPatternToList(includesFileList);
214 }
215
216 /**
217 * add a name entry on the exclude list
218 * @return a nested exclude element to be configured.
219 */
220 public NameEntry createExclude() {
221 if (isReference()) {
222 throw noChildrenAllowed();
223 }
224 return addPatternToList(excludeList);
225 }
226
227 /**
228 * add a name entry on the exclude files list
229 * @return a nested excludesfile element to be configured.
230 */
231 public NameEntry createExcludesFile() {
232 if (isReference()) {
233 throw noChildrenAllowed();
234 }
235 return addPatternToList(excludesFileList);
236 }
237
238 /**
239 * Appends <code>includes</code> to the current list of include patterns.
240 * Patterns may be separated by a comma or a space.
241 *
242 * @param includes the string containing the include patterns
243 */
244 public void setIncludes(String includes) {
245 if (isReference()) {
246 throw tooManyAttributes();
247 }
248 if (includes != null && includes.length() > 0) {
249 StringTokenizer tok = new StringTokenizer(includes, ", ", false);
250 while (tok.hasMoreTokens()) {
251 createInclude().setName(tok.nextToken());
252 }
253 }
254 }
255
256 /**
257 * Appends <code>excludes</code> to the current list of exclude patterns.
258 * Patterns may be separated by a comma or a space.
259 *
260 * @param excludes the string containing the exclude patterns
261 */
262 public void setExcludes(String excludes) {
263 if (isReference()) {
264 throw tooManyAttributes();
265 }
266 if (excludes != null && excludes.length() > 0) {
267 StringTokenizer tok = new StringTokenizer(excludes, ", ", false);
268 while (tok.hasMoreTokens()) {
269 createExclude().setName(tok.nextToken());
270 }
271 }
272 }
273
274 /**
275 * add a name entry to the given list
276 */
277 private NameEntry addPatternToList(Vector list) {
278 NameEntry result = new NameEntry();
279 list.addElement(result);
280 return result;
281 }
282
283 /**
284 * Sets the name of the file containing the includes patterns.
285 *
286 * @param includesFile The file to fetch the include patterns from.
287 * @throws BuildException on error.
288 */
289 public void setIncludesfile(File includesFile) throws BuildException {
290 if (isReference()) {
291 throw tooManyAttributes();
292 }
293 createIncludesFile().setName(includesFile.getAbsolutePath());
294 }
295
296 /**
297 * Sets the name of the file containing the excludes patterns.
298 *
299 * @param excludesFile The file to fetch the exclude patterns from.
300 * @throws BuildException on error.
301 */
302 public void setExcludesfile(File excludesFile) throws BuildException {
303 if (isReference()) {
304 throw tooManyAttributes();
305 }
306 createExcludesFile().setName(excludesFile.getAbsolutePath());
307 }
308
309 /**
310 * Reads path matching patterns from a file and adds them to the
311 * includes or excludes list (as appropriate).
312 */
313 private void readPatterns(File patternfile, Vector patternlist, Project p)
314 throws BuildException {
315
316 BufferedReader patternReader = null;
317 try {
318 // Get a FileReader
319 patternReader =
320 new BufferedReader(new FileReader(patternfile));
321
322 // Create one NameEntry in the appropriate pattern list for each
323 // line in the file.
324 String line = patternReader.readLine();
325 while (line != null) {
326 if (line.length() > 0) {
327 line = p.replaceProperties(line);
328 addPatternToList(patternlist).setName(line);
329 }
330 line = patternReader.readLine();
331 }
332 } catch (IOException ioe) {
333 String msg = "An error occurred while reading from pattern file: "
334 + patternfile;
335 throw new BuildException(msg, ioe);
336 } finally {
337 if (null != patternReader) {
338 try {
339 patternReader.close();
340 } catch (IOException ioe) {
341 //Ignore exception
342 }
343 }
344 }
345 }
346
347 /**
348 * Adds the patterns of the other instance to this set.
349 * @param other the other PatternSet instance.
350 * @param p the current project.
351 */
352 public void append(PatternSet other, Project p) {
353 if (isReference()) {
354 throw new BuildException("Cannot append to a reference");
355 }
356
357 String[] incl = other.getIncludePatterns(p);
358 if (incl != null) {
359 for (int i = 0; i < incl.length; i++) {
360 createInclude().setName(incl[i]);
361 }
362 }
363
364 String[] excl = other.getExcludePatterns(p);
365 if (excl != null) {
366 for (int i = 0; i < excl.length; i++) {
367 createExclude().setName(excl[i]);
368 }
369 }
370 }
371
372 /**
373 * Returns the filtered include patterns.
374 * @param p the current project.
375 * @return the filtered included patterns.
376 */
377 public String[] getIncludePatterns(Project p) {
378 if (isReference()) {
379 return getRef(p).getIncludePatterns(p);
380 } else {
381 readFiles(p);
382 return makeArray(includeList, p);
383 }
384 }
385
386 /**
387 * Returns the filtered include patterns.
388 * @param p the current project.
389 * @return the filtered excluded patterns.
390 */
391 public String[] getExcludePatterns(Project p) {
392 if (isReference()) {
393 return getRef(p).getExcludePatterns(p);
394 } else {
395 readFiles(p);
396 return makeArray(excludeList, p);
397 }
398 }
399
400 /**
401 * helper for FileSet.
402 */
403 boolean hasPatterns(Project p) {
404 if (isReference()) {
405 return getRef(p).hasPatterns(p);
406 } else {
407 return includesFileList.size() > 0 || excludesFileList.size() > 0
408 || includeList.size() > 0 || excludeList.size() > 0;
409 }
410 }
411
412 /**
413 * Performs the check for circular references and returns the
414 * referenced PatternSet.
415 */
416 private PatternSet getRef(Project p) {
417 if (!isChecked()) {
418 Stack stk = new Stack();
419 stk.push(this);
420 dieOnCircularReference(stk, p);
421 }
422
423 Object o = getRefid().getReferencedObject(p);
424 if (!(o instanceof PatternSet)) {
425 String msg = getRefid().getRefId() + " doesn\'t denote a patternset";
426 throw new BuildException(msg);
427 } else {
428 return (PatternSet) o;
429 }
430 }
431
432 /**
433 * Convert a vector of NameEntry elements into an array of Strings.
434 */
435 private String[] makeArray(Vector list, Project p) {
436 if (list.size() == 0) {
437 return null;
438 }
439
440 Vector tmpNames = new Vector();
441 for (Enumeration e = list.elements(); e.hasMoreElements();) {
442 NameEntry ne = (NameEntry) e.nextElement();
443 String pattern = ne.evalName(p);
444 if (pattern != null && pattern.length() > 0) {
445 tmpNames.addElement(pattern);
446 }
447 }
448
449 String[] result = new String[tmpNames.size()];
450 tmpNames.copyInto(result);
451 return result;
452 }
453
454 /**
455 * Read includesfile ot excludesfile if not already done so.
456 */
457 private void readFiles(Project p) {
458 if (includesFileList.size() > 0) {
459 Enumeration e = includesFileList.elements();
460 while (e.hasMoreElements()) {
461 NameEntry ne = (NameEntry) e.nextElement();
462 String fileName = ne.evalName(p);
463 if (fileName != null) {
464 File inclFile = p.resolveFile(fileName);
465 if (!inclFile.exists()) {
466 throw new BuildException("Includesfile "
467 + inclFile.getAbsolutePath()
468 + " not found.");
469 }
470 readPatterns(inclFile, includeList, p);
471 }
472 }
473 includesFileList.removeAllElements();
474 }
475
476 if (excludesFileList.size() > 0) {
477 Enumeration e = excludesFileList.elements();
478 while (e.hasMoreElements()) {
479 NameEntry ne = (NameEntry) e.nextElement();
480 String fileName = ne.evalName(p);
481 if (fileName != null) {
482 File exclFile = p.resolveFile(fileName);
483 if (!exclFile.exists()) {
484 throw new BuildException("Excludesfile "
485 + exclFile.getAbsolutePath()
486 + " not found.");
487 }
488 readPatterns(exclFile, excludeList, p);
489 }
490 }
491 excludesFileList.removeAllElements();
492 }
493 }
494
495 /**
496 * @return a printable form of this object.
497 */
498 public String toString() {
499 return "patternSet{ includes: " + includeList
500 + " excludes: " + excludeList + " }";
501 }
502
503 /**
504 * @since Ant 1.6
505 * @return a clone of this patternset.
506 */
507 public Object clone() {
508 if (isReference()) {
509 return getRef(getProject()).clone();
510 } else {
511 try {
512 PatternSet ps = (PatternSet) super.clone();
513 ps.includeList = (Vector) includeList.clone();
514 ps.excludeList = (Vector) excludeList.clone();
515 ps.includesFileList = (Vector) includesFileList.clone();
516 ps.excludesFileList = (Vector) excludesFileList.clone();
517 return ps;
518 } catch (CloneNotSupportedException e) {
519 throw new BuildException(e);
520 }
521 }
522 }
523
524}
Note: See TracBrowser for help on using the repository browser.