/*
 * 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.cocoon.source;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.excalibur.source.ModifiableSource;
import org.apache.excalibur.source.ModifiableTraversableSource;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.publication.RepositoryException;
import org.apache.lenya.xml.DocumentHelper;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * @version $Id$
 * @deprecated use o.a.l.utils.SourceUtil instead see the usage of sourceutils.checkin and checkout functions not keep in o.a.l.utils.SourceUtil
 * because they are related to lenyaDocument and not really to sources
 */
public final class SourceUtil {

    /**
     * <p>
     * Copies one Source to another using a source buffer i.e. the source Source is buffered before
     * it is copied to its final destination.
     * </p>
     * <p>
     * The optional buffering is sometimes useful, if the source Source somehow depends on the
     * destination Source. This situation may occur e.g. if source Source is a Cocoon pipeline.
     * </p>
     * <p>
     * <em>NOTE:</em> o.a.e..s.SourceUtil.copy does not close streams on an exception!!
     * </p>
     * @param source
     * @param destination
     * @param useBuffer If true, the source data will be read into a buffer before it is written to
     *            the final destination.
     * @throws IOException If an error occures.
     */
    public static void copy(Source source, ModifiableSource destination, boolean useBuffer)
            throws IOException {
        InputStream sourceInputStream = null;
        OutputStream destOutputStream = null;
        try {
            sourceInputStream = source.getInputStream();
            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();
            }
        }
    }

    /**
     * Copies one Source to another. The source Source is optionally buffered.
     * @param resolver The SourceResolver to use for lookin up Sources.
     * @param sourceUri The source to be copied.
     * @param destUri The URI to copy to.
     * @param useBuffer If true, the source Source is buffered before copied to the final
     *            destination.
     * @throws IOException If an error occures.
     * @throws SourceException If the destination is not modifiable.
     * @see #copy(Source, ModifiableSource, boolean)
     */
    public static void copy(SourceResolver resolver, String sourceUri, String destUri,
            boolean useBuffer) throws IOException, SourceException {
        Source source = null;
        Source dest = null;
        try {
            source = resolver.resolveURI(sourceUri);
            dest = resolver.resolveURI(destUri);

            if (!(dest instanceof ModifiableSource))
                throw new SourceException("Destination '" + dest.getURI() + "' is not modifiable.");

            copy(source, (ModifiableSource) dest, useBuffer);
        } finally {
            if (source != null)
                resolver.release(source);
            if (dest != null)
                resolver.release(dest);
        }
    }

    /**
     * Copies a Source without buffering.
     * @param resolver A SourceResolver instance.
     * @param sourceUri The source URI to copy from.
     * @param destUri The destination URI to copy to.
     * @throws IOException If an error occures.
     * @see #copy(SourceResolver, String, String, boolean)
     */
    public static void copy(SourceResolver resolver, String sourceUri, String destUri)
            throws IOException {
        copy(resolver, sourceUri, destUri, false);
    }

    /**
     * Copies a Source without buffering.
     * @param manager A service manager.
     * @param sourceUri The source URI to copy from.
     * @param destUri The destination URI to copy to.
     * @throws IOException If an error occures.
     * @throws ServiceException
     * @see #copy(SourceResolver, String, String, boolean)
     */
    public static void copy(ServiceManager manager, String sourceUri, String destUri)
            throws IOException, ServiceException {
        SourceResolver resolver = null;
        try {
            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            copy(resolver, sourceUri, destUri, false);
        } finally {
            if (resolver != null) {
                manager.release(resolver);
            }
        }
    }

    /**
     * Reads a DOM from a source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A document or <code>null</code> if the source does not exist.
     * @throws ServiceException if an error occurs.
     * @throws SourceNotFoundException if an error occurs.
     * @throws ParserConfigurationException if an error occurs.
     * @throws SAXException if an error occurs.
     * @throws IOException if an error occurs.
     * @deprecated
     */
    public static Document readDOM(String sourceUri, ServiceManager manager)
            throws ServiceException, SourceNotFoundException, ParserConfigurationException,
            SAXException, IOException {
        SourceResolver resolver = null;
        Source source = null;
        Document document = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = resolver.resolveURI(sourceUri);

            if (source.exists()) {
                document = DocumentHelper.readDocument(source.getInputStream());
            }
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
        return document;
    }

    /**
     * Reads a DOM from a source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A document or <code>null</code> if the source does not exist.
     * @throws SourceNotFoundException if an error occurs.
     * @throws ParserConfigurationException if an error occurs.
     * @throws SAXException if an error occurs.
     * @throws IOException if an error occurs.
     */
    public static Document readDOM(String sourceUri, SourceResolver resolver)
            throws SourceNotFoundException, ParserConfigurationException, SAXException, IOException {
        Source source = null;
        Document document = null;
        try {
            source = resolver.resolveURI(sourceUri);
            if (source.exists()) {
                document = DocumentHelper.readDocument(source.getInputStream());
            }
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
            }
        }
        return document;
    }

    /**
     * Writes a DOM to a source.
     * @param document The document.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws TransformerConfigurationException if an error occurs.
     * @throws TransformerException if an error occurs.
     * @throws ServiceException if the source resolver could not be obtained.
     * @throws MalformedURLException if the source URI is not valid.
     * @throws IOException if an error occurs.
     * @deprecated
     */
    public static void writeDOM(Document document, String sourceUri, ServiceManager manager)
            throws TransformerConfigurationException, TransformerException, ServiceException,
            MalformedURLException, IOException {
        SourceResolver resolver = null;
        ModifiableSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (ModifiableSource) resolver.resolveURI(sourceUri);

            OutputStream oStream = source.getOutputStream();
            writeDOM(document, oStream);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Writes a DOM to a source.
     * @param document The document.
     * @param sourceUri The source URI.
     * @throws TransformerConfigurationException if an error occurs.
     * @throws TransformerException if an error occurs.
     * @throws ServiceException if the source resolver could not be obtained.
     * @throws MalformedURLException if the source URI is not valid.
     * @throws IOException if an error occurs.
     */
    public static void writeDOM(Document document, String sourceUri, SourceResolver resolver)
            throws TransformerConfigurationException, TransformerException, ServiceException,
            MalformedURLException, IOException {
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            if (source instanceof ModifiableSource) {
                ModifiableSource modifiableSource = (ModifiableSource) source;
                OutputStream oStream = modifiableSource.getOutputStream();
                writeDOM(document, oStream);
            } else {
                throw new IOException("The source " + sourceUri + " is not modifiable.");
            }
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * @param document The XML document.
     * @param oStream The output stream.
     * @throws TransformerConfigurationException if an error occurs.
     * @throws TransformerException if an error occurs.
     * @throws IOException if an error occurs.
     */
    public static void writeDOM(Document document, OutputStream oStream)
            throws TransformerConfigurationException, TransformerException, IOException {
        DocumentHelper.writeDocument(document, oStream);
        if (oStream != null) {
            oStream.flush();
            try {
                oStream.close();
            } catch (Throwable t) {
                throw new RuntimeException("Could not write document: ", t);
            }
        }
    }

    /**
     * Deletes a source if it exists.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     * @deprecated
     */
    public static void delete(String sourceUri, ServiceManager manager) throws ServiceException,
            MalformedURLException, IOException {
        SourceResolver resolver = null;
        ModifiableTraversableSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (ModifiableTraversableSource) resolver.resolveURI(sourceUri);
            if (source.exists()) {
                source.delete();
            }

        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Deletes a source if it exists.
     * @param sourceUri The source URI.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     */
    public static void delete(String sourceUri, SourceResolver resolver) throws ServiceException,
            MalformedURLException, IOException {
        ModifiableTraversableSource source = null;
        try {
            source = (ModifiableTraversableSource) resolver.resolveURI(sourceUri);
            if (source.exists()) {
                source.delete();
            }

        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
            }
        }
    }

    /**
     * Deletes all empty collections in a subtree.
     * @param sourceUri The root source URI.
     * @param manager The service manager.
     * @throws ServiceException
     * @throws MalformedURLException
     * @throws IOException
     */
    public static void deleteEmptyCollections(String sourceUri, ServiceManager manager)
            throws ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        try {
            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            deleteEmptyCollections(sourceUri, resolver);
        } finally {
            if (resolver != null) {
                manager.release(resolver);
            }
        }
    }

    /**
     * Deletes all empty collections in a subtree.
     * @param sourceUri The root source URI.
     * @throws ServiceException
     * @throws MalformedURLException
     * @throws IOException
     */
    public static void deleteEmptyCollections(String sourceUri, SourceResolver resolver)
            throws ServiceException, MalformedURLException, IOException {
        ModifiableTraversableSource source = null;
        try {
            source = (ModifiableTraversableSource) resolver.resolveURI(sourceUri);
            if (source.isCollection()) {
                for (Iterator i = source.getChildren().iterator(); i.hasNext();) {
                    ModifiableTraversableSource child = (ModifiableTraversableSource) i.next();
                    deleteEmptyCollections(child.getURI(), resolver);
                }
                if (source.getChildren().size() == 0) {
                    source.delete();
                }
            }
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * Checks if a source exists.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A boolean value.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     * @deprecated
     */
    public static boolean exists(String sourceUri, ServiceManager manager) throws ServiceException,
            MalformedURLException, IOException {
        SourceResolver resolver = null;
        Source source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = resolver.resolveURI(sourceUri);

            return source.exists();
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Checks if a source exists.
     * @param sourceUri The source URI.
     * @return A boolean value.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     */
    public static boolean exists(String sourceUri, SourceResolver resolver)
            throws ServiceException, MalformedURLException, IOException {
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            return source.exists();
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * Returns the last modification date of a source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A long value.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     * @deprecated
     */
    public static long getLastModified(String sourceUri, ServiceManager manager)
            throws ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        Source source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = resolver.resolveURI(sourceUri);

            return source.getLastModified();
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Returns the last modification date of a source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A long value.
     * @throws ServiceException if an error occurs.
     * @throws MalformedURLException if an error occurs.
     * @throws IOException if an error occurs.
     */
    public static long getLastModified(String sourceUri, SourceResolver resolver)
            throws ServiceException, MalformedURLException, IOException {
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            return source.getLastModified();
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * Checks out a repository source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws RepositoryException If an error occurs.
     * @throws ServiceException If an error occurs.
     * @throws MalformedURLException If an error occurs.
     * @throws IOException If an error occurs.
     */
    public static void checkout(String sourceUri, ServiceManager manager)
            throws RepositoryException, ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        DocumentSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (DocumentSource) resolver.resolveURI(sourceUri);

            source.getDocument().checkout();

        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Checks in a transactionable source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws RepositoryException If an error occurs.
     * @throws ServiceException If an error occurs.
     * @throws MalformedURLException If an error occurs.
     * @throws IOException If an error occurs.
     */
    public static void checkin(String sourceUri, ServiceManager manager)
            throws RepositoryException, ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        DocumentSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (DocumentSource) resolver.resolveURI(sourceUri);

            source.getDocument().checkin();

        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Locks a transactionable source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws RepositoryException If an error occurs.
     */
    public static void lock(String sourceUri, ServiceManager manager) throws RepositoryException {
        SourceResolver resolver = null;
        DocumentSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (DocumentSource) resolver.resolveURI(sourceUri);

            source.getDocument().lock();

        } catch (Exception e) {
            throw new RepositoryException(e);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Unlocks a transactionable source.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @throws RepositoryException If an error occurs.
     */
    public static void unlock(String sourceUri, ServiceManager manager) throws RepositoryException {
        SourceResolver resolver = null;
        DocumentSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (DocumentSource) resolver.resolveURI(sourceUri);

            source.getDocument().unlock();

        } catch (Exception e) {
            throw new RepositoryException(e);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * Registers a source as dirty.
     * @param sourceUri The source URI.
     * @param manager The service manager.
     */
    public static void registerDirty(String sourceUri, ServiceManager manager) {
        SourceResolver resolver = null;
        DocumentSource source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = (DocumentSource) resolver.resolveURI(sourceUri);
            source.getDocument().registerDirty();

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A content length.
     * @throws ServiceException
     * @throws MalformedURLException
     * @throws IOException
     * @deprecated
     */
    public static long getContentLength(String sourceUri, ServiceManager manager)
            throws ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        Source source = null;
        try {
            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = resolver.resolveURI(sourceUri);
            return source.getContentLength();
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * @param sourceUri The source URI.
     * @return A content length.
     * @throws ServiceException
     * @throws MalformedURLException
     * @throws IOException
     */
    public static long getContentLength(String sourceUri, SourceResolver resolver)
            throws ServiceException, MalformedURLException, IOException {
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            return source.getContentLength();
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * @param sourceUri The source URI.
     * @return A mime type.
     * @throws ServiceException
     * @throws IOException
     * @throws MalformedURLException
     */
    public static String getMimeType(String sourceUri, SourceResolver resolver)
            throws ServiceException, MalformedURLException, IOException {
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            return source.getMimeType();
        } finally {
            if (source != null) {
                resolver.release(source);
            }
        }
    }

    /**
     * @param sourceUri The source URI.
     * @param manager The service manager.
     * @return A mime type.
     * @throws ServiceException
     * @throws IOException
     * @throws MalformedURLException
     * @deprecated
     */
    public static String getMimeType(String sourceUri, ServiceManager manager)
            throws ServiceException, MalformedURLException, IOException {
        SourceResolver resolver = null;
        Source source = null;
        try {

            resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
            source = resolver.resolveURI(sourceUri);

            return source.getMimeType();
        } finally {
            if (resolver != null) {
                if (source != null) {
                    resolver.release(source);
                }
                manager.release(resolver);
            }
        }
    }

    /**
     * @param resolver
     * @param sourceUri
     * @param destOutputStream
     * @throws MalformedURLException
     * @throws IOException
     */
    public static void copy(SourceResolver resolver, String sourceUri, OutputStream destOutputStream)
            throws MalformedURLException, IOException {
        boolean useBuffer = true;
        InputStream sourceInputStream = null;
        Source source = null;
        try {
            source = resolver.resolveURI(sourceUri);
            sourceInputStream = source.getInputStream();

            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();
            }
            if (source != null) {
                resolver.release(source);
            }
        }
    }
}