/*
 ************************************************************************
 *
 * Copyright (c) 2003-2004, C&C Research Laboratories, NEC Europe Ltd.
 *
 * Copyright in this software belongs to C&C Research Laboratories,
 * Rathausallee 10, 53757 Sankt Augustin, Germany.
 *
 * This software may not be used, sold, licensed, transferred, copied
 * or reproduced in whole or in part in any manner or form or in or
 * on any media by any person other than in accordance with the terms
 * of the Licence Agreement supplied with the software, or otherwise
 * without the prior written consent of the copyright owners.
 *
 * This software is distributed WITHOUT ANY WARRANTY, without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE, except where stated in the Licence Agreement supplied with
 * the software.
 *
 *  Created By :           G.A. Kohring
 *  Created for Project :  GEMSS (IST-2001-37153)
 *
 ************************************************************************
 *
 */
                                                                                
package de.nece.ccrle.util;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * A catalog classifies items into categories.
 * Within each catagory their are no duplicate items.  A <em>category</em>
 * is identified by an <code>Object</code>.
 *
 * @author  G.A. Kohring
 */
public interface Catalog extends Map{
    //
    // Query Operations
    //

    /**
     * Returns the number of items in the specified category.
     * If the category contains more than 
     * <code>Integer.MAX_VALUE</code> items,
     * returns <code>Integer.MAX_VALUE</code>.
     *
     * @param category the category whose size is to be returned.
     * @return the number of items associated
     *      with the category or <code>-1</code> if no such category exists
     *      in this catalog.
     */
    public int size( Object category );

    /**
     * Returns the number of categories in the catalog.
     * If the catalog contains more than
     * <code>Integer.MAX_VALUE</code> categories,
     * returns <code>Integer.MAX_VALUE</code>.
     *
     * @return the number of categories in the catalog.
     */
    public int size();

    /**
     * Returns a set view of the categories contained in this catalog.
     * <p>
     * Note this is a convenience operation which should convey more
     * meaning than the <code>keySet()</code> method of the
     * <code>Map</code> interface.
     * <p>
     * The set is backed by the catalog, so changes to the catalog are
     * reflected in the set, and vice-versa. If the catalog is modified while
     * an iteration over the set is in progress, the results of the
     * iteration are undefined. The set supports element removal,
     * which removes the corresponding category from the catalog, via
     * the Iterator.remove, Set.remove, removeAll retainAll, and clear
     * operations. It does not support the add or addAll operations.
     */
    public Set categories();

    /**
     * Returns <code>true</code> if the specified category contains no items.
     *
     * @param category the category whose status is to be queried.
     * @return <code>true</code> if this category contains no items.
     */
    public boolean isEmpty( Object category );

    /**
     * Returns <code>true</code> if this catalog contains the specified item
     * under one or more categories.
     * More formally, returns <code>true</code> if and only if this catalog 
     * contains at least one item in any catagory <code>i</code> such that
     * <code>(item==null ? v==null : item.equals(i))</code>.  This operation
     * will probably require time linear in the number of categories for most
     * implementations of the <code>Catalog</code> interface.
     *
     * @param item item whose presence in this catalog is to be tested.
     * @return <code>true</code> if this catalog contains the specified item
     *      under one or more categories.
     * @throws ClassCastException if the item is of an inappropriate type for
     * 		  this catalog (optional).
     * @throws NullPointerException if the item is <code>null</code> and this
     *      catalog does not not permit <code>null</code> items (optional).
     */
    public boolean containsItem( Object item );

    /**
     * Return <code>true</code> if this map contains the
     * specified category.
     *
     * @param category the category whose presence in this catalog is to be
     *      tested.
     * @return <code>true</code> if this catalog contains the specified
     *      category.
     * @throws ClassCastException if the category is of an inappropriate 
     *      type for this catalog (optional).
     * @throws NullPointerException if the category is <code>null</code> 
     *      and this
     *      catalog does not not permit <code>null</code> categories (optional).
     */
    public boolean containsCategory( Object category );

    /**
     * Returns the set of items in the specified category. Returns
     * <code>null</code> if the catalog does not contain the category. 
     *
     * @param category the category whose associated items 
     *      are to be
     *        returned.
     * @return the set of items classified under this category, or
     *	       <code>null</code> if catalog does not contain the category.
     * 
     * @throws ClassCastException if the category is of an inappropriate 
     *      type for
     * 		this catalog (optional).
     * @throws NullPointerException if category is <code>null</code> and 
     *      this catalog
     *      does not permit <code>null</code> categories (optional).
     * 
     * @see #containsItem(Object)
     * @see Map#get(Object)
     */
    public Set getItems( Object category );

    //
    // Modification Operations
    //

    /**
     * Associates the specified set of items with the specified category in 
     * this catalog (optional operation).  If the catalog previously 
     * contained the specified category, then the new set of items is copied
     * into the old set of items. If the set of
     * items is null, then a new, empty category is created in the catalog if
     * no such category exist before.
     *
     * @param category the category under which the set of
     *              items are to be associated
     * @param items set of items to be associated with the 
     *      specified category.
     * @return true if the category was already present in this catalog.
     * 
     * @throws UnsupportedOperationException if the <code>put</code> 
     *      operation is not supported by this catalog.
     * @throws ClassCastException if the class of the specified category
     * 	       prevents it from being stored in this catalog.
     * @throws IllegalArgumentException if some aspect of this category or 
     *      set of items prevents it from being stored in this catalog.
     * @throws NullPointerException if this catalog does not permit 
     *      <code>null</code> categories, and the specified category is 
     *      <code>null</code>. 
     */
    public boolean addItems( Object category, Set items );

    /**
     * Classifies the specified item under the specified category 
     * (optional operation). If the category does not exist in the catalog,
     * then it is first added before the item is classified.
     *
     * @param category the category under which the specified item
     *              is to be classified.
     * @param item item to be classified under the specified category.
     * @return <code>true</code> if the specified item already exists in
     *         the category.
     * 
     * @throws UnsupportedOperationException if the <code>put</code> 
     *      operation is not supported by this catalog.
     * @throws ClassCastException if the class of the specified category 
     *      or item prevents it from being stored in this catalog.
     * @throws IllegalArgumentException if some aspect of this category or
     *      item prevents it from being stored in this catalog.
     * @throws NullPointerException if this catalog does not permit 
     *         <code>null</code>
     *            categories or items, and the specified category or item is
     *            <code>null</code>.
     */
    public boolean addItem( Object category, Object item );

    /**
     * Adds the specified category to the catalog and associaties with it an
     * empty set (optional operation). If the specified category already 
     * exists,
     * then the catalog is not changed and the method returns <code>true</code>
     *
     * @param category cateory representing the category under which the 
     *      specified item is to be classified.
     * @return <code>true</code> if the category already exists.
     * 
     * @throws UnsupportedOperationException if the <code>put</code> 
     *      operation is not supported by this catalog.
     * @throws ClassCastException if the class of the specified category 
     * 	          prevents it from being stored in this catalog.
     * @throws IllegalArgumentException if some aspect of this category
     *	          prevents it from being stored in this catalog.
     * @throws NullPointerException if this catalog does not permit 
     *         <code>null</code>
     *         categories, and the specified category is <code>null</code>.
     */
    public boolean add( Object category );



    /**
     * Removes the specified item from the specified category
     * (optional operation). 
     * <p>
     * Returns the <code>true</code> if the specified category contained the
     * specified item and <code>false</code> otherwise.
     *
     * @param category the category from which the specified 
     *      item is to be removed.
     * @param item item which is to be removed from this category.
     * @return <code>true</code> if the specified category contained the
     *      specified item
     *
     * @throws UnsupportedOperationException if the <code>remove</code> 
     *      method is not supported by this catalog.
     */
    public boolean remove( Object category, Object item );


    // 
    // Bulk Operations
    // 

    /**
     * Copies all of the categories and their associated items from the 
     * specified catalog to this catalog
     * (optional operation).  
     *
     * @param catalog the <code>Catalog</code> of objects to be stored 
     *      in this catalog.
     * 
     * @throws UnsupportedOperationException if the <code>putAll</code> 
     *      method is
     * 		  not supported by this catalog.
     * 
     * @throws ClassCastException if the class of a category or item in the
     * 	     specified catalog prevents it from being stored in this catalog.
     * 
     * @throws IllegalArgumentException if some aspect of a category or item 
     *          in the
     *	          specified catalog prevents it from being stored in this
     *	          catalog.
     * @throws NullPointerException the specified catalog is <code>null</code>, 
     *      or if this catalog does not permit <code>null</code> category 
     *      or items, 
     *      and the specified catalog contains <code>null</code> category 
     *      or items.
     */
    public void putAll( Catalog catalog );

    /**
     * Removes all the items from the specified category, but leaves the
     * category in the catalog (optional operation). 
     * <p>
     * Returns the set of items which the catalog previously 
     * classified under the category, or
     * <code>null</code> if the catalog contained no such category.
     *
     * @param category the category whose items are to be deleted.
     * @throws UnsupportedOperationException if clear is not supported by this
     * 		  catalog.
     */
    public Set clear( Object category );

}
