// Central.java
//    An interface to the Moby Central service.
//
//    senger@ebi.ac.uk
//    February 2003
//

package org.biomoby.shared;

import java.util.Map;
import java.io.InputStream;

/**
 * An interface to the Moby Registry. <p>
 *
 * The Moby Registry (or Moby Central) is used to do various
 * transactions, including registering new Data and Service types,
 * querying for these types, registering new Services, or querying for
 * available services given certain input/output or service type
 * constraints. <P>
 *
 * The main purpose of this interface is to express the Moby Registry
 * functionality in Java language, and to hide complexity of the
 * parameters required by the Moby Registry. The Moby Registry gets
 * most parameters as small XML documents while this interface defines
 * the same parameters as various Java method signatures. <p>
 *
 * For details describing and explaining the methods see the original documentation at
 * <a href="http://biomoby.org/" target="_top">
 * http://biomoby.org</a>.
 *<p>
 * @author <A HREF="mailto:senger@ebi.ac.uk">Martin Senger</A>
 * @version $Id: Central.java,v 1.17 2008/10/30 02:33:25 gordonp Exp $
 */

public interface Central {

    /** A relationship type expressing a straight inheritance (as
     * string). If Object_A ISA Object_B then all attributes of
     * Object_B are guaranteed to be present in Object_A.
     */
    static final String ISA = "ISA";

    /** A relationship type expressing a contaiment (as string). If
     * Object_A HASA Object_B then Object_B is an object inside of
     * Object_A in one copy only. */
    static final String HASA = "HASA";

    /** A relationship type expressing a contaiment (as string). If
     * Object_A HAS Object_B then Object_B is an object inside of
     * Object_A in one or more copies. */
    static final String HAS = "HAS";

    /** A relationship type expressing a straight inheritance (as
     * integer). If Object_A ISA Object_B then all attributes of
     * Object_B are guaranteed to be present in Object_A.
     */
    static final int iISA = 1;

    /** A relationship type expressing a contaiment (as integer). If
     * Object_A HASA Object_B then Object_B is an object inside of
     * Object_A in one copy only. */
    static final int iHASA = 2;

    /** A relationship type expressing a contaiment (as integer). If
     * Object_A HAS Object_B then Object_B is an object inside of
     * Object_A in one or more copies. */
    static final int iHAS = 3;

    /** A name of an ontology describing registered service types.
	The name is used in a hash table returned by the {@link
	#getResourceRefs}.
     */
    static final String SERVICE_TYPES_RESOURCE_NAME = "Service";

    /** A name of an ontology describing registered service types.
	The name is used in a hash table returned by the {@link
	#getResourceRefs}.
     */
    static final String SERVICE_INSTANCES_RESOURCE_NAME = "ServiceInstance";

    /** A name of an ontology describing registered data types. The
	name is used in a hash table returned by the {@link
	#getResourceRefs}.
     */
    static final String DATA_TYPES_RESOURCE_NAME = "Object";

    /** A name of an ontology describing registered service types.
	The name is used in a hash table returned by the {@link
	#getResourceRefs}.
     */
    static final String NAMESPACES_RESOURCE_NAME = "Namespace";

    /** A name of an ontology describing all registered entities.  The
	name is used in a hash table returned by the {@link
	#getResourceRefs}. The contents returned by this method for
	this ontology name is a concatenation of all other ontologies.
     */
    static final String FULL_RESOURCE_NAME = "Full";

    /**************************************************************************
     * Get a (redundant) list of all registered service names. <p>
     *
     * @deprecated Replaced by {@link
     * #getServiceNamesByAuthority}. The reason is that this method
     * returns a random result if there are more services with the
     * same name but belonging to different authorities. <p>
     *
     * @return a hash table where keys are names of services while
     *         values are their authorities
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String> getServiceNames()
	throws MobyException;

    /**************************************************************************
     * Get a list of all authorities - and for each of them a list of
     * their registered service names. <p>
     *
     * This method is a better replacement for the deprecated method
     * {@link #getServiceNames}. <p>
     *
     * @return a hash table where keys are authority names and values
     * are arrays of service names provided by each authority
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String[]> getServiceNamesByAuthority()
	throws MobyException;

    /**************************************************************************
     * Get the list of all providers (each provider is represented by an
     * authority's URI.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    String[] getProviders()
	throws MobyException;

    /**************************************************************************
     * Get the list of all registered service types.
     *<p>
     * @return a hash table where keys are names of service types while
     *         values are their descriptions
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String> getServiceTypes()
	throws MobyException;

    /**************************************************************************
     * Get all ISA relationships of the given 'serviceTypeName'.
     *<p>
     * @param serviceTypeName is a service type name whose
     * relationships should be looked at
     * @param expand 'true' causes that all related type names are
     * returned, 'false' means that only first-level neighbour is returned
     * @return an array of service type names representing all parents
     * (direct or indirect) of the given 'serviceTypeName'
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    String[] getServiceTypeRelationships (String serviceTypeName,
					  boolean expand)
	throws MobyException;

    /**************************************************************************
     * Get the list of all registered namespaces. <p>
     *
     * @deprecated Replaced by {@link #getFullNamespaces} that gives
     * more information for the same price. <p>
     *
     * @return a hash table where keys are names of namespaces while
     *         values are their descriptions
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String> getNamespaces()
	throws MobyException;

    /**************************************************************************
     * Get the list of all registered namespaces, with all their
     * attributes. <p>
     *
     * @return array of namespaces
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    MobyNamespace[]  getFullNamespaces()
	throws MobyException;

    /**************************************************************************
     * Get the list of all registered data types.
     *<p>
     * @return a hash table where keys are names of data types while
     *         values are their descriptions
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String> getDataTypeNames()
	throws MobyException;

    /*************************************************************************
     * Get definition of the given data type.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if 'dataTypeName' was not found
     *************************************************************************/
    MobyDataType getDataType (String dataTypeName)
 	throws MobyException, NoSuccessException;

