package de.uka.ipd.consensus.foundation.query;

import java.util.Collection;

import de.uka.ipd.consensus.foundation.rights.DynamicRightsManagerException;
import de.uka.ipd.consensus.foundation.schema.Association;
import de.uka.ipd.consensus.foundation.schema.Concept;
import de.uka.ipd.consensus.foundation.schema.Topic;
import de.uka.ipd.consensus.foundation.schema.User;


/**
 * The QueryEngine is part of the OntologyManager. It is used to retrieve the elements of the ontology by id, by type or as various collections.
 * @author Thomas Much
 * @version 2006-06-14
 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager
 */
public interface QueryEngine {

	/**
	 * Executes a query string and returns the result as a QueryEngineResultSet.
	 * @param user the user who wants to do the query
	 * @param query the query string
	 * @return a possibly empty result set, never <code>null</code>
	 * @throws QueryEngineSyntaxException if the query string is syntactically incorrect
	 * @throws QueryEngineProcessingException the the query could not be processed (for example, due to logical errors in the query string)
	 * @throws QueryEngineException if any other error occurs
	 * @throws DynamicRightsManagerException if the user is not allowed to execute free queries in the query language
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayQuery(User, String)
	 * @see #getQuerySyntaxName()
	 * @see #getQuerySyntaxURL()
	 * @see #getQuerySyntaxVersion()
	 */
	public QueryEngineResultSet executeQuery(User user, String query) throws QueryEngineException,DynamicRightsManagerException;

	
	/**
	 * Returns a topic for a given id.
	 * @param user the user who wants to get the topic
	 * @param id the topic's id
	 * @return the topic with the given id or <code>null</code> if the id does not exist
	 * @throws QueryEngineException if the topic could not be read
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Topic getTopicById(User user, String id) throws QueryEngineException;

	
	/**
	 * Returns a collection of all Topic objects.
	 * @param user the user who wants to get the topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getTopics(User user) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of Topic objects whose names match the given beginning (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param beginning the required beginning of a topic name; <code>null</code> or the empty string match all topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getTopicsByBeginning(User user, String beginning) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of Topic objects whose name (and optionally comment) contain the given substring (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param substring the required substring of a topic name or comment; <code>null</code> or the empty string match all topics
	 * @param searchComment if <code>true</code>, the comments are searched for the substring, too, otherwise only the topic name is searched
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getTopicsBySubstring(User user, String substring, boolean searchComment) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of all class Topic objects.
	 * @param user the user who wants to get the topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getClassTopics(User user) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of class Topic objects whose names match the given beginning (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param beginning the required beginning of a topic name; <code>null</code> or the empty string match all class topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getClassTopicsByBeginning(User user, String beginning) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of class Topic objects whose name (and optionally comment) contain the given substring (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param substring the required substring of a topic name or comment; <code>null</code> or the empty string match all class topics
	 * @param searchComment if <code>true</code>, the comments are searched for the substring, too, otherwise only the topic name is searched
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getClassTopicsBySubstring(User user, String substring, boolean searchComment) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of all non-class Topic objects.
	 * @param user the user who wants to get the topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getInstanceTopics(User user) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of non-class Topic objects whose names match the given beginning (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param beginning the required beginning of a topic name; <code>null</code> or the empty string match all non-class topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getInstanceTopicsByBeginning(User user, String beginning) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of non-class Topic objects whose name (and optionally comment) contain the given substring (case-insensitive).
	 * @param user the user who wants to get the topics
	 * @param substring the required substring of a topic name or comment; <code>null</code> or the empty string match all non-class topics
	 * @param searchComment if <code>true</code>, the comments are searched for the substring, too, otherwise only the topic name is searched
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getInstanceTopicsBySubstring(User user, String substring, boolean searchComment) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of TypeInstance objects that represent the types of a given instance topic.
	 * @param user the user who wants to get the types
	 * @param topic the instance topic for which the types are returned
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the types could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.TypeInstance
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getTypes(User user, Topic topic) throws QueryEngineException;

	
	/**
	 * Returns a collection of TypeInstance objects that represent the instances of a given type topic.
	 * @param user the user who wants to get the instances
	 * @param topic the type topic for which the instances are returned
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the instances could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.TypeInstance
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getInstances(User user, Topic topic) throws QueryEngineException;

	
	/**
	 * Returns a collection of instance Topic objects that have no types.
	 * @param user the user who wants to get the root instance topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the root instance topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getInstanceRoots(User user) throws QueryEngineException;

	
	/**
	 * Returns a collection of SuperSubclass objects that represent the superclasses of a given class topic.
	 * <p>If the implementation does not support classes, an empty collection is returned.</p>
	 * @param user the user who wants to get the superclasses
	 * @param topic the class topic for which the superclasses are returned
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the superclasses could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.SuperSubclass
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getSuperclasses(User user, Topic topic) throws QueryEngineException;

	
	/**
	 * Returns a collection of SuperSubclass objects that represent the subclasses of a given class topic.
	 * <p>If the implementation does not support classes, an empty collection is returned.</p>
	 * @param user the user who wants to get the subclasses
	 * @param topic the class topic for which the subclasses are returned
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the subclasses could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.SuperSubclass
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getSubclasses(User user, Topic topic) throws QueryEngineException;

	
	/**
	 * Returns a collection of class Topic objects that have no superclasses.
	 * <p>If the implementation does not support classes, an empty collection is returned.</p>
	 * @param user the user who wants to get the root class topics
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the root class topics could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Topic
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getClassRoots(User user) throws QueryEngineException;

	
	/**
	 * Returns an association for a given id.
	 * @param user the user who wants to get the association
	 * @param id the association's id
	 * @return the association with the given id or <code>null</code> if the id does not exist
	 * @throws QueryEngineException if the association could not be read
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 */
	public Association getAssociationById(User user, String id) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of all Association objects in which the given topic plays a role.
	 * @param user the user who wants to get the associations
	 * @param topic the topic that is player in all returned associations
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the associations could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Association
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 */
	public Collection getAssociations(User user, Topic topic) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of all Association objects with the given type.
	 * @param user the user who wants to get the associations
	 * @param type the type of all returned associations, including <code>null</code> for typeless associations
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the associations could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.Association
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 */
	public Collection getAssociationsOfType(User user, Topic type) throws QueryEngineException;
	
	
	/**
	 * Returns a collection of all AssociationRole objects that are part of the given association.
	 * This includes the typeless role if it is part of the association.
	 * @param user the user who wants to get the association roles
	 * @param assoc the association for which the roles are returned
	 * @return a possibly empty collection, never <code>null</code>
	 * @throws QueryEngineException if the association roles could not be read
	 * @see de.uka.ipd.consensus.foundation.schema.AssociationRole
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getAssociationRoles(User user, Association assoc) throws QueryEngineException;

	
	/**
	 * Returns a concept for a given id.
	 * @param user the user who wants to get the concept
	 * @param id the concept's id
	 * @return the concept with the given id or <code>null</code> if the id does not exist
	 * @throws QueryEngineException if the concept could not be read
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAttribute(User, Attribute)
	 */
	public Concept getConceptById(User user, String id) throws QueryEngineException;

	
	/**
	 * Returns the total number of topics in the ontology that the user may see.
	 * @param user the user who wants to read the number of topics
	 * @return the number of topics the user is allowed to see
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public int getTopicCount(User user);
	
	
	/**
	 * Returns the number of class topics in the ontology that the user may see.
	 * @param user the user who wants to read the number of class topics
	 * @return the number of class topics the user is allowed to see
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public int getClassTopicCount(User user);
	
	
	/**
	 * Returns the number of non-class topics in the ontology that the user may see.
	 * @param user the user who wants to read the number of non-class topics
	 * @return the number of non-class topics the user is allowed to see
	 * @see de.uka.ipd.consensus.foundation.schema.Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public int getInstanceTopicCount(User user);
	
	
	/**
	 * Returns the number of associations in the ontology that the user may see.
	 * @param user the user who wants to read the number of associations
	 * @return the number of associations the user is allowed to see
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 */
	public int getAssociationCount(User user);

	
	/**
	 * Returns an implementation specific version of the QueryEngine.
	 * @return the version of the QueryEngine
	 */
	public String getVersion();

	
	/**
	 * Returns the name of the query language that is provided by the implementation of the QueryEngine.
	 * @return the name of the query language (e.g. "Tolog")
	 * @see #getQuerySyntaxVersion()
	 * @see #executeQuery(User, String)
	 */
	public String getQuerySyntaxName();
	
	
	/**
	 * Returns the version of the query language that is provided by the implementation of the QueryEngine.
	 * @return the version of the query language (e.g. "1.0")
	 * @see #getQuerySyntaxName()
	 * @see #executeQuery(User, String)
	 */
	public String getQuerySyntaxVersion();
	
	
	/**
	 * Returns a URL with human-readable information about the syntax of the query language that is provided by the implementation of the QueryEngine.
	 * @return a URL that points to a query language documentation
	 * @see #executeQuery(User, String)
	 */
	public String getQuerySyntaxURL();

}
