/*
 *  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
 *
 *      http://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.ant.compress.taskdefs;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipException;

import org.apache.ant.compress.resources.ArFileSet;
import org.apache.ant.compress.resources.CommonsCompressArchiveResource;
import org.apache.ant.compress.resources.CpioFileSet;
import org.apache.ant.compress.resources.TarFileSet;
import org.apache.ant.compress.resources.TarResource;
import org.apache.ant.compress.resources.ZipFileSet;
import org.apache.ant.compress.resources.ZipResource;
import org.apache.ant.compress.util.ArchiveStreamFactory;
import org.apache.ant.compress.util.EntryHelper;
import org.apache.ant.compress.util.FileAwareArchiveStreamFactory;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ExtraFieldUtils;
import org.apache.commons.compress.archivers.zip.ZipExtraField;
import org.apache.commons.compress.archivers.zip.ZipShort;
import org.apache.commons.compress.utils.IOUtils;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.types.ArchiveFileSet;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.ArchiveResource;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.MappedResource;
import org.apache.tools.ant.types.resources.Resources;
import org.apache.tools.ant.types.resources.Restrict;
import org.apache.tools.ant.types.resources.selectors.Name;
import org.apache.tools.ant.types.resources.selectors.Not;
import org.apache.tools.ant.types.resources.selectors.Or;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.IdentityMapper;
import org.apache.tools.ant.util.MergingMapper;
import org.apache.tools.ant.util.ResourceUtils;
import org.apache.tools.zip.UnixStat;

/**
 * Base implementation of tasks creating archives.
 */
public abstract class ArchiveBase extends Task {
    private ArchiveStreamFactory factory;
    private FileSetBuilder fileSetBuilder;
    private EntryBuilder entryBuilder;

    private Resource dest;
    private List/*<ResourceCollection>*/ sources = new ArrayList();
    private Mode mode = new Mode();
    private String encoding;
    private boolean filesOnly = true;
    private boolean preserve0permissions = false;
    private boolean roundUp = true;
    private boolean preserveLeadingSlashes = false;
    private Duplicate duplicate = new Duplicate();
    private WhenEmpty emptyBehavior = new WhenEmpty();

    private static final String NO_SOURCES_MSG = "No sources, nothing to do.";

    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

    protected ArchiveBase() {}

    protected final void setFactory(ArchiveStreamFactory factory) {
        this.factory = factory;
    }

    protected final ArchiveStreamFactory getFactory() {
        return factory;
    }

    protected final void setEntryBuilder(EntryBuilder builder) {
        this.entryBuilder = builder;
    }

    protected final EntryBuilder getEntryBuilder() {
        return entryBuilder;
    }

    protected final void setFileSetBuilder(FileSetBuilder builder) {
        this.fileSetBuilder = builder;
    }

    protected final FileSetBuilder getFileSetBuilder() {
        return fileSetBuilder;
    }

    /**
     * The archive to create.
     */
    public void setDestfile(File f) {
        setDest(new FileResource(f));
    }

    /**
     * The archive to create.
     */
    public void addConfiguredDest(Resources r) {
        for (Iterator it = r.iterator(); it.hasNext(); ) {
            setDest((Resource) it.next());
        }
    }

    /**
     * The archive to create.
     */
    public void setDest(Resource r) {
        if (dest != null) {
            throw new BuildException("Can only have one destination resource"
                                     + " for archive.");
        }
        dest = r;
    }

    protected Resource getDest() {
        return dest;
    }

    /**
     * Sources for the archive.
     */
    public void add(ResourceCollection c) {
        sources.add(c);
    }

    /**
     * How to treat the target archive.
     */
    public void setMode(Mode m) {
        mode = m;
    }

    protected Mode getMode() {
        return mode;
    }

    /**
     * Encoding of file names.
     */
    public void setEncoding(String e) {
        encoding = e;
    }

    /**
     * Encoding of file names.
     */
    public String getEncoding() {
        return encoding;
    }

    /**
     * Whether only file entries should be added to the archive.
     */
    public void setFilesOnly(boolean b) {
        filesOnly = b;
    }

    /**
     * Whether only file entries should be added to the archive.
     */
    protected boolean isFilesOnly() {
        return filesOnly;
    }