    MobyDataType[] getDataTypes ()
 	throws MobyException, NoSuccessException;

    /**************************************************************************
     * Get all relationships of the given 'dataTypeName'.
     *<p>
     * @param dataTypeName is an ontology term specifying whose
     * relationships should be looked at
     * @return a Map of ontology terms defining all relationships of
     * the given 'dataTypeName'. The keys (of type String) are from
     * the set {@link #ISA}, {@link #HASA}, and {@link #HAS}. The
     * values (of type String) are data type names.
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    Map<String,String> getDataTypeRelationships (String dataTypeName)
	throws MobyException;

    /**************************************************************************
     * Get all relationships of type 'relationshipType' for the given
     *'dataTypeName'.  <p>
     * @param dataTypeName is an ontology term specifying whose
     * relationships should be looked at
     * @param relationshipType is one from the set {@link #ISA},
     * {@link #HASA}, and {@link #HAS}.
     * @return an array of names specifying all related types (of the
     * given type and for the given data type)
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    String[] getDataTypeRelationships (String dataTypeName, String relationshipType)
	throws MobyException;

    /*************************************************************************
     * Get XML Schema definition of the given data type.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if 'dataTypeName' was not found
     *************************************************************************/
//     String getDataTypeSchema (String dataTypeName)
// 	throws MobyException, NoSuccessException;

    /*************************************************************************
     * Get WSDL defining a service given by its name and its authority.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if such service was not found
     *************************************************************************/
    String getServiceWSDL (String serviceName, String authority)
	throws MobyException, NoSuccessException;

    /*************************************************************************
     * Get WSDL defining a service given by its name.
     * The method asks for all services first and then uses the first one
     * matches the given name.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if such service was not found
     * @see #getServiceWSDL(String,String)
     *************************************************************************/
    String getServiceWSDL (String serviceName)
	throws MobyException, NoSuccessException;

    /*************************************************************************
     * Register new data type.
     *<p>
     * If the same data type is already registered, it is overwritten.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if registration failed
     *************************************************************************/
    void registerDataType (MobyDataType dataType)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Unregister given Moby data type.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if unregistration failed
     *************************************************************************/
    void unregisterDataType (MobyDataType dataType)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Register new service type.
     *<p>
     * If the same service type is already registered, it is <b>not</b>
     * overwritten but an exception is raised.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if registration failed
     *************************************************************************/
    void registerServiceType (MobyServiceType serviceType)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Unregister given Moby service type.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if unregistration failed
     *************************************************************************/
    void unregisterServiceType (MobyServiceType serviceType)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Register new namespace.
     *<p>
     * If the same namespace is already registered, it is overwritten.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if registration failed
     *************************************************************************/
    void registerNamespace (MobyNamespace namespace)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Unregister given Moby namespace.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if unregistration failed
     *************************************************************************/
    void unregisterNamespace (MobyNamespace namespace)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Register a new service.
     *<p>
     * If the same service type is already registered, it is <b>not</b>
     * overwritten but an exception is raised.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if registration failed
     *************************************************************************/
    void registerService (MobyService service)
	throws MobyException, NoSuccessException, PendingCurationException;

    /*************************************************************************
     * Unregister given Moby service.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
     * @throws NoSuccessException if unregistration failed
     *************************************************************************/
    void unregisterService (MobyService service)
	throws MobyException, NoSuccessException, PendingCurationException;

    /**************************************************************************
     * Find services of the given type and its sub-types.
     *<p>
     * @return services of the given type and all sub-typesd,
     *         or an empty array if none was found
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    MobyService[] findService (String serviceType)
	throws MobyException;

    /**************************************************************************
     * Find services by given keywords. More keywords are treated as
     * logical OR.
     *<p>
     * @return services containing given keywords,
     *         or an empty array if none was found
     * @throws MobyException if communication with the Moby Registry fails
     *************************************************************************/
    MobyService[] findService (String[] keywords)
	throws MobyException;

    /**************************************************************************
     * Find services matching whatever is non-empty in the given 'pattern'.
     * If more fields are given the logical AND is applied on them.
     *<p>
     * @throws MobyException if communication with the Moby Registry fails
    *************************************************************************/
    MobyService[] findService (MobyService pattern)
	throws MobyException;

    /**************************************************************************
     * Find service matching both all non-empty fields in the 'pattern' and
     * the 'keywords'.
     *************************************************************************/
    MobyService[] findService (MobyService pattern, String[] keywords)
	throws MobyException;

    /**************************************************************************
     * Find service matching both all non-empty fields in the 'pattern' and
     * the 'keywords', and take into account also the whole ontology tree.
     * <p>
     * @param includeChildrenServiceTypes - if true (which is default)
     * then it discovers also services that are child types (more
     * specific) than the service type in 'pattern'
     * @param includeParentDataTypes - if true (which is default) then
     * it finds services that operate not only on the input/output
     * data types defined in 'pattern', but also any ontolological
     * parent types of that data types
     *************************************************************************/
    MobyService[] findService (MobyService pattern, String[] keywords,
			       boolean includeChildrenServiceTypes,
			       boolean includeParentDataTypes)
	throws MobyException;

    /**************************************************************************
     * Call Moby registry's method with given XML as input and return whatever
     * you get back. If 'inputXML' is null or empty, the method is called
     * without any parameters.
     *<p>
     * Meant for debugging and may be deprecated anytime...
     *************************************************************************/
    String call (String methodName, String inputXML)
	throws MobyException;

    /**************************************************************************
     * Ask the implementation to create more verbose logs or messages
     * about what is going on. The behaviour is completely
     * implementation dependent. <p>
     *
     * @param enabled true if debug mode should be enabled, false otherwise
     * @return the previous value of the debug mode
     *************************************************************************/
    boolean setDebug (boolean enabled);

    /**************************************************************************
     * Set whether the server responses should cached or not to speedup 
     * multiple calls for the same data.   
     * @param shouldCache if set to false, any previously cached documents should be deleted
     *************************************************************************/
    void setCacheMode(boolean shouldCache); 

    /**************************************************************************
     * Reports whether server responses are being cached or not.
     *************************************************************************/
    boolean getCacheMode();

    /**************************************************************************
     * Return an endpoint (a stringified URL) representing a Moby
     * registry that an instance of this implementation is connected
     * to.
     *************************************************************************/
    String getRegistryEndpoint();

    /**************************************************************************
     * Return a namespace (a URI) used by a Moby registry that an
     * instance of this implementation is connected to.
     *************************************************************************/
    String getRegistryNamespace();

    /**************************************************************************
     * Get URLs (and content types) of RDF documents describing
     * various BioMoby ontologies. These RDF documents are yet another
     * form how to get information about registered entities in the
     * BioMoby registry. <p>
     * 
     * There are five possible ontology names:
     * {@link #SERVICE_TYPES_RESOURCE_NAME},
     * {@link #DATA_TYPES_RESOURCE_NAME},
     * {@link #NAMESPACES_RESOURCE_NAME},
     * {@link #SERVICE_INSTANCES_RESOURCE_NAME},
     * {@link #FULL_RESOURCE_NAME}. <p>
     *
     * @return an array of references to RDF documents; some elements
     * of this array may refer to the same resources but
     * stored/available in a different content type (this mostly means
     * that some of them may be compressed to get them faster)
     *
     * @throws MobyException if communication with the Moby Registry fails
      *************************************************************************/
    MobyResourceRef[] getResourceRefs()
	throws MobyException;

    /**************************************************************************
     * First get (from a BioMoby registry) a URL for the given
     * 'resourceName' and then retrieve a document from this URL. If
     * the resource is available in a compressed format, return it
     * uncompressed. <p>
     *
     * The document is in RDF and represents some (or all) entities
     * registered in the BioMoby registry. <p>
     *
     * @param resourceName is an ontology name (must be one of these:
     * {@link #SERVICE_TYPES_RESOURCE_NAME}, {@link
     * #DATA_TYPES_RESOURCE_NAME}, {@link #NAMESPACES_RESOURCE_NAME},
     * {@link #SERVICE_INSTANCES_RESOURCE_NAME}, {@link
     * #FULL_RESOURCE_NAME})
     *
     * @return an input stream that contains an RDF document
     * @throws MobyException if communication with the Moby Registry
     * fails, or if communication with the resource URL fails
     *************************************************************************/
    InputStream getResource (String resourceName)
	throws MobyException;


}
