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

import java.io.Serializable;
import java.util.Collection;

import de.uka.ipd.consensus.foundation.ontology.OntologyManagerException;
import de.uka.ipd.consensus.foundation.rights.DynamicRightsManagerException;

/**
 * This interface repesents a topic, the main element of the ontology.
 * @author Thomas Much
 * @version 2006-06-14
 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager#createTopic(User, String, String, Topic)
 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager#createClassTopic(User, String, String, Topic)
 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager#createInternalTopic(User, String, String, Topic)
 */
public interface Topic extends Concept,Attributeable,Serializable,Comparable {

	/**
	 * Returns a collection of Association objects in which this topic plays a role.
	 * @param user the user who wants to see the associations
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Association
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewAssociation(User, Association)
	 * @see de.uka.ipd.consensus.foundation.query.QueryEngine#getAssociations(User, Topic)
	 */
	public Collection getAssociations(User user);
	
	
	/**
	 * Queries a type with the given id of this instance topic.
	 * @param user the user who wants to see the type
	 * @param id the queried id
	 * @return a TypeInstance object containing the type or <code>null</code> if there's no type with the given id
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see #getSuperclass(User, String)
	 */
	public TypeInstance getType(User user, String id);
	
	
	/**
	 * Returns a collection of TypeInstance objects containing the types of this instance topic.
	 * @param user the user who wants to see the types
	 * @return a possibly empty collection, never <code>null</code>
	 * @see TypeInstance
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see de.uka.ipd.consensus.foundation.query.QueryEngine#getTypes(User, Topic)
	 * @see #getSuperclasses(User)
	 */
	public Collection getTypes(User user);
	
	
	/**
	 * Returns a collection of TypeInstance objects containing the instances of this type (class) topic.
	 * @param user the user who wants to see the instances
	 * @return a possibly empty collection, never <code>null</code>
	 * @see TypeInstance
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see de.uka.ipd.consensus.foundation.query.QueryEngine#getInstances(User, Topic)
	 * @see #isClassTopic()
	 * @see #getSubclasses(User)
	 */
	public Collection getInstances(User user);

	
	/**
	 * Adds a type to this topic. If the implementation supports classes, the type must be a class topic.
	 * @param adder the user who wants to add the type
	 * @param type the type topic to be added (must not be <code>null</code>)
	 * @return a TypeInstance object containing the type topic
	 * @throws OntologyManagerException if the type could not be added
	 * @throws DynamicRightsManagerException if the user is not allowed to add a type
	 * @see Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayAddType(User, Topic)
	 * @see #addSuperclass(User, Topic)
	 */
	public TypeInstance addType(User adder, Topic type) throws OntologyManagerException,DynamicRightsManagerException;
	
	
	/**
	 * Removes a type from this topic. If the given type is no type of this topic, this call has no effect.
	 * @param remover the user who wants to remove the type
	 * @param type the type to be removed
	 * @throws OntologyManagerException if the type could not be removed
	 * @throws DynamicRightsManagerException if the user is not allowed to remove the type
	 * @see TypeInstance
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayRemoveType(User, TypeInstance)
	 * @see #removeSuperclass(User, Topic)
	 */
	public void removeType(User remover, Topic type) throws OntologyManagerException,DynamicRightsManagerException;


	/**
	 * Creates an occurrence for this topic with the given type and value (data).
	 * If the implementation supports classes, the type must be a class topic.
	 * @param adder the user who wants to create the occurrence
	 * @param data the value of the occurrence (<code>null</code> is treated as the empty string)
	 * @param type the type of the occurrence, including <code>null</code> for a typeless occurrence
	 * @return the newly created Occurrence object
	 * @throws OntologyManagerException if a new occurrence could not be created
	 * @throws DynamicRightsManagerException if the user is not allowed to create occurrences
	 * @see Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayChangeOccurrence(User)
	 */
	public Occurrence addOccurrence(User adder, String data, Topic type) throws OntologyManagerException,DynamicRightsManagerException;
	
	
	/**
	 * Removes an occurrence from this topic.
	 * @param remover the user who wants to remove the occurrence.
	 * @param occ the occurrence to be removed
	 * @throws OntologyManagerException if the occurrence could not be removed
	 * @throws DynamicRightsManagerException if the user is not allowed to remove occurrences
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayChangeOccurrence(User)
	 */
	public void removeOccurrence(User remover, Occurrence occ) throws OntologyManagerException,DynamicRightsManagerException;

	
	/**
	 * Returns a collection of all Occurrence objects for this topic.
	 * The collection contains only occurrences whose type the user is allowed to see.
	 * @param user the user who wants to see the occurrences.
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Occurrence
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getOccurrences(User user);
	
	
	/**
	 * Returns a collection of all Occurrence objects of a certain type for this topic.
	 * @param type the type of the occurrences
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Occurrence
	 */
	public Collection getOccurrences(Topic type);
	
	
	/**
	 * Queries an occurrence of this topic with the given id.
	 * @param user the user who wants to see the occurrence
	 * @param id the queried id
	 * @return the occurrence or <code>null</code> if there's no occurrence with the given id for this topic
	 * @see Occurrence#getId()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Occurrence getOccurrence(User user, String id);
	
	
	/**
	 * Adds another topic as a synonym to this topic (and vice versa).
	 * @param adder the user who wants to add the synonym
	 * @param synonym the synonymous topic to be added (not <code>null</code>, not this topic itself)
	 * @return a Synonym object containing the two synonymous topics
	 * @throws OntologyManagerException if the synonymous topic could not be added
	 * @throws DynamicRightsManagerException if the user is not allowed to add synonyms
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayAddSynonym(User, Topic)
	 */
	public Synonym addSynonym(User adder, Topic synonym) throws OntologyManagerException,DynamicRightsManagerException;
	
	
	/**
	 * Removes a synonymous topic from this topic (and vice versa).
	 * @param remover the user who wants to remove the synonymous topic
	 * @param synonym the synonymous topic to be removed
	 * @throws OntologyManagerException if the synonymous topic could not be removed
	 * @throws DynamicRightsManagerException if the user is not allowed to remove the synonymous topic
	 * @see Synonym
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayRemoveSynonym(User, Synonym)
	 */
	public void removeSynonym(User remover, Topic synonym) throws OntologyManagerException,DynamicRightsManagerException;
	
	
	/**
	 * Returns a collection of all Synonym objects for this topic.
	 * The collection contains only synonymous topics the user is allowed to see.
	 * @param user the user who wants to see the synonyms
	 * @return a possibly empty collection, never <code>null</code>
	 * @see Synonym
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Collection getSynonyms(User user);
	
	
	/**
	 * Queries a synonym of this topic with the given id.
	 * @param user the user who wants to see the synonym
	 * @param id the queried id
	 * @return a Synonym object containing the two synonymous topics or <code>null</code> if there's no synonym with the given id
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 */
	public Synonym getSynonym(User user, String id);
	
	
	/**
	 * Checks if the given topic is synonymous with this topic.
	 * @param topic the topic in question
	 * @return <code>true</code> if the two topics are synonymous, <code>false</code> otherwise
	 */
	public boolean isSynonymous(Topic topic);

	
	/**
	 * Queries a superclass of this topic with the given id.
	 * If this topic is not a class or if the implementation does not support classes at all, <code>null</code> is returned.
	 * @param user the user who wants to see the superclass
	 * @param id the queried id
	 * @return a SuperSubclass object containing the superclass topic or <code>null</code> if there's no superclass with the given id
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see #isClassTopic()
	 * @see #getType(User, String)
	 */
	public SuperSubclass getSuperclass(User user, String id);
	
	
	/**
	 * Returns a collection of SuperSubclass objects containing the superclasses of this class topic.
	 * If this topic is not a class or if the implementation does not support classes at all, an empty collection is returned.
	 * @param user the user who wants to see the superclasses
	 * @return a possibly empty collection, never <code>null</code>
	 * @see SuperSubclass
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see de.uka.ipd.consensus.foundation.query.QueryEngine#getSuperclasses(User, Topic)
	 * @see #getTypes(User)
	 */
	public Collection getSuperclasses(User user);
	
	
	/**
	 * Returns a collection of SuperSubclass objects containing the subclasses of this class topic.
	 * If this topic is not a class or if the implementation does not support classes at all, an empty collection is returned.
	 * @param user the user who wants to see the subclasses
	 * @return a possibly empty collection, never <code>null</code>
	 * @see SuperSubclass
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayViewTopic(User, Topic)
	 * @see de.uka.ipd.consensus.foundation.query.QueryEngine#getSubclasses(User, Topic)
	 * @see #getInstances(User)
	 */
	public Collection getSubclasses(User user);

	
	/**
	 * Adds a superclass to this topic. Both topics must be class topics.
	 * @param adder the user who wants to add the superclass
	 * @param cls the superclass topic to be added (must not be <code>null</code>)
	 * @return a SuperSubclass object containing the superclass topic
	 * @throws OntologyManagerException if the superclass could not be added
	 * @throws DynamicRightsManagerException if the user is not allowed to add a superclass
	 * @throws java.lang.UnsupportedOperationException if the implementation does not support classes
	 * @see Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayAddClass(User, Topic)
	 * @see #addType(User, Topic)
	 */
	public SuperSubclass addSuperclass(User adder, Topic cls) throws OntologyManagerException,DynamicRightsManagerException;
	
	
	/**
	 * Removes a superclass from this class topic.
	 * @param remover the user who wants to remove the superclass
	 * @param cls the superclass topic to be removed
	 * @throws OntologyManagerException if the superclass could not be removed
	 * @throws DynamicRightsManagerException if the user is not allowed to remove the superclass
	 * @throws java.lang.UnsupportedOperationException if the implementation does not support classes
	 * @see Topic#isClassTopic()
	 * @see de.uka.ipd.consensus.foundation.rights.DynamicRightsManager#mayRemoveClass(User, SuperSubclass)
	 * @see #removeType(User, Topic)
	 */
	public void removeSuperclass(User remover, Topic cls) throws OntologyManagerException,DynamicRightsManagerException;

	
	/**
	 * <p>Controls the class flag, i.e. if the topic is a class or an instance topic.</p>
	 * <p>You can use this method explicitely if the implementation is not configured to use classes,
	 * but usually you'll let the implementation decide which topics are classes by how the topics are created.</p>
	 * @param isclass <code>true</code> if the topic shall be a class topic, <code>false</code> if it shall be an instance topic
	 * @throws OntologyManagerException if the class flag could not be changed
	 * @see de.uka.ipd.consensus.foundation.ontology.OntologyManager#createClassTopic(User, String, String, Topic)
	 * @see #isClassTopic()
	 */
	public void setClassTopic(boolean isclass) throws OntologyManagerException;
	
	
	/**
	 * Checks if this topic is a class topic.
	 * @return <code>true</code> if this topic is a class topic, <code>false</code> otherwise
	 * @see #setClassTopic(boolean)
	 */
	public boolean isClassTopic();

}