    /**
     * Whether 0 permissions read from an archive should be considered
     * real permissions (that should be preserved) or missing
     * permissions (which is the default).
     */
    public void setPreserve0permissions(boolean b) {
        preserve0permissions = b;
    }

    /**
     * Whether the file modification times will be rounded up to the
     * next timestamp (second or even second depending on the archive
     * format).
     *
     * <p>Zip archives store file modification times with a
     * granularity of two seconds, ar, tar and cpio use a granularity
     * of one second.  Times will either be rounded up or down.  If
     * you round down, the archive will always seem out-of-date when
     * you rerun the task, so the default is to round up.  Rounding up
     * may lead to a different type of problems like JSPs inside a web
     * archive that seem to be slightly more recent than precompiled
     * pages, rendering precompilation useless.</p>
     * @param r a <code>boolean</code> value
     */
    public void setRoundUp(boolean r) {
        roundUp = r;
    }

    /**
     * Flag to indicates whether leading `/'s should
     * be preserved in the file names.
     * Optional, default is <code>false</code>.
     * @param b the leading slashes flag.
     */
    public void setPreserveLeadingSlashes(boolean b) {
        this.preserveLeadingSlashes = b;
    }

    /**
     * Sets behavior for when a duplicate file is about to be added -
     * one of <code>add</code>, <code>preserve</code> or <code>fail</code>.
     * Possible values are: <code>add</code> (keep both
     * of the files); <code>preserve</code> (keep the first version
     * of the file found); <code>fail</code> halt a problem
     * Default is <code>fail</code>
     * @param df a <code>Duplicate</code> enumerated value
     */
    public void setDuplicate(Duplicate df) {
        duplicate = df;
    }

    /**
     * Sets behavior of the task when no resources are to be added.
     * Possible values are: <code>fail</code> (throw an exception
     * and halt the build); <code>skip</code> (do not create
     * any archive, but issue a warning);.
     * Default is <code>fail</code>;
     * @param we a <code>WhenEmpty</code> enumerated value
     */
    public void setWhenempty(WhenEmpty we) {
        emptyBehavior = we;
    }

    public void execute() {
        validate();
        final Resource targetArchive = getDest();
        if (!targetArchive.isExists()) {
            // force create mode
            mode = new Mode();
            mode.setValue(Mode.FORCE_CREATE);
        }
        Collection sourceResources;
        try {
            sourceResources = findSources();
        } catch (IOException ioex) {
            throw new BuildException("Failed to read sources", ioex);
        }
        if (sourceResources.size() == 0) {
            if (WhenEmpty.SKIP.equals(emptyBehavior.getValue())) {
                log(NO_SOURCES_MSG, Project.MSG_WARN);
            } else {
                throw new BuildException(NO_SOURCES_MSG);
            }
        } else {
            File copyOfDest = maybeCopyTarget();
            Resource destOrCopy = copyOfDest == null
                ? targetArchive
                : new FileResource(copyOfDest);
            ArchiveFileSet existingEntries =
                fileSetBuilder.buildFileSet(destOrCopy);
            existingEntries.setProject(getProject());
            try {

                List/*<ResourceWithFlags>*/ toAdd
                    = new ArrayList/*<ResourceWithFlags>*/();
                toAdd.addAll(sourceResources);

                if (checkAndLogUpToDate(toAdd, targetArchive,
                                        existingEntries)) {
                    return;
                }

                addResourcesToKeep(toAdd, existingEntries, sourceResources);
                sort(toAdd);

                try {
                    writeArchive(toAdd);
                } catch (IOException ioex) {
                    throw new BuildException("Failed to write archive", ioex);
                }
            } finally {
                if (copyOfDest != null) {
                    FILE_UTILS.tryHardToDelete(copyOfDest);
                }
            }
        }
    }

    /**
     * Argument validation.
     */
    protected void validate() throws BuildException {
        if (factory == null) {
            throw new BuildException("subclass didn't provide a factory"
                                     + " instance");
        }
        if (entryBuilder == null) {
            throw new BuildException("subclass didn't provide an entryBuilder"
                                     + " instance");
        }
        if (fileSetBuilder == null) {
            throw new BuildException("subclass didn't provide a fileSetBuilder"
                                     + " instance");
        }
        if (getDest() == null) {
            throw new BuildException("must provide a destination resource");
        }
        if (sources.size() == 0) {
            throw new BuildException("must provide sources");
        }
    }

