/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.tools.ant.types.resources;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.AbstractFileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;

Union of file/dirsets that share the same patterns and selectors but have different roots.
Since:Ant 1.9.4
/** * Union of file/dirsets that share the same patterns and selectors * but have different roots. * @since Ant 1.9.4 */
public class MultiRootFileSet extends AbstractFileSet implements ResourceCollection { private SetType type = SetType.file; private boolean cache = true; private List<File> baseDirs = new ArrayList<>(); private Union union; @Override public void setDir(final File dir) { throw new BuildException(getDataTypeName() + " doesn't support the dir attribute"); }
Determines the types of resources to return.
Params:
  • type – the types of resources to return
/** * Determines the types of resources to return. * @param type the types of resources to return */
public void setType(final SetType type) { if (isReference()) { throw tooManyAttributes(); } this.type = type; }
Set whether to cache collections.
Params:
  • b – boolean cache flag.
/** * Set whether to cache collections. * @param b boolean cache flag. */
public synchronized void setCache(final boolean b) { if (isReference()) { throw tooManyAttributes(); } cache = b; }
Adds basedirs as a comma separated list.
Params:
  • dirs – directories as CSV
/** * Adds basedirs as a comma separated list. * @param dirs directories as CSV */
public void setBaseDirs(final String dirs) { if (isReference()) { throw tooManyAttributes(); } if (dirs != null && !dirs.isEmpty()) { for (final String d : dirs.split(",")) { baseDirs.add(getProject().resolveFile(d)); } } }
Adds a basedir as nested element.
Params:
  • r – basedir
/** * Adds a basedir as nested element. * @param r basedir */
public void addConfiguredBaseDir(final FileResource r) { if (isReference()) { throw noChildrenAllowed(); } baseDirs.add(r.getFile()); } @Override public void setRefid(final Reference r) { if (!baseDirs.isEmpty()) { throw tooManyAttributes(); } super.setRefid(r); }
Return a MultiRootFileSet that has the same basedirs and same patternsets as this one.
Returns:the cloned MultiRootFileSet.
/** * Return a MultiRootFileSet that has the same basedirs and same patternsets * as this one. * @return the cloned MultiRootFileSet. */
@Override public Object clone() { if (isReference()) { return getRef().clone(); } final MultiRootFileSet fs = (MultiRootFileSet) super.clone(); fs.baseDirs = new ArrayList<>(baseDirs); fs.union = null; return fs; }
Fulfill the ResourceCollection contract.
Returns:an Iterator of Resources.
/** * Fulfill the ResourceCollection contract. * @return an Iterator of Resources. */
@Override public Iterator<Resource> iterator() { if (isReference()) { return getRef().iterator(); } return merge().iterator(); }
Fulfill the ResourceCollection contract.
Returns:number of elements as int.
/** * Fulfill the ResourceCollection contract. * @return number of elements as int. */
@Override public int size() { if (isReference()) { return getRef().size(); } return merge().size(); }
Always returns true.
Returns:true indicating that all elements will be FileResources.
/** * Always returns true. * @return true indicating that all elements will be FileResources. */
@Override public boolean isFilesystemOnly() { return true; }
Returns included directories as a list of semicolon-separated paths.
Returns:a String of included directories.
/** * Returns included directories as a list of semicolon-separated paths. * * @return a <code>String</code> of included directories. */
@Override public String toString() { if (isReference()) { return getRef().toString(); } return merge().toString(); } private MultiRootFileSet getRef() { return getCheckedRef(MultiRootFileSet.class); } private synchronized Union merge() { if (cache && union != null) { return union; } final Union u = new Union(); setup(u); if (cache) { union = u; } return u; } private void setup(final Union u) { for (final File d : baseDirs) { u.add(new Worker(this, type, d)); } }
What to return from the set: files, directories or both.
/** * What to return from the set: files, directories or both. */
public enum SetType { file, dir, both } private static class Worker extends AbstractFileSet implements ResourceCollection { private final SetType type; private Worker(final MultiRootFileSet fs, final SetType type, final File dir) { super(fs); this.type = type; setDir(dir); } @Override public boolean isFilesystemOnly() { return true; } @Override public Iterator<Resource> iterator() { final DirectoryScanner ds = getDirectoryScanner(); String[] names = type == SetType.file ? ds.getIncludedFiles() : ds.getIncludedDirectories(); if (type == SetType.both) { final String[] files = ds.getIncludedFiles(); final String[] merged = new String[names.length + files.length]; System.arraycopy(names, 0, merged, 0, names.length); System.arraycopy(files, 0, merged, names.length, files.length); names = merged; } return new FileResourceIterator(getProject(), getDir(getProject()), names); } @Override public int size() { final DirectoryScanner ds = getDirectoryScanner(); int count = type == SetType.file ? ds.getIncludedFilesCount() : ds.getIncludedDirsCount(); if (type == SetType.both) { count += ds.getIncludedFilesCount(); } return count; } } }