/*
 * 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.lenya.cms.publication;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.cocoon.util.AbstractLogEnabled;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataException;
import org.apache.lenya.cms.publication.util.DocumentSet;
import org.apache.lenya.cms.publication.util.DocumentVisitor;
import org.apache.lenya.cms.repository.Node;
import org.apache.lenya.cms.repository.NodeFactory;
import org.apache.lenya.cms.repository.UUIDGenerator;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.NodeIterator;
import org.apache.lenya.cms.site.NodeSet;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteManager;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.cms.site.SiteUtil;

/**
 * DocumentManager implementation.
 * 
 * @version $Id$
 */
public class DocumentManagerImpl extends AbstractLogEnabled implements DocumentManager {

    private SourceResolver sourceResolver;
    private UUIDGenerator uuidGenerator;
    private NodeFactory nodeFactory;

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#add(org.apache.lenya.cms.publication.Document,
     *      java.lang.String, java.lang.String, java.lang.String, java.lang.String,
     *      java.lang.String, boolean)
     */
    public Document add(Document sourceDocument, String area, String path, String language,
            String extension, String navigationTitle, boolean visibleInNav)
            throws DocumentBuildException, PublicationException {

        Document document = add(sourceDocument.getResourceType(), sourceDocument.getInputStream(),
                sourceDocument.getPublication(), area, path, language, extension, navigationTitle,
                visibleInNav, sourceDocument.getMimeType());

        copyMetaData(sourceDocument, document);
        return document;
    }

    /**
     * Copies meta data from one document to another. If the destination document is a different
     * area version, the meta data are duplicated (i.e., onCopy = delete is neglected).
     * @param source
     * @param destination
     * @throws PublicationException
     */
    protected void copyMetaData(Document source, Document destination) throws PublicationException {

        boolean duplicate = source.getUUID().equals(destination.getUUID())
                && source.getLanguage().equals(destination.getLanguage())
                && !source.getArea().equals(destination.getArea());

        try {
            String[] uris = source.getMetaDataNamespaceUris();
            for (int i = 0; i < uris.length; i++) {
                if (duplicate) {
                    destination.getMetaData(uris[i]).forcedReplaceBy(source.getMetaData(uris[i]));
                } else {
                    destination.getMetaData(uris[i]).replaceBy(source.getMetaData(uris[i]));
                }
            }
        } catch (MetaDataException e) {
            throw new PublicationException(e);
        }
    }

    public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
            String area, String path, String language, String extension, String navigationTitle,
            boolean visibleInNav) throws DocumentBuildException, DocumentException,
            PublicationException {

        Area areaObj = pub.getArea(area);
        SiteStructure site = areaObj.getSite();
        if (site.contains(path) && site.getNode(path).hasLink(language)) {
            throw new DocumentException("The link [" + path + ":" + language
                    + "] is already contained in site [" + site + "]");
        }

        Document document = add(documentType, initialContentsURI, pub, area, language, extension);

        addToSiteManager(path, document, navigationTitle, visibleInNav);
        return document;
    }

    protected Document add(ResourceType documentType, InputStream initialContentsStream,
            Publication pub, String area, String path, String language, String extension,
            String navigationTitle, boolean visibleInNav, String mimeType)
            throws DocumentBuildException, DocumentException, PublicationException {

        Area areaObj = pub.getArea(area);
        SiteStructure site = areaObj.getSite();
        if (site.contains(path) && site.getNode(path).hasLink(language)) {
            throw new DocumentException("The link [" + path + ":" + language
                    + "] is already contained in site [" + site + "]");
        }

        Document document = add(documentType, initialContentsStream, pub, area, language,
                extension, mimeType);

        addToSiteManager(path, document, navigationTitle, visibleInNav);
        return document;
    }

    public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
            String area, String language, String extension) throws DocumentBuildException,
            DocumentException, PublicationException {

        String uuid = getUuidGenerator().nextUUID();
        Source source = null;
        try {
            source = getSourceResolver().resolveURI(initialContentsURI);
            return add(documentType, uuid, source.getInputStream(), pub, area, language, extension,
                    getMimeType(source));
        } catch (Exception e) {
            throw new PublicationException(e);
        } finally {
            if (source != null) {
                getSourceResolver().release(source);
            }
        }
    }

    protected String getMimeType(Source source) {
        String mimeType = source.getMimeType();
        if (mimeType == null) {
            mimeType = "";
        }
        return mimeType;
    }

    protected Document add(ResourceType documentType, InputStream initialContentsStream,
            Publication pub, String area, String language, String extension, String mimeType)
            throws DocumentBuildException, DocumentException, PublicationException {

        String uuid = getUuidGenerator().nextUUID();
        return add(documentType, uuid, initialContentsStream, pub, area, language, extension,
                mimeType);
    }

    protected Document add(ResourceType documentType, String uuid, InputStream stream,
            Publication pub, String area, String language, String extension, String mimeType)
            throws DocumentBuildException {
        try {

            Area areaObj = pub.getArea(area);
            if (areaObj.contains(uuid, language)) {
                throw new DocumentBuildException("The document [" + pub.getId() + ":" + area + ":"
                        + uuid + ":" + language + "] already exists!");
            }

            Document document = areaObj.getDocument(uuid, language);
            document.lock();

            document.setResourceType(documentType);
            document.setSourceExtension(extension);
            document.setMimeType(mimeType);

            // Write Lenya-internal meta-data
            MetaData lenyaMetaData = document.getMetaData(DocumentImpl.METADATA_NAMESPACE);
            lenyaMetaData.setValue(DocumentImpl.METADATA_CONTENT_TYPE, "xml");

            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Create");
                getLogger().debug("    document:     [" + document + "]");
            }

            create(stream, document);
            return document;
        } catch (Exception e) {
            throw new DocumentBuildException("call to creator for new document failed", e);
        }
    }

    protected void create(InputStream stream, Document document) throws Exception {

        // Read initial contents as DOM
        if (getLogger().isDebugEnabled())
            getLogger().debug(
                    "DefaultCreator::create(), ready to read initial contents from URI [" + stream
                            + "]");

        copy(getSourceResolver(), stream, document);
    }

    protected void copy(SourceResolver resolver, InputStream sourceInputStream, Document destination)
            throws IOException {

        boolean useBuffer = true;

        OutputStream destOutputStream = null;
        try {
            destOutputStream = destination.getOutputStream();

            if (useBuffer) {
                final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
                IOUtils.copy(sourceInputStream, sourceBos);
                IOUtils.write(sourceBos.toByteArray(), destOutputStream);
            } else {
                IOUtils.copy(sourceInputStream, destOutputStream);
            }
        } finally {
            if (destOutputStream != null) {
                destOutputStream.flush();
                destOutputStream.close();
            }
            if (sourceInputStream != null) {
                sourceInputStream.close();
            }
        }
    }

    protected void addToSiteManager(String path, Document document, String navigationTitle,
            boolean visibleInNav) throws PublicationException {
        addToSiteManager(path, document, navigationTitle, visibleInNav, null);
    }

    protected void addToSiteManager(String path, Document document, String navigationTitle,
            boolean visibleInNav, String followingSiblingPath) throws PublicationException {
        SiteStructure site = document.area().getSite();
        if (!site.contains(path) && followingSiblingPath != null) {
            site.add(path, followingSiblingPath);
        }
        site.add(path, document);
        document.getLink().setLabel(navigationTitle);
        document.getLink().getNode().setVisible(visibleInNav);
    }

    /**
     * Template method to copy a document. Override {@link #copyDocumentSource(Document, Document)}
     * to implement access to a custom repository.
     * @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.Document,
     *      org.apache.lenya.cms.publication.DocumentLocator)
     */
    public void copy(Document sourceDoc, DocumentLocator destination) throws PublicationException {

        if (!destination.getPublicationId().equals(sourceDoc.getPublication().getId())) {
            throw new PublicationException("Can't copy to a different publication!");
        }

        SiteStructure destSite = sourceDoc.getPublication().getArea(destination.getArea())
                .getSite();
        String destPath = destination.getPath();
        if (destSite.contains(destination.getPath(), destination.getLanguage())) {
            Document destDoc = destSite.getNode(destPath).getLink(destination.getLanguage())
                    .getDocument();
            copyDocumentSource(sourceDoc, destDoc);
            copyInSiteStructure(sourceDoc, destDoc, destPath);
        } else {
            add(sourceDoc, destination.getArea(), destPath, destination.getLanguage(), sourceDoc
                    .getExtension(), sourceDoc.getLink().getLabel(), sourceDoc.getLink().getNode()
                    .isVisible());
        }

    }

    protected void copyInSiteStructure(Document sourceDoc, Document destDoc, String destPath)
            throws PublicationException, DocumentException, SiteException {

        String destArea = destDoc.getArea();

        SiteStructure destSite = sourceDoc.getPublication().getArea(destArea).getSite();

        if (sourceDoc.hasLink()) {
            if (destDoc.hasLink()) {
                Link srcLink = sourceDoc.getLink();
                Link destLink = destDoc.getLink();
                destLink.setLabel(srcLink.getLabel());
                destLink.getNode().setVisible(srcLink.getNode().isVisible());
            } else {
                String label = sourceDoc.getLink().getLabel();
                boolean visible = sourceDoc.getLink().getNode().isVisible();
                if (destSite.contains(sourceDoc.getLink().getNode().getPath())) {
                    addToSiteManager(destPath, destDoc, label, visible);
                } else {

                    String followingSiblingPath = null;

                    if (sourceDoc.getPath().equals(destPath)) {
                        SiteStructure sourceSite = sourceDoc.area().getSite();

                        SiteNode[] sourceSiblings;
                        SiteNode sourceNode = sourceDoc.getLink().getNode();
                        if (sourceNode.isTopLevel()) {
                            sourceSiblings = sourceSite.getTopLevelNodes();
                        } else if (sourceNode.getParent() != null) {
                            sourceSiblings = sourceNode.getParent().getChildren();
                        } else {
                            sourceSiblings = new SiteNode[1];
                            sourceSiblings[0] = sourceNode;
                        }

                        final int sourcePos = Arrays.asList(sourceSiblings).indexOf(sourceNode);

                        int pos = sourcePos;
                        while (followingSiblingPath == null && pos < sourceSiblings.length) {
                            String siblingPath = sourceSiblings[pos].getPath();
                            if (destSite.contains(siblingPath)) {
                                followingSiblingPath = siblingPath;
                            }
                            pos++;
                        }
                    }

                    if (followingSiblingPath == null) {
                        addToSiteManager(destPath, destDoc, label, visible);
                    } else {
                        addToSiteManager(destPath, destDoc, label, visible, followingSiblingPath);
                    }
                }
            }
        }
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.Document)
     */
    public void delete(Document document) throws PublicationException {
        if (!document.exists()) {
            throw new PublicationException("Document [" + document + "] does not exist!");
        }

        if (document.hasLink()) {
            document.getLink().delete();
        }

        document.delete();
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.Document,
     *      org.apache.lenya.cms.publication.DocumentLocator)
     */
    public void move(Document sourceDocument, DocumentLocator destination)
            throws PublicationException {

        if (!destination.getArea().equals(sourceDocument.getArea())) {
            throw new PublicationException("Can't move to a different area!");
        }

        SiteStructure site = sourceDocument.area().getSite();
        if (site.contains(destination.getPath())) {
            throw new PublicationException("The path [" + destination
                    + "] is already contained in this publication!");
        }

        String label = sourceDocument.getLink().getLabel();
        boolean visible = sourceDocument.getLink().getNode().isVisible();
        sourceDocument.getLink().delete();

        site.add(destination.getPath(), sourceDocument);
        sourceDocument.getLink().setLabel(label);
        sourceDocument.getLink().getNode().setVisible(visible);

    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.Document,
     *      java.lang.String)
     */
    public void copyToArea(Document sourceDoc, String destinationArea) throws PublicationException {
        String language = sourceDoc.getLanguage();
        copyToVersion(sourceDoc, destinationArea, language);
    }

    protected void copyToVersion(Document sourceDoc, String destinationArea, String language)
            throws DocumentException, DocumentBuildException, PublicationException, SiteException {

        Document destDoc;
        if (sourceDoc.existsAreaVersion(destinationArea)) {
            destDoc = sourceDoc.getAreaVersion(destinationArea);
            copyDocumentSource(sourceDoc, destDoc);
        } else {
            destDoc = addVersion(sourceDoc, destinationArea, language);
        }

        if (sourceDoc.hasLink()) {
            copyInSiteStructure(sourceDoc, destDoc, sourceDoc.getPath());
        }
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.util.DocumentSet,
     *      java.lang.String)
     */
    public void copyToArea(DocumentSet documentSet, String destinationArea)
            throws PublicationException {
        Document[] documents = documentSet.getDocuments();
        for (int i = 0; i < documents.length; i++) {
            copyToArea(documents[i], destinationArea);
        }
    }

    public void moveAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
            throws PublicationException {
        SiteStructure site = sourceArea.getSite();

        SiteNode root = site.getNode(sourcePath);
        List subsite = preOrder(root);

        for (Iterator n = subsite.iterator(); n.hasNext();) {
            SiteNode node = (SiteNode) n.next();
            String subPath = node.getPath().substring(sourcePath.length());
            targetArea.getSite().add(targetPath + subPath);
        }
        Collections.reverse(subsite);
        for (Iterator n = subsite.iterator(); n.hasNext();) {
            SiteNode node = (SiteNode) n.next();
            String subPath = node.getPath().substring(sourcePath.length());
            moveAllLanguageVersions(sourceArea, sourcePath + subPath, targetArea, targetPath
                    + subPath);
        }
    }

    protected List preOrder(SiteNode node) {
        List list = new ArrayList();
        list.add(node);
        SiteNode[] children = node.getChildren();
        for (int i = 0; i < children.length; i++) {
            list.addAll(preOrder(children[i]));
        }
        return list;
    }

    public void moveAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
            String targetPath) throws PublicationException {

        SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
        String[] languages = sourceNode.getLanguages();
        for (int i = 0; i < languages.length; i++) {
            Link sourceLink = sourceNode.getLink(languages[i]);
            String label = sourceLink.getLabel();
            Document sourceDoc = sourceLink.getDocument();
            sourceLink.delete();

            Document targetDoc;
            if (sourceArea.getName().equals(targetArea.getName())) {
                targetDoc = sourceDoc;
            } else {
                targetDoc = addVersion(sourceDoc, targetArea.getName(), sourceDoc.getLanguage());
                copyRevisions(sourceDoc, targetDoc);
                sourceDoc.delete();
            }

            Link link = targetArea.getSite().add(targetPath, targetDoc);
            link.setLabel(label);
            assert targetDoc.getLink().getLabel().equals(label);
        }
        SiteNode targetNode = targetArea.getSite().getNode(targetPath);
        targetNode.setVisible(sourceNode.isVisible());
    }

    protected void copyRevisions(Document sourceDoc, Document targetDoc)
            throws PublicationException {
        try {
            Node targetNode = ((DocumentImpl) targetDoc).getRepositoryNode();
            targetNode.copyRevisionsFrom(((DocumentImpl) sourceDoc).getRepositoryNode());
        } catch (Exception e) {
            throw new PublicationException(e);
        }
    }

    public void copyAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
            throws PublicationException {

        SiteStructure site = sourceArea.getSite();
        SiteNode root = site.getNode(sourcePath);

        List preOrder = preOrder(root);
        for (Iterator i = preOrder.iterator(); i.hasNext();) {
            SiteNode node = (SiteNode) i.next();
            String nodeSourcePath = node.getPath();
            String nodeTargetPath = targetPath + nodeSourcePath.substring(sourcePath.length());
            copyAllLanguageVersions(sourceArea, nodeSourcePath, targetArea, nodeTargetPath);
        }
    }

    public void copyAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
            String targetPath) throws PublicationException {
        Publication pub = sourceArea.getPublication();

        SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
        String[] languages = sourceNode.getLanguages();

        Document targetDoc = null;

        for (int i = 0; i < languages.length; i++) {
            Document sourceVersion = sourceNode.getLink(languages[i]).getDocument();
            DocumentLocator targetLocator = DocumentLocator.getLocator(pub.getId(), targetArea
                    .getName(), targetPath, languages[i]);
            if (targetDoc == null) {
                copy(sourceVersion, targetLocator.getLanguageVersion(languages[i]));
                targetDoc = targetArea.getSite().getNode(targetPath).getLink(languages[i])
                        .getDocument();
            } else {
                targetDoc = addVersion(targetDoc, targetLocator.getArea(), languages[i]);
                addToSiteManager(targetLocator.getPath(), targetDoc, sourceVersion.getLink()
                        .getLabel(), sourceVersion.getLink().getNode().isVisible());
                copyDocumentSource(sourceVersion, targetDoc);
            }
        }
    }

    /**
     * Copies a document source.
     * @param sourceDocument The source document.
     * @param destinationDocument The destination document.
     * @throws PublicationException when something went wrong.
     */
    public void copyDocumentSource(Document sourceDocument, Document destinationDocument)
            throws PublicationException {
        copyContent(sourceDocument, destinationDocument);
        copyMetaData(sourceDocument, destinationDocument);
    }

    protected void copyContent(Document sourceDocument, Document destinationDocument)
            throws PublicationException {
        boolean useBuffer = true;

        OutputStream destOutputStream = null;
        InputStream sourceInputStream = null;
        try {
            try {
                sourceInputStream = sourceDocument.getInputStream();
                destOutputStream = destinationDocument.getOutputStream();

                if (useBuffer) {
                    final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
                    IOUtils.copy(sourceInputStream, sourceBos);
                    IOUtils.write(sourceBos.toByteArray(), destOutputStream);
                } else {
                    IOUtils.copy(sourceInputStream, destOutputStream);
                }
            } finally {
                if (destOutputStream != null) {
                    destOutputStream.flush();
                    destOutputStream.close();
                }
                if (sourceInputStream != null) {
                    sourceInputStream.close();
                }
            }
        } catch (Exception e) {
            throw new PublicationException(e);
        }
    }

    /**
     * Abstract base class for document visitors which operate on a source and target document.
     */
    public static abstract class SourceTargetVisitor implements DocumentVisitor {

        private DocumentLocator rootSource;
        private DocumentLocator rootTarget;
        private DocumentManager manager;

        /**
         * Ctor.
         * @param manager The document manager.
         * @param source The root source.
         * @param target The root target.
         */
        public SourceTargetVisitor(DocumentManager manager, Document source, DocumentLocator target) {
            this.manager = manager;
            this.rootSource = source.getLocator();
            this.rootTarget = target;
        }

        /**
         * @return the root source
         */
        protected DocumentLocator getRootSource() {
            return rootSource;
        }

        /**
         * @return the root target
         */
        protected DocumentLocator getRootTarget() {
            return rootTarget;
        }

        /**
         * @return the document manager
         */
        protected DocumentManager getDocumentManager() {
            return this.manager;
        }

        /**
         * Returns the target corresponding to a source relatively to the root target document.
         * @param source The source.
         * @return A document.
         * @throws DocumentBuildException if the target could not be built.
         */
        protected DocumentLocator getTarget(Document source) throws DocumentBuildException {
            DocumentLocator sourceLocator = source.getLocator();
            String rootSourcePath = getRootSource().getPath();
            if (sourceLocator.getPath().equals(rootSourcePath)) {
                return rootTarget;
            } else {
                String relativePath = sourceLocator.getPath().substring(rootSourcePath.length());
                return rootTarget.getDescendant(relativePath);
            }
        }
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#deleteAll(org.apache.lenya.cms.publication.Document)
     */
    public void deleteAll(Document document) throws PublicationException {
        NodeSet subsite = SiteUtil.getSubSite(document.getLink().getNode());
        for (NodeIterator i = subsite.descending(); i.hasNext();) {
            SiteNode node = i.next();
            String[] languages = node.getLanguages();
            for (int l = 0; l < languages.length; l++) {
                Document doc = node.getLink(languages[l]).getDocument();
                delete(doc);
            }
        }
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#deleteAllLanguageVersions(org.apache.lenya.cms.publication.Document)
     */
    public void deleteAllLanguageVersions(Document document) throws PublicationException {
        String[] languages = document.getLanguages();
        for (int i = 0; i < languages.length; i++) {
            delete(document.getTranslation(languages[i]));
        }
    }

    /**
     * Visitor to delete documents.
     */
    public static class DeleteVisitor implements DocumentVisitor {

        private DocumentManager manager;

        /**
         * Ctor.
         * @param manager The document manager.
         */
        public DeleteVisitor(DocumentManager manager) {
            this.manager = manager;
        }

        protected DocumentManager getDocumentManager() {
            return this.manager;
        }

        /**
         * @see org.apache.lenya.cms.publication.util.DocumentVisitor#visitDocument(org.apache.lenya.cms.publication.Document)
         */
        public void visitDocument(Document document) throws PublicationException {
            getDocumentManager().deleteAllLanguageVersions(document);
        }

    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public void delete(DocumentSet documents) throws PublicationException {

        if (documents.isEmpty()) {
            return;
        }

        DocumentSet set = new DocumentSet(documents.getDocuments());
        sortAscending(set);
        set.reverse();

        DocumentVisitor visitor = new DeleteVisitor(this);
        try {
            set.visit(visitor);
        } catch (Exception e) {
            throw new PublicationException(e);
        }

    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.util.DocumentSet,
     *      org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public void move(DocumentSet sources, DocumentSet destinations) throws PublicationException {
        copy(sources, destinations);
        delete(sources);
        /*
         * Document[] sourceDocs = sources.getDocuments(); Document[] targetDocs =
         * destinations.getDocuments();
         * 
         * if (sourceDocs.length != targetDocs.length) { throw new PublicationException( "The number
         * of source and destination documents must be equal!"); }
         * 
         * Map source2target = new HashMap(); for (int i = 0; i < sourceDocs.length; i++) {
         * source2target.put(sourceDocs[i], targetDocs[i]); }
         * 
         * DocumentSet sortedSources = new DocumentSet(sourceDocs);
         * SiteUtil.sortAscending(this.manager, sortedSources); Document[] sortedSourceDocs =
         * sortedSources.getDocuments();
         * 
         * for (int i = 0; i < sortedSourceDocs.length; i++) { move(sortedSourceDocs[i], (Document)
         * source2target.get(sortedSourceDocs[i])); }
         */
    }

    /**
     * @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.util.DocumentSet,
     *      org.apache.lenya.cms.publication.util.DocumentSet)
     */
    public void copy(DocumentSet sources, DocumentSet destinations) throws PublicationException {
        Document[] sourceDocs = sources.getDocuments();
        Document[] targetDocs = destinations.getDocuments();

        if (sourceDocs.length != targetDocs.length) {
            throw new PublicationException(
                    "The number of source and destination documents must be equal!");
        }

        Map source2target = new HashMap();
        for (int i = 0; i < sourceDocs.length; i++) {
            source2target.put(sourceDocs[i], targetDocs[i]);
        }

        DocumentSet sortedSources = new DocumentSet(sourceDocs);
        sortAscending(sortedSources);
        Document[] sortedSourceDocs = sortedSources.getDocuments();

        for (int i = 0; i < sortedSourceDocs.length; i++) {
            copy(sortedSourceDocs[i], ((Document) source2target.get(sortedSourceDocs[i]))
                    .getLocator());
        }
    }

    protected void sortAscending(DocumentSet set) throws PublicationException {

        if (!set.isEmpty()) {

            Document[] docs = set.getDocuments();
            int n = docs.length;

            Publication pub = docs[0].getPublication();
            SiteManager siteManager = (SiteManager) WebAppContextUtils
                    .getCurrentWebApplicationContext().getBean(
                            SiteManager.class.getName() + "/" + pub.getSiteManagerHint());

            Set nodes = new HashSet();
            for (int i = 0; i < docs.length; i++) {
                nodes.add(docs[i].getLink().getNode());
            }

            SiteNode[] ascending = siteManager.sortAscending((SiteNode[]) nodes
                    .toArray(new SiteNode[nodes.size()]));

            set.clear();
            for (int i = 0; i < ascending.length; i++) {
                for (int d = 0; d < docs.length; d++) {
                    if (docs[d].getPath().equals(ascending[i].getPath())) {
                        set.add(docs[d]);
                    }
                }
            }

            if (set.getDocuments().length != n) {
                throw new IllegalStateException("Number of documents has changed!");
            }

        }
    }

    public Document addVersion(Document sourceDocument, String area, String language,
            boolean addToSiteStructure) throws DocumentBuildException, PublicationException {
        Document document = addVersion(sourceDocument, area, language);

        if (addToSiteStructure && sourceDocument.hasLink()) {
            String path = sourceDocument.getPath();
            boolean visible = sourceDocument.getLink().getNode().isVisible();
            addToSiteManager(path, document, sourceDocument.getLink().getLabel(), visible);
        }

        return document;
    }

    public Document addVersion(Document sourceDocument, String area, String language)
            throws DocumentBuildException, DocumentException, PublicationException {
        Document document = add(sourceDocument.getResourceType(), sourceDocument.getUUID(),
                sourceDocument.getInputStream(), sourceDocument.getPublication(), area, language,
                sourceDocument.getSourceExtension(), sourceDocument.getMimeType());
        copyMetaData(sourceDocument, document);

        return document;
    }

    public SourceResolver getSourceResolver() {
        return sourceResolver;
    }

    public void setSourceResolver(SourceResolver sourceResolver) {
        this.sourceResolver = sourceResolver;
    }

    public UUIDGenerator getUuidGenerator() {
        return uuidGenerator;
    }

    public void setUuidGenerator(UUIDGenerator uuidGenerator) {
        this.uuidGenerator = uuidGenerator;
    }

    public NodeFactory getNodeFactory() {
        return nodeFactory;
    }

    public void setNodeFactory(NodeFactory nodeFactory) {
        this.nodeFactory = nodeFactory;
    }

}