    /**
     * Find all the resources with their flags that should be added to
     * the archive.
     */
    protected Collection/*<ResourceWithFlags>*/ findSources()
        throws IOException {

        List/*<ResourceWithFlags>*/ l = new ArrayList/*<ResourceWithFlags>*/();
        Set/*<String>*/ addedNames = new HashSet/*<String>*/();
        for (Iterator rcs = sources.iterator(); rcs.hasNext(); ) {
            ResourceCollection rc = (ResourceCollection) rcs.next();
            ResourceCollectionFlags rcFlags = getFlags(rc);
            for (Iterator rs = rc.iterator(); rs.hasNext(); ) {
                Resource r = (Resource) rs.next();
                if (!isFilesOnly() || !r.isDirectory()) {
                    ResourceWithFlags rwf =
                        new ResourceWithFlags(r, rcFlags, getFlags(r));
                    String name = rwf.getName();
                    if (!"".equals(name) && !"/".equals(name)) {
                        boolean isDup = !addedNames.add(name);
                        if (!isDup || addDuplicate(name)) {
                            l.add(rwf);
                        }
                    }
                }
            }
        }
        return l;
    }

    private boolean checkAndLogUpToDate(Collection/*<ResourceWithFlags>*/ src,
                                        Resource targetArchive,
                                        ArchiveFileSet existingEntries) {
        try {
            if (!Mode.FORCE_CREATE.equals(getMode().getValue())
                && !Mode.FORCE_REPLACE.equals(getMode().getValue())
                && isUpToDate(src, existingEntries)) {
                log(targetArchive + " is up-to-date, nothing to do.");
                return true;
            }
        } catch (IOException ioex) {
            throw new BuildException("Failed to read target archive", ioex);
        }
        return false;
    }

    /**
     * Checks whether the target is more recent than the resources
     * that shall be added to it.
     *
     * <p>Will only ever be invoked if the target exists.</p>
     *
     * @param src the resources that have been found as sources, may
     * be modified in "update" mode to remove entries that are up to
     * date
     * @param existingEntries the target archive as fileset
     *
     * @return true if the target is up-to-date
     */
    protected boolean isUpToDate(Collection/*<ResourceWithFlags>*/ src,
                                 ArchiveFileSet existingEntries)
        throws IOException {

        final Resource[] srcResources = new Resource[src.size()];
        int index = 0;
        for (Iterator i = src.iterator(); i.hasNext(); ) {
            ResourceWithFlags r = (ResourceWithFlags) i.next();
            srcResources[index++] =
                new MappedResource(r.getResource(),
                                   new MergingMapper(r.getName()));
        }
        Resource[] outOfDate = ResourceUtils
            .selectOutOfDateSources(this, srcResources,
                                    new IdentityMapper(),
                                    existingEntries
                                    .getDirectoryScanner(getProject()));
        if (outOfDate.length > 0 && Mode.UPDATE.equals(getMode().getValue())) {
            HashSet/*<String>*/ oodNames = new HashSet/*<String>*/();
            for (int i = 0; i < outOfDate.length; i++) {
                oodNames.add(outOfDate[i].getName());
            }
            List/*<ResourceWithFlags>*/ copy =
                new LinkedList/*<ResourceWithFlags>*/(src);
            src.clear();
            for (Iterator i = copy.iterator(); i.hasNext(); ) {
                ResourceWithFlags r = (ResourceWithFlags) i.next();
                if (oodNames.contains(r.getName())) {
                    src.add(r);
                }
            }
        }
        return outOfDate.length == 0;
    }

    /**
     * Add the resources of the target archive that shall be kept when
     * creating the new one.
     */
    private void addResourcesToKeep(Collection/*<ResourceWithFlags>*/ toAdd,
                                    ArchiveFileSet target,
                                    Collection/*<ResourceWithFlags>*/ src) {
        if (!Mode.FORCE_CREATE.equals(getMode().getValue())
            && !Mode.CREATE.equals(getMode().getValue())) {
            try {
                toAdd.addAll(findUnmatchedTargets(target, src));
            } catch (IOException ioex) {
                throw new BuildException("Failed to read target archive", ioex);
            }
        }
    }

    /**
     * Find the resources from the target archive that don't have a
     * matching resource in the sources to be added.
     */
    protected Collection/*<ResourceWithFlags>*/
        findUnmatchedTargets(ArchiveFileSet target,
                             Collection/*<ResourceWithFlags>*/ src)
        throws IOException {

        List/*<ResourceWithFlags>*/ l = new ArrayList/*<ResourceWithFlags>*/();
        ResourceCollectionFlags rcFlags = getFlags(target);

        Restrict res = new Restrict();
        res.setProject(getProject());
        res.add(target);

        Not not = new Not();
        Or or = new Or();
        not.add(or);
        for (Iterator i = src.iterator(); i.hasNext(); ) {
            ResourceWithFlags r = (ResourceWithFlags) i.next();
            Name name = new Name();
            name.setName(r.getName());
            or.add(name);
        }
        res.add(not);

        for (Iterator rs = res.iterator(); rs.hasNext(); ) {
            Resource r = (Resource) rs.next();
            String name = r.getName();
            if ("".equals(name) || "/".equals(name)) {
                continue;
            }
            if (!isFilesOnly() || !r.isDirectory()) {
                l.add(new ResourceWithFlags(r, rcFlags, getFlags(r)));
            }
        }

        return l;
    }

    /**
     * Sorts the list of resources to add.
     */
    protected void sort(List/*<ResourceWithFlags>*/ l) {
        Collections.sort(l, new Comparator/*<ResourceWithFlags>*/() {
                public int compare(Object o1, Object o2) {
                    ResourceWithFlags r1 = (ResourceWithFlags) o1;
                    ResourceWithFlags r2 = (ResourceWithFlags) o2;
                    return r1.getName().compareTo(r2.getName());
                }
            });
    }

    /**
     * Creates the archive archiving the given resources.
     */
    protected void writeArchive(Collection/*<ResourceWithFlags>*/ src)
        throws IOException {
        ArchiveOutputStream out = null;
        Set addedDirectories = new HashSet();
        try {
            String enc = Expand.NATIVE_ENCODING.equals(getEncoding())
                ? null : getEncoding();
            if (factory instanceof FileAwareArchiveStreamFactory
                && getDest().as(FileProvider.class) != null) {
                FileProvider p =
                    (FileProvider) getDest().as(FileProvider.class);
                FileAwareArchiveStreamFactory f =
                    (FileAwareArchiveStreamFactory) factory;
                out = f.getArchiveOutputStream(p.getFile(), enc);
            } else {
                out =
                    factory.getArchiveStream(new BufferedOutputStream(getDest()
                                                                      .getOutputStream()),
                                             enc);
            }
            for (Iterator i = src.iterator(); i.hasNext(); ) {
                ResourceWithFlags r = (ResourceWithFlags) i.next();

                if (!isFilesOnly()) {
                    ensureParentDirs(out, r, addedDirectories);
                }

                ArchiveEntry ent = entryBuilder.buildEntry(r);
                out.putArchiveEntry(ent);
                if (!r.getResource().isDirectory()) {
                    InputStream in = null;
                    try {
                        in = r.getResource().getInputStream();
                        IOUtils.copy(in, out);
                    } finally {
                        FILE_UTILS.close(in);
                    }
                } else {
                    addedDirectories.add(r.getName());
                }
                out.closeArchiveEntry();

            }
        } finally {
            FILE_UTILS.close(out);
        }
    }

    /**
     * Adds records for all parent directories of the given resource
     * that haven't already been added.
     *
     * <p>Flags for the "missing" directories will be taken from the
     * ResourceCollection that contains the resource to be added.</p>
     */
    protected void ensureParentDirs(ArchiveOutputStream out,
                                    ResourceWithFlags r,
                                    Set directoriesAdded)
        throws IOException {

        String[] parentStack = FileUtils.getPathStack(r.getName());
        String currentParent = "";
        int skip = r.getName().endsWith("/") ? 2 : 1;
        for (int i = 0; i < parentStack.length - skip; i++) {
            if ("".equals(parentStack[i])) continue;
            currentParent += parentStack[i] + "/";
            if (directoriesAdded.add(currentParent)) {
                Resource dir = new Resource(currentParent, true,
                                            System.currentTimeMillis(),
                                            true);
                ResourceWithFlags artifical =
                    new ResourceWithFlags(currentParent,
                                          dir, r.getCollectionFlags(),
                                          new ResourceFlags());
                ArchiveEntry ent = entryBuilder.buildEntry(artifical);
                out.putArchiveEntry(ent);
                out.closeArchiveEntry();
            }
        }
    }

    /**
     * Extracts flags from a resource.
     *
     * <p>ZipExceptions are only here for the code that translates
     * Ant's ZipExtraFields to CC ZipExtraFields and should never
     * actually be thrown.</p>
     */
    protected ResourceFlags getFlags(Resource r) throws ZipException {
        if (r instanceof ArchiveResource) {
            if (r instanceof CommonsCompressArchiveResource) {
                if (r instanceof TarResource) {
                    TarResource tr = (TarResource) r;
                    return new ResourceFlags(tr.getMode(), tr.getUid(),
                                             tr.getGid(), tr.getUserName(),
                                             tr.getGroup());
                } else if (r instanceof ZipResource) {
                    ZipResource zr = (ZipResource) r;
                    return new ResourceFlags(zr.getMode(), zr.getExtraFields(),
                                             zr.getMethod());
                } else {
                    CommonsCompressArchiveResource cr =
                        (CommonsCompressArchiveResource) r;
                    return new ResourceFlags(cr.getMode(), cr.getUid(),
                                             cr.getGid());
                }
            } else if (r instanceof
                       org.apache.tools.ant.types.resources.TarResource) {
                org.apache.tools.ant.types.resources.TarResource tr =
                    (org.apache.tools.ant.types.resources.TarResource) r;
                return new ResourceFlags(tr.getMode(), tr.getUid(),
                                         tr.getGid(), tr.getUserName(),
                                         tr.getGroup());
            } else if (r instanceof
                       org.apache.tools.ant.types.resources.ZipResource) {
                org.apache.tools.ant.types.resources.ZipResource zr =
                    (org.apache.tools.ant.types.resources.ZipResource) r;

                org.apache.tools.zip.ZipExtraField[] extra = zr.getExtraFields();
                ZipExtraField[] ex =
                    new ZipExtraField[extra == null ? 0 : extra.length];
                if (extra != null && extra.length > 0) {
                    for (int i = 0; i < extra.length; i++) {
                        try {
                            ex[i] = ExtraFieldUtils
                                .createExtraField(new ZipShort(extra[i]
                                                               .getHeaderId()
                                                               .getValue()));
                        } catch (InstantiationException e) {
                            throw new BuildException(e);
                        } catch (IllegalAccessException e) {
                            throw new BuildException(e);
                        }
                        byte[] b = extra[i].getCentralDirectoryData();
                        ex[i].parseFromCentralDirectoryData(b, 0, b.length);
                        b = extra[i].getLocalFileDataData();
                        ex[i].parseFromLocalFileData(b, 0, b.length);
                    }
                }

                return new ResourceFlags(zr.getMode(), ex, zr.getMethod());
            } else {
                ArchiveResource ar = (ArchiveResource) r;
                return new ResourceFlags(ar.getMode());
            }
        }
        return new ResourceFlags();
    }

    /**
     * Extracts flags from a resource collection.
     */
    protected ResourceCollectionFlags getFlags(ResourceCollection rc) {
        if (rc instanceof ArchiveFileSet) {
            if (rc instanceof ArFileSet) {
                ArFileSet ar = (ArFileSet) rc;
                return new ResourceCollectionFlags(ar.getPrefix(getProject()),
                                                   ar.getFullpath(getProject()),
                                                   ar.hasFileModeBeenSet()
                                                   ? ar.getFileMode(getProject())
                                                   : -1,
                                                   ar.hasDirModeBeenSet()
                                                   ? ar.getDirMode(getProject())
                                                   : -1,
                                                   ar.hasUserIdBeenSet()
                                                   ? ar.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   ar.hasGroupIdBeenSet()
                                                   ? ar.getGid()
                                                   : EntryHelper.UNKNOWN_ID);
            } else if (rc instanceof CpioFileSet) {
                CpioFileSet cr = (CpioFileSet) rc;
                return new ResourceCollectionFlags(cr.getPrefix(getProject()),
                                                   cr.getFullpath(getProject()),
                                                   cr.hasFileModeBeenSet()
                                                   ? cr.getFileMode(getProject())
                                                   : -1,
                                                   cr.hasDirModeBeenSet()
                                                   ? cr.getDirMode(getProject())
                                                   : -1,
                                                   cr.hasUserIdBeenSet()
                                                   ? cr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   cr.hasGroupIdBeenSet()
                                                   ? cr.getGid()
                                                   : EntryHelper.UNKNOWN_ID);
            } else if (rc instanceof TarFileSet) {
                TarFileSet tr = (TarFileSet) rc;
                return new ResourceCollectionFlags(tr.getPrefix(getProject()),
                                                   tr.getFullpath(getProject()),
                                                   tr.hasFileModeBeenSet()
                                                   ? tr.getFileMode(getProject())
                                                   : -1,
                                                   tr.hasDirModeBeenSet()
                                                   ? tr.getDirMode(getProject())
                                                   : -1,
                                                   tr.hasUserIdBeenSet()
                                                   ? tr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasGroupIdBeenSet()
                                                   ? tr.getGid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasUserNameBeenSet()
                                                   ? tr.getUserName() : null,
                                                   tr.hasGroupBeenSet()
                                                   ? tr.getGroup() : null);
            } else if (rc instanceof
                       org.apache.tools.ant.types.TarFileSet) {
                org.apache.tools.ant.types.TarFileSet tr =
                    (org.apache.tools.ant.types.TarFileSet) rc;
                return new ResourceCollectionFlags(tr.getPrefix(getProject()),
                                                   tr.getFullpath(getProject()),
                                                   tr.hasFileModeBeenSet()
                                                   ? tr.getFileMode(getProject())
                                                   : -1,
                                                   tr.hasDirModeBeenSet()
                                                   ? tr.getDirMode(getProject())
                                                   : -1,
                                                   tr.hasUserIdBeenSet()
                                                   ? tr.getUid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasGroupIdBeenSet()
                                                   ? tr.getGid()
                                                   : EntryHelper.UNKNOWN_ID,
                                                   tr.hasUserNameBeenSet()
                                                   ? tr.getUserName() : null,
                                                   tr.hasGroupBeenSet()
                                                   ? tr.getGroup() : null);
            } else {
                ArchiveFileSet ar = (ArchiveFileSet) rc;
                return new ResourceCollectionFlags(ar.getPrefix(getProject()),
                                                   ar.getFullpath(getProject()),
                                                   ar.hasFileModeBeenSet()
                                                   ? ar.getFileMode(getProject())
                                                   : -1,
                                                   ar.hasDirModeBeenSet()
                                                   ? ar.getDirMode(getProject())
                                                   : -1);
            }
        }
        return new ResourceCollectionFlags();
    }

    /**
     * Ensures a forward slash is used as file separator and strips
     * leading slashes if preserveLeadingSlashes is false.
     */
    protected String bendSlashesForward(String s) {
        if (s != null) {
            s = s.replace('\\', '/');
            if (File.separatorChar != '/' && File.separatorChar != '\\') { 
                s = s.replace(File.separatorChar, '/');
            }
            while (!preserveLeadingSlashes && s.startsWith("/")) {
                s = s.substring(1);
            }
        }
        return s;
    }

    /**
     * Modify last modified timestamp based on the roundup attribute.
     *
     * @param millis the timestamp
     * @param granularity the granularity of timestamps in the archive
     * format in millis
     */
    protected long round(long millis, long granularity) {
        return roundUp ? millis + granularity - 1 : millis;
    }

    /**
     * Is invoked if a duplicate entry is found, decides whether the
     * entry shall be added regardless.
     */
    protected boolean addDuplicate(String name) {
        if (duplicate.getValue().equals(Duplicate.PRESERVE)) {
            log(name + " already added, skipping.", Project.MSG_INFO);
            return false;
        } else if (duplicate.getValue().equals(Duplicate.FAIL)) {
            throw new BuildException("Duplicate entry " + name
                                     + " was found and the duplicate "
                                     + "attribute is 'fail'.");
        }
        // duplicate equal to add, so we continue
        log("duplicate entry " + name + " found, adding.", Project.MSG_VERBOSE);
        return true;
    }

    /**
     * Creates a copy of the target archive in update or recreate mode
     * because some entries may later be read and archived from it.
     */
    private File maybeCopyTarget() {
        File copyOfDest = null;
        try {
            if (!Mode.FORCE_CREATE.equals(getMode().getValue())
                && !Mode.CREATE.equals(getMode().getValue())) {
                copyOfDest = FILE_UTILS.createTempFile(getTaskName(), ".tmp",
                                                       null, true, false);
                ResourceUtils.copyResource(getDest(),
                                           new FileResource(copyOfDest));
            }
        } catch (IOException ioex) {
            if (copyOfDest != null && copyOfDest.exists()) {
                FILE_UTILS.tryHardToDelete(copyOfDest);
            }
            throw new BuildException("Failed to copy target archive", ioex);
        }
        return copyOfDest;
    }

    /**
     * Valid Modes for create/update/replace.
     */
    public static final class Mode extends EnumeratedAttribute {

        /**
         * Create a new archive.
         */
        public static final String CREATE = "create";
        /**
         * Create a new archive even if the target exists and seems
         * up-to-date.
         */
        public static final String FORCE_CREATE = "force-create";
        /**
         * Update an existing archive.
         */
        public static final String UPDATE = "update";
        /**
         * Update an existing archive, replacing all existing entries
         * with those from sources.
         */
        public static final String REPLACE = "replace";
        /**
         * Update an existing archive - replacing all existing entries
         * with those from sources - even if the target exists and
         * seems up-to-date.
         */
        public static final String FORCE_REPLACE = "force-replace";

        public Mode() {
            super();
            setValue(CREATE);
        }

        public String[] getValues() {
            return new String[] {CREATE, UPDATE, REPLACE,
                                 FORCE_CREATE, FORCE_REPLACE};
        }

    }

    /**
     * Possible behaviors when a duplicate file is added:
     * "add", "preserve" or "fail"
     */
    public static class Duplicate extends EnumeratedAttribute {
        private static String ADD = "add";
        private static String PRESERVE = "preserve";
        private static String FAIL = "fail";

        public Duplicate() {
            setValue(FAIL);
        }

        /**
         * @see EnumeratedAttribute#getValues()
         */
        /** {@inheritDoc} */
        public String[] getValues() {
            return new String[] {ADD, PRESERVE, FAIL};
        }
    }

    /**
     * Possible behaviors when there are no matching files for the task:
     * "fail", "skip".
     */
    public static class WhenEmpty extends EnumeratedAttribute {
        private static String FAIL = "fail";
        private static String SKIP = "skip";

        public WhenEmpty() {
            setValue(FAIL);
        }

        /**
         * The string values for the enumerated value
         * @return the values
         */
        public String[] getValues() {
            return new String[] {FAIL, SKIP};
        }
    }

    /**
     * Various flags a (archive) resource may hold in addition to
     * being a plain resource.
     */
    public class ResourceFlags {
        private final int mode;
        private final boolean modeSet;
        private final int gid;
        private final int uid;
        private final ZipExtraField[] extraFields;
        private final String userName;
        private final String groupName;
        private final int compressionMethod;

        public ResourceFlags() {
            this(-1);
        }

        public ResourceFlags(int mode) {
            this(mode, new ZipExtraField[0], -1);
        }

        public ResourceFlags(int mode, ZipExtraField[] extraFields,
                             int compressionMethod) {
            this(mode, extraFields, EntryHelper.UNKNOWN_ID,
                 EntryHelper.UNKNOWN_ID, null, null,
                 compressionMethod);
        }

        public ResourceFlags(int mode, int uid, int gid) {
            this(mode, new ZipExtraField[0], uid, gid, null, null, -1);
        }

        public ResourceFlags(int mode, int uid, int gid, String userName,
                             String groupName) {
            this(mode, new ZipExtraField[0], uid, gid, userName, groupName, -1);
        }

        private ResourceFlags(int mode, ZipExtraField[] extraFields,
                              int uid, int gid,
                              String userName, String groupName,
                              int compressionMethod) {
            this.mode = mode;
            this.extraFields = extraFields;
            this.gid = gid;
            this.uid = uid;
            this.userName = userName;
            this.groupName = groupName;
            int m = mode & UnixStat.PERM_MASK;
            modeSet = mode >= 0 && (m > 0 || (m == 0 && preserve0permissions));
            this.compressionMethod = compressionMethod;
        }

        public boolean hasModeBeenSet() { return modeSet; }
        public int getMode() { return mode; }

        public ZipExtraField[] getZipExtraFields() { return extraFields; }

        public boolean hasUserIdBeenSet() {
            return uid != EntryHelper.UNKNOWN_ID;
        }
        public int getUserId() { return uid; }

        public boolean hasGroupIdBeenSet() {
            return gid != EntryHelper.UNKNOWN_ID;
        }
        public int getGroupId() { return gid; }

        public boolean hasUserNameBeenSet() { return userName != null; }
        public String getUserName() { return userName; }

        public boolean hasGroupNameBeenSet() { return groupName != null; }
        public String getGroupName() { return groupName; }

        public boolean hasCompressionMethod() { return compressionMethod >= 0; }
        public int getCompressionMethod() { return compressionMethod; }
    }

    /**
     * Various flags a (archive) resource collection may hold.
     */
    public class ResourceCollectionFlags extends ResourceFlags {
        private final String prefix, fullpath;
        private final int dirMode;

        public ResourceCollectionFlags() {
            this(null, null);
        }

        public ResourceCollectionFlags(String prefix, String fullpath) {
            this(prefix, fullpath, -1, -1);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode) {
            this(prefix, fullpath, fileMode, dirMode, EntryHelper.UNKNOWN_ID,
                 EntryHelper.UNKNOWN_ID);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode,
                                       int uid, int gid) {
            this(prefix, fullpath, fileMode, dirMode, uid, gid, null, null);
        }

        public ResourceCollectionFlags(String prefix, String fullpath,
                                       int fileMode, int dirMode,
                                       int uid, int gid,
                                       String userName, String groupName) {
            super(fileMode, uid, gid, userName, groupName);
            this.dirMode = dirMode;
            this.prefix = bendSlashesForward(prefix);
            this.fullpath = bendSlashesForward(fullpath);
        }

        public boolean hasDirModeBeenSet() { return dirMode >= 0; }
        public int getDirMode() { return dirMode; }

        public boolean hasPrefix() {
            return prefix != null && !"".equals(prefix);
        }
        public String getPrefix() { return prefix; }

        public boolean hasFullpath() {
            return fullpath != null && !"".equals(fullpath);
        }
        public String getFullpath() { return fullpath; }
    }

    /**
     * Binds a resource to additional data that may be present.
     */
    public class ResourceWithFlags {
        private final Resource r;
        private final ResourceCollectionFlags rcFlags;
        private final ResourceFlags rFlags;
        private final String name;

        public ResourceWithFlags(Resource r, ResourceCollectionFlags rcFlags,
                                 ResourceFlags rFlags) {
            this(null, r, rcFlags, rFlags);
        }

        public ResourceWithFlags(String name, Resource r,
                                 ResourceCollectionFlags rcFlags,
                                 ResourceFlags rFlags) {
            this.r = r;
            this.rcFlags = rcFlags;
            this.rFlags = rFlags;

            if (name == null) {
                name = r.getName();
                if (rcFlags.hasFullpath()) {
                    name = rcFlags.getFullpath();
                } else if (rcFlags.hasPrefix()) {
                    String prefix = rcFlags.getPrefix();
                    if (!prefix.endsWith("/")) {
                        prefix = prefix + "/";
                    }
                    name = prefix + name;
                }
                name = bendSlashesForward(name);
            }
            if (r.isDirectory() && !name.endsWith("/")) {
                name += "/";
            } else if (!r.isDirectory() && name.endsWith("/")) {
                name = name.substring(0, name.length() - 1);
            }

            this.name = name;
        }

        public Resource getResource() { return r; }
        public ResourceCollectionFlags getCollectionFlags() { return rcFlags; }
        public ResourceFlags getResourceFlags() { return rFlags; }

        /**
         * The name the target entry will have.
         *
         * <p>Already takes fullpath and prefix into account.</p>
         *
         * <p>Ensures directory names end in slashes while file names
         * never will.</p>
         */
        public String getName() {
            return name;
        }
    }

    /**
     * Creates an archive entry for the concrete format.
     */
    public static interface EntryBuilder {
        ArchiveEntry buildEntry(ResourceWithFlags resource);
    }

    /**
     * Creates an archive fileset to read the target archive.
     */
    public static interface FileSetBuilder {
        ArchiveFileSet buildFileSet(Resource dest);
    }
}
