/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.repository;

//import fr.gouv.culture.sdx.db.AttachedDocument;

import fr.gouv.culture.sdx.document.Document;
import fr.gouv.culture.sdx.document.ParsableDocument;
import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.utils.SdxObject;
import fr.gouv.culture.sdx.utils.save.Saveable;

import org.apache.cocoon.xml.XMLConsumer;
import org.xml.sax.ContentHandler;

import java.io.InputStream;
import java.io.OutputStream;

/**
 *	A generic storage location for SDX documents.
 *
 * <p>
 * When SDX indexes a document, it must make it available, for example send it as
 * a stream or as SAX events. A repository is responsible for sending the document's
 * contents and, possibly, to store it.
 * <p>
 * A repository can be read-only or not. TODO?: i think we have removed this option?-rbp
 * If it is, documents can't be stored, they can only be retrieved. There are two main
 * interests for read-only repositories : (1) to implement an SDX application on a
 * read-only media such as a CD-ROM, the indexing may have been done before ;
 * (2) for URL repositories, where the document can be distant and not writable.
 * <p>
 * A repository must be able to find a document only with the document's id. The manner in which
 * it keeps track of these ids is implementation specific.
 * <p>
 * A repository must also manage a connection, even if it doesn't use it. A connection
 * may be used to speed up batch operations.
 * <p>
 * To be usable, a repository object must created, a super.getLog() set, then configured and initialized.
 */
public interface Repository extends SdxObject, Saveable {

    interface ConfigurationNode {

        /**String representation of the element name "repositories". */
        String REPOSITORIES = "repositories";
        /**String representation of the "repository" attribute name "default". */
        String DEFAULT = "default";
        /**String representation of the 'repository' attribute named 'ref'. */
        String REF = "ref";//TODO: move to a Referencable inteface-rbp
    }

    /**String representation of the repository package name (including trailing separator "."). */
    public static final String PACKAGE_QUALNAME = "fr.gouv.culture.sdx.repository.";

    /**String representation of the repository class name suffix. */
    public static final String CLASS_NAME_SUFFIX = "Repository";

    /** Initializes the repository. */
    public void init() throws SDXException;

    /** Returns a connection to the repository. */
    public RepositoryConnection getConnection() throws SDXException;

    /** Releases a previously opened connection
     *
     *	@param	c	The connection to release.
     */
    public void releaseConnection(RepositoryConnection c) throws SDXException;

    /** Returns the number of documents within the repository. */
    public long size() throws SDXException;

    /**
     * Lists the repository content as SAX events.
     *
     * <p>
     * The exact structure is still to be defined, but it shoud be very
     * simple, with only one element per document and a few properties
     * as attributes.
     *
     *	@param	hdl		The SAX content handler to feed with events.
     */
    public void lists(ContentHandler hdl) throws SDXException;

    /**
     * Adds a document to the repository.
     *
     *	@param	doc		The document to add.
     *	@param	c		A connection to the repository.
     */
    public void add(Document doc, RepositoryConnection c) throws SDXException;

    /**
     * Deletes all documents from the repository.
     */
    public void empty() throws SDXException;

    /**
     * Deletes a document.
     *
     *	@param	doc		The document to delete.
     */
    public void delete(Document doc, RepositoryConnection c) throws SDXException;

    /**
     * Retrieves a SDX document as SAX events.
     *
     *	@param	doc		    The document.
     * @param	consumer	A SAX content handler to feed with events.
     * <p>The wrapped contentHandler for including events within an XSP page contentHandler should be created using
     IncludeXMLConsumer stripper = new IncludeXMLConsumer(xspContentHandler);</p>
     *	@param	c		    A connection to the repository.
     */
    public void toSAX(ParsableDocument doc, XMLConsumer consumer, RepositoryConnection c) throws SDXException;

    /**
     * Opens a stream to read a document.
     *
     *	@param	doc		    The document to read.
     *	@param	encoding    The encoding to use for serialization of XML content (may be null).
     *	@param	c		    A connection to the repository.
     *
     *	@return		An input stream from which the serialized content of the document can be read.
     */
    public InputStream openStream(Document doc, String encoding, RepositoryConnection c) throws SDXException;

    /**
     * Feeds a stream with a document.
     *
     *	@param	doc		The document to read.
     *	@param	os		The output stream where to write.
     *	@param	c		A connection to the repository.
     */
    public void get(Document doc, OutputStream os, RepositoryConnection c) throws SDXException;

    /** Returns whether it is a default repository for an application. */
    public boolean isDefault();

    /**Sets the default flag for the repository*/
    public void setIsDefault(boolean b);

    /**Utility method for repository maintenance,
     * normally used to optimize indices of Lucene based repositories
     *
     * It is the responsibility of the Repository to ensure that
     * unnecessary optimizations are not performed when this method
     * is called.
     */
    public void optimize() throws SDXException;

    public boolean exists(String id, RepositoryConnection conn);
}
