source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/types/AbstractFileSet.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: 22.2 KB
Line 
1/*
2 * Copyright 2002-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 */
17package org.apache.tools.ant.types;
18
19import java.io.File;
20import java.util.Enumeration;
21import java.util.Hashtable;
22import java.util.Stack;
23import java.util.Vector;
24import org.apache.tools.ant.BuildException;
25import org.apache.tools.ant.DirectoryScanner;
26import org.apache.tools.ant.FileScanner;
27import org.apache.tools.ant.Project;
28import org.apache.tools.ant.types.selectors.AndSelector;
29import org.apache.tools.ant.types.selectors.ContainsSelector;
30import org.apache.tools.ant.types.selectors.DateSelector;
31import org.apache.tools.ant.types.selectors.DependSelector;
32import org.apache.tools.ant.types.selectors.DepthSelector;
33import org.apache.tools.ant.types.selectors.ExtendSelector;
34import org.apache.tools.ant.types.selectors.FileSelector;
35import org.apache.tools.ant.types.selectors.DifferentSelector;
36import org.apache.tools.ant.types.selectors.FilenameSelector;
37import org.apache.tools.ant.types.selectors.TypeSelector;
38import org.apache.tools.ant.types.selectors.MajoritySelector;
39import org.apache.tools.ant.types.selectors.NoneSelector;
40import org.apache.tools.ant.types.selectors.NotSelector;
41import org.apache.tools.ant.types.selectors.OrSelector;
42import org.apache.tools.ant.types.selectors.PresentSelector;
43import org.apache.tools.ant.types.selectors.ContainsRegexpSelector;
44import org.apache.tools.ant.types.selectors.SelectSelector;
45import org.apache.tools.ant.types.selectors.SelectorContainer;
46import org.apache.tools.ant.types.selectors.SelectorScanner;
47import org.apache.tools.ant.types.selectors.SizeSelector;
48import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
49
50/**
51 * Class that holds an implicit patternset and supports nested
52 * patternsets and creates a DirectoryScanner using these patterns.
53 *
54 * <p>Common base class for DirSet and FileSet.</p>
55 *
56 */
57public abstract class AbstractFileSet extends DataType
58 implements Cloneable, SelectorContainer {
59
60 private PatternSet defaultPatterns = new PatternSet();
61 private Vector additionalPatterns = new Vector();
62 private Vector selectors = new Vector();
63
64 private File dir;
65 private boolean useDefaultExcludes = true;
66 private boolean isCaseSensitive = true;
67 private boolean followSymlinks = true;
68
69 /**
70 * Construct a new <code>AbstractFileSet</code>.
71 */
72 public AbstractFileSet() {
73 super();
74 }
75
76 /**
77 * Construct a new <code>AbstractFileSet</code>, shallowly cloned
78 * from the specified <code>AbstractFileSet</code>.
79 * @param fileset the <code>AbstractFileSet</code> to use as a template.
80 */
81 protected AbstractFileSet(AbstractFileSet fileset) {
82 this.dir = fileset.dir;
83 this.defaultPatterns = fileset.defaultPatterns;
84 this.additionalPatterns = fileset.additionalPatterns;
85 this.selectors = fileset.selectors;
86 this.useDefaultExcludes = fileset.useDefaultExcludes;
87 this.isCaseSensitive = fileset.isCaseSensitive;
88 this.followSymlinks = fileset.followSymlinks;
89 setProject(fileset.getProject());
90 }
91
92 /**
93 * Makes this instance in effect a reference to another instance.
94 *
95 * <p>You must not set another attribute or nest elements inside
96 * this element if you make it a reference.</p>
97 * @param r the <code>Reference</code> to use.
98 */
99 public void setRefid(Reference r) throws BuildException {
100 if (dir != null || defaultPatterns.hasPatterns(getProject())) {
101 throw tooManyAttributes();
102 }
103 if (!additionalPatterns.isEmpty()) {
104 throw noChildrenAllowed();
105 }
106 if (!selectors.isEmpty()) {
107 throw noChildrenAllowed();
108 }
109 super.setRefid(r);
110 }
111
112 /**
113 * Sets the base-directory for this instance.
114 * @param dir the directory's <code>File</code> instance.
115 */
116 public void setDir(File dir) throws BuildException {
117 if (isReference()) {
118 throw tooManyAttributes();
119 }
120 this.dir = dir;
121 }
122
123 /**
124 * Retrieves the base-directory for this instance.
125 * @param p the <code>Project</code> against which the
126 * reference is resolved, if set.
127 * @return <code>File</code>.
128 */
129 public File getDir(Project p) {
130 return (isReference()) ? getRef(p).getDir(p) : dir;
131 }
132
133 /**
134 * Creates a nested patternset.
135 * @return <code>PatternSet</code>.
136 */
137 public PatternSet createPatternSet() {
138 if (isReference()) {
139 throw noChildrenAllowed();
140 }
141 PatternSet patterns = new PatternSet();
142 additionalPatterns.addElement(patterns);
143 return patterns;
144 }
145
146 /**
147 * Add a name entry to the include list.
148 * @return <code>PatternSet.NameEntry</code>.
149 */
150 public PatternSet.NameEntry createInclude() {
151 if (isReference()) {
152 throw noChildrenAllowed();
153 }
154 return defaultPatterns.createInclude();
155 }
156
157 /**
158 * Add a name entry to the include files list.
159 * @return <code>PatternSet.NameEntry</code>.
160 */
161 public PatternSet.NameEntry createIncludesFile() {
162 if (isReference()) {
163 throw noChildrenAllowed();
164 }
165 return defaultPatterns.createIncludesFile();
166 }
167
168 /**
169 * Add a name entry to the exclude list.
170 * @return <code>PatternSet.NameEntry</code>.
171 */
172 public PatternSet.NameEntry createExclude() {
173 if (isReference()) {
174 throw noChildrenAllowed();
175 }
176 return defaultPatterns.createExclude();
177 }
178
179 /**
180 * Add a name entry to the excludes files list.
181 * @return <code>PatternSet.NameEntry</code>.
182 */
183 public PatternSet.NameEntry createExcludesFile() {
184 if (isReference()) {
185 throw noChildrenAllowed();
186 }
187 return defaultPatterns.createExcludesFile();
188 }
189
190 /**
191 * Creates a single file fileset.
192 * @param file the single <code>File</code> included in this
193 * <code>AbstractFileSet</code>.
194 */
195 public void setFile(File file) {
196 if (isReference()) {
197 throw tooManyAttributes();
198 }
199 setDir(file.getParentFile());
200 createInclude().setName(file.getName());
201 }
202
203 /**
204 * Appends <code>includes</code> to the current list of include
205 * patterns.
206 *
207 * <p>Patterns may be separated by a comma or a space.</p>
208 *
209 * @param includes the <code>String</code> containing the include patterns.
210 */
211 public void setIncludes(String includes) {
212 if (isReference()) {
213 throw tooManyAttributes();
214 }
215 defaultPatterns.setIncludes(includes);
216 }
217
218 /**
219 * Appends <code>excludes</code> to the current list of exclude
220 * patterns.
221 *
222 * <p>Patterns may be separated by a comma or a space.</p>
223 *
224 * @param excludes the <code>String</code> containing the exclude patterns.
225 */
226 public void setExcludes(String excludes) {
227 if (isReference()) {
228 throw tooManyAttributes();
229 }
230 defaultPatterns.setExcludes(excludes);
231 }
232
233 /**
234 * Sets the <code>File</code> containing the includes patterns.
235 *
236 * @param incl <code>File</code> instance.
237 */
238 public void setIncludesfile(File incl) throws BuildException {
239 if (isReference()) {
240 throw tooManyAttributes();
241 }
242 defaultPatterns.setIncludesfile(incl);
243 }
244
245 /**
246 * Sets the <code>File</code> containing the excludes patterns.
247 *
248 * @param excl <code>File</code> instance.
249 */
250 public void setExcludesfile(File excl) throws BuildException {
251 if (isReference()) {
252 throw tooManyAttributes();
253 }
254 defaultPatterns.setExcludesfile(excl);
255 }
256
257 /**
258 * Sets whether default exclusions should be used or not.
259 *
260 * @param useDefaultExcludes <code>boolean</code>.
261 */
262 public void setDefaultexcludes(boolean useDefaultExcludes) {
263 if (isReference()) {
264 throw tooManyAttributes();
265 }
266 this.useDefaultExcludes = useDefaultExcludes;
267 }
268
269 /**
270 * Whether default exclusions should be used or not.
271 * @since Ant 1.6.3
272 */
273 public boolean getDefaultexcludes() {
274 return (isReference())
275 ? getRef(getProject()).getDefaultexcludes() : useDefaultExcludes;
276 }
277
278 /**
279 * Sets case sensitivity of the file system.
280 *
281 * @param isCaseSensitive <code>boolean</code>.
282 */
283 public void setCaseSensitive(boolean isCaseSensitive) {
284 if (isReference()) {
285 throw tooManyAttributes();
286 }
287 this.isCaseSensitive = isCaseSensitive;
288 }
289
290 /**
291 * Sets whether or not symbolic links should be followed.
292 *
293 * @param followSymlinks whether or not symbolic links should be followed.
294 */
295 public void setFollowSymlinks(boolean followSymlinks) {
296 if (isReference()) {
297 throw tooManyAttributes();
298 }
299 this.followSymlinks = followSymlinks;
300 }
301
302 /**
303 * Find out if the fileset wants to follow symbolic links.
304 *
305 * @return <code>boolean</code> indicating whether symbolic links
306 * should be followed.
307 *
308 * @since Ant 1.6
309 */
310 public boolean isFollowSymlinks() {
311 return (isReference())
312 ? getRef(getProject()).isFollowSymlinks() : followSymlinks;
313 }
314
315 /**
316 * Gets as descriptive as possible a name used for this datatype instance.
317 * @return <code>String</code> name.
318 */
319 protected String getDataTypeName() {
320 // look up the types in project and see if they match this class
321 Project p = getProject();
322 if (p != null) {
323 Hashtable typedefs = p.getDataTypeDefinitions();
324 for (Enumeration e = typedefs.keys(); e.hasMoreElements();) {
325 String typeName = (String) e.nextElement();
326 Class typeClass = (Class) typedefs.get(typeName);
327 if (typeClass == getClass()) {
328 return typeName;
329 }
330 }
331 }
332 String classname = getClass().getName();
333 return classname.substring(classname.lastIndexOf('.') + 1);
334 }
335
336 /**
337 * Returns the directory scanner needed to access the files to process.
338 * @return a <code>DirectoryScanner</code> instance.
339 */
340 public DirectoryScanner getDirectoryScanner(Project p) {
341 if (isReference()) {
342 return getRef(p).getDirectoryScanner(p);
343 }
344 if (dir == null) {
345 throw new BuildException("No directory specified for "
346 + getDataTypeName() + ".");
347 }
348 if (!dir.exists()) {
349 throw new BuildException(dir.getAbsolutePath() + " not found.");
350 }
351 if (!dir.isDirectory()) {
352 throw new BuildException(dir.getAbsolutePath()
353 + " is not a directory.");
354 }
355 DirectoryScanner ds = new DirectoryScanner();
356 setupDirectoryScanner(ds, p);
357 ds.setFollowSymlinks(followSymlinks);
358 ds.scan();
359 return ds;
360 }
361
362 /**
363 * Set up the specified directory scanner against the specified project.
364 * @param ds a <code>FileScanner</code> instance.
365 * @param p an Ant <code>Project</code> instance.
366 */
367 public void setupDirectoryScanner(FileScanner ds, Project p) {
368 if (isReference()) {
369 getRef(p).setupDirectoryScanner(ds, p);
370 return;
371 }
372 if (ds == null) {
373 throw new IllegalArgumentException("ds cannot be null");
374 }
375 ds.setBasedir(dir);
376
377 final int count = additionalPatterns.size();
378 for (int i = 0; i < count; i++) {
379 Object o = additionalPatterns.elementAt(i);
380 defaultPatterns.append((PatternSet) o, p);
381 }
382 p.log(getDataTypeName() + ": Setup scanner in dir " + dir
383 + " with " + defaultPatterns, Project.MSG_DEBUG);
384
385 ds.setIncludes(defaultPatterns.getIncludePatterns(p));
386 ds.setExcludes(defaultPatterns.getExcludePatterns(p));
387 if (ds instanceof SelectorScanner) {
388 SelectorScanner ss = (SelectorScanner) ds;
389 ss.setSelectors(getSelectors(p));
390 }
391 if (useDefaultExcludes) {
392 ds.addDefaultExcludes();
393 }
394 ds.setCaseSensitive(isCaseSensitive);
395 }
396
397 /**
398 * Performs the check for circular references and returns the
399 * referenced FileSet.
400 */
401 protected AbstractFileSet getRef(Project p) {
402 if (!isChecked()) {
403 Stack stk = new Stack();
404 stk.push(this);
405 dieOnCircularReference(stk, p);
406 }
407 Object o = getRefid().getReferencedObject(p);
408 if (!getClass().isAssignableFrom(o.getClass())) {
409 throw new BuildException(getRefid().getRefId()
410 + " doesn\'t denote a " + getDataTypeName());
411 }
412 return (AbstractFileSet) o;
413 }
414
415 // SelectorContainer methods
416
417 /**
418 * Indicates whether there are any selectors here.
419 *
420 * @return whether any selectors are in this container.
421 */
422 public boolean hasSelectors() {
423 return (isReference() && getProject() != null)
424 ? getRef(getProject()).hasSelectors() : !(selectors.isEmpty());
425 }
426
427 /**
428 * Indicates whether there are any patterns here.
429 *
430 * @return whether any patterns are in this container.
431 */
432 public boolean hasPatterns() {
433 if (isReference() && getProject() != null) {
434 return getRef(getProject()).hasPatterns();
435 }
436 if (defaultPatterns.hasPatterns(getProject())) {
437 return true;
438 }
439 Enumeration e = additionalPatterns.elements();
440 while (e.hasMoreElements()) {
441 PatternSet ps = (PatternSet) e.nextElement();
442 if (ps.hasPatterns(getProject())) {
443 return true;
444 }
445 }
446 return false;
447 }
448
449 /**
450 * Gives the count of the number of selectors in this container.
451 *
452 * @return the number of selectors in this container as an <code>int</code>.
453 */
454 public int selectorCount() {
455 return (isReference() && getProject() != null)
456 ? getRef(getProject()).selectorCount() : selectors.size();
457 }
458
459 /**
460 * Returns the set of selectors as an array.
461 *
462 * @return a <code>FileSelector[]</code> of the selectors in this container.
463 */
464 public FileSelector[] getSelectors(Project p) {
465 return (isReference())
466 ? getRef(p).getSelectors(p) : (FileSelector[])(selectors.toArray(
467 new FileSelector[selectors.size()]));
468 }
469
470 /**
471 * Returns an enumerator for accessing the set of selectors.
472 *
473 * @return an <code>Enumeration</code> of selectors.
474 */
475 public Enumeration selectorElements() {
476 return (isReference() && getProject() != null)
477 ? getRef(getProject()).selectorElements() : selectors.elements();
478 }
479
480 /**
481 * Add a new selector into this container.
482 *
483 * @param selector the new <code>FileSelector</code> to add.
484 */
485 public void appendSelector(FileSelector selector) {
486 if (isReference()) {
487 throw noChildrenAllowed();
488 }
489 selectors.addElement(selector);
490 }
491
492 /* Methods below all add specific selectors */
493
494 /**
495 * Add a "Select" selector entry on the selector list.
496 * @param selector the <code>SelectSelector</code> to add.
497 */
498 public void addSelector(SelectSelector selector) {
499 appendSelector(selector);
500 }
501
502 /**
503 * Add an "And" selector entry on the selector list.
504 * @param selector the <code>AndSelector</code> to add.
505 */
506 public void addAnd(AndSelector selector) {
507 appendSelector(selector);
508 }
509
510 /**
511 * Add an "Or" selector entry on the selector list.
512 * @param selector the <code>OrSelector</code> to add.
513 */
514 public void addOr(OrSelector selector) {
515 appendSelector(selector);
516 }
517
518 /**
519 * Add a "Not" selector entry on the selector list.
520 * @param selector the <code>NotSelector</code> to add.
521 */
522 public void addNot(NotSelector selector) {
523 appendSelector(selector);
524 }
525
526 /**
527 * Add a "None" selector entry on the selector list.
528 * @param selector the <code>NoneSelector</code> to add.
529 */
530 public void addNone(NoneSelector selector) {
531 appendSelector(selector);
532 }
533
534 /**
535 * Add a majority selector entry on the selector list.
536 * @param selector the <code>MajoritySelector</code> to add.
537 */
538 public void addMajority(MajoritySelector selector) {
539 appendSelector(selector);
540 }
541
542 /**
543 * Add a selector date entry on the selector list.
544 * @param selector the <code>DateSelector</code> to add.
545 */
546 public void addDate(DateSelector selector) {
547 appendSelector(selector);
548 }
549
550 /**
551 * Add a selector size entry on the selector list.
552 * @param selector the <code>SizeSelector</code> to add.
553 */
554 public void addSize(SizeSelector selector) {
555 appendSelector(selector);
556 }
557
558 /**
559 * Add a DifferentSelector entry on the selector list.
560 * @param selector the <code>DifferentSelector</code> to add.
561 */
562 public void addDifferent(DifferentSelector selector) {
563 appendSelector(selector);
564 }
565
566 /**
567 * Add a selector filename entry on the selector list.
568 * @param selector the <code>FilenameSelector</code> to add.
569 */
570 public void addFilename(FilenameSelector selector) {
571 appendSelector(selector);
572 }
573
574 /**
575 * Add a selector type entry on the selector list.
576 * @param selector the <code>TypeSelector</code> to add.
577 */
578 public void addType(TypeSelector selector) {
579 appendSelector(selector);
580 }
581
582 /**
583 * Add an extended selector entry on the selector list.
584 * @param selector the <code>ExtendSelector</code> to add.
585 */
586 public void addCustom(ExtendSelector selector) {
587 appendSelector(selector);
588 }
589
590 /**
591 * Add a contains selector entry on the selector list.
592 * @param selector the <code>ContainsSelector</code> to add.
593 */
594 public void addContains(ContainsSelector selector) {
595 appendSelector(selector);
596 }
597
598 /**
599 * Add a present selector entry on the selector list.
600 * @param selector the <code>PresentSelector</code> to add.
601 */
602 public void addPresent(PresentSelector selector) {
603 appendSelector(selector);
604 }
605
606 /**
607 * Add a depth selector entry on the selector list.
608 * @param selector the <code>DepthSelector</code> to add.
609 */
610 public void addDepth(DepthSelector selector) {
611 appendSelector(selector);
612 }
613
614 /**
615 * Add a depends selector entry on the selector list.
616 * @param selector the <code>DependSelector</code> to add.
617 */
618 public void addDepend(DependSelector selector) {
619 appendSelector(selector);
620 }
621
622 /**
623 * Add a regular expression selector entry on the selector list.
624 * @param selector the <code>ContainsRegexpSelector</code> to add.
625 */
626 public void addContainsRegexp(ContainsRegexpSelector selector) {
627 appendSelector(selector);
628 }
629
630 /**
631 * Add the modified selector.
632 * @param selector the <code>ModifiedSelector</code> to add.
633 * @since ant 1.6
634 */
635 public void addModified(ModifiedSelector selector) {
636 appendSelector(selector);
637 }
638
639 /**
640 * Add an arbitary selector.
641 * @param selector the <code>FileSelector</code> to add.
642 * @since Ant 1.6
643 */
644 public void add(FileSelector selector) {
645 appendSelector(selector);
646 }
647
648 /**
649 * Returns included files as a list of semicolon-separated filenames.
650 *
651 * @return a <code>String</code> of included filenames.
652 */
653 public String toString() {
654 DirectoryScanner ds = getDirectoryScanner(getProject());
655 String[] files = ds.getIncludedFiles();
656 StringBuffer sb = new StringBuffer();
657
658 for (int i = 0; i < files.length; i++) {
659 if (i > 0) {
660 sb.append(';');
661 }
662 sb.append(files[i]);
663 }
664 return sb.toString();
665 }
666
667 /**
668 * Creates a deep clone of this instance, except for the nested
669 * selectors (the list of selectors is a shallow clone of this
670 * instance's list).
671 *
672 * @since Ant 1.6
673 */
674 public Object clone() {
675 if (isReference()) {
676 return (getRef(getProject())).clone();
677 } else {
678 try {
679 AbstractFileSet fs = (AbstractFileSet) super.clone();
680 fs.defaultPatterns = (PatternSet) defaultPatterns.clone();
681 fs.additionalPatterns = new Vector(additionalPatterns.size());
682 Enumeration e = additionalPatterns.elements();
683 while (e.hasMoreElements()) {
684 fs.additionalPatterns
685 .addElement(((PatternSet) e.nextElement()).clone());
686 }
687 fs.selectors = (Vector) fs.selectors.clone();
688 return fs;
689 } catch (CloneNotSupportedException e) {
690 throw new BuildException(e);
691 }
692 }
693 }
694
695}
Note: See TracBrowser for help on using the repository browser.