package data; import java.util.*; import data.events.*; /** * A Stock. * * <p>Stocks are lists that refer to a {@link Catalog} and denote for each {@link CatalogItem} how many * objects of this type are actually available. There are two basically different types of Stocks: * * <ol> * <li><b>{@link CountingStock}</b><br> * Stocks that store only the number of objects available for each CatalogItem.<br> * This type of Stock will be used whenever the information given by the CatalogItem sufficiently * describes the object.<br> * In general this type of Stock should be sufficient.</li> * <li><b>{@link StoringStock}</b><br> * Stocks that store a list of actual StockItems for each CatalogItem.<br> * This type of Stock is usually used to store additional information with the StockItems. E.g. to store * the 'Stock' of lent books in a library you would create {@link StockItem StockItems} that can store * the name of the borrower and the date of borrowing.<br> * This type of Stock is also needed when implementing nested Stocks.</li> * </ol> * * <p>To suit both types of Stock, {@link StockItem StockItems} are introduced. A StockItem refers to a * CatalogItem but can store additional information as well.</p> * * <p>Stocks work always on StockItems. They add, remove and search StockItems. They are able to return an * Iterator of StockItems for a given key, but can as well just count all StockItems for the same key.</p> * * @author Steffen Zschaler * @version 2.0 18/08/1999 * @since v0.5 */ public interface Stock extends StockItem, DataBasketEntrySource, DataBasketEntryDestination { /** * Add an item to the Stock. * * <p>The item will only be visible to users of the same DataBasket. Only after a {@link DataBasket#commit} * was performed on the DataBasket, the item will become visible to other users.</p> * * <p>For a {@link ListenableStock} a <code>addedStockItems</code> event will be fired.</p> * * @param si the item to be added. * @param db the DataBasket relative to which the item will be added. * * @override Always * * @exception CatalogConflictException if the items key is not contained in the corresponding {@link Catalog}. * @exception DataBasketConflictException if the item has already been added/removed using another DataBasket. */ public void add (StockItem si, DataBasket db); /** * Add the contents of a Stock to this Stock. The method conceptually calls {@link #add} for each item in * the source Stock so the same constraints apply and the same exceptions may be thrown. * * @override Always * * @param st the Stock whose contents is to be added to this Stock. * @param db the DataBasket relative to which to perform the actions. <code>addStock</code> will add all * items from the source Stock that are visible using this DataBasket. * @param fRemove if true, the items will be removed from the source Stock prior to adding them to this * Stock. Otherwise, they will be cloned prior to adding them to the Stock. */ public void addStock (Stock st, DataBasket db, boolean fRemove); /** * Iterate all items with a given key. * * <p>This method, together with {@link #iterator} is the only way of accessing the individual * {@link StockItem StockItems} contained in a Stock. The iterator will deliver all items that have the * specified key and are visible using the given DataBasket. Depending on the <code>fForEdit</code> * parameter, the items will be retrieved in different ways. See {@link DataBasket} for an explanation of * the different possibilities.</p> * * <p>For a {@link ListenableStock} <code>canEditStockItems</code> and <code>editingStockItems</code> events * will be fired if <code>fForEdit</code> == true. {@link VetoException VetoExceptions} will be converted * into <code>UnSupportedOperationException</code>s.</p> * * @override Always * * @param sKey the key for which to retrieve the StockItems. * @param db the DataBasket relative to which to retrieve the StockItems. * @param fForEdit if true, the StockItems will be retrieved for editing. */ public Iterator get (String sKey, DataBasket db, boolean fForEdit); /** * Count the StockItems with a given key that are visible using a given DataBasket. * * @override Always * * @param sKey the key for which to count the StockItems. * @param db the DataBasket that is used to determine visibility. */ public int countItems (String sKey, DataBasket db); /** * Check whether the Stock contains an item with the given key. * * <p>Equivalent to:<code>({@link #countItems} (sKey, db) > 0)</code>.</p> * * @override Always * * @param sKey the key for which to check containment. * @param db the DataBasket used to check visibility. */ public boolean contains (String sKey, DataBasket db); /** * Check whether the Stock contains the given StockItem. * * <p>Return true if the Stock contains a StockItem that is equal to the given one.</p> * * @param si the StockItem for which to check containment. * @param db the DataBasket used to check visibility. * * @override Always. */ public boolean contains (StockItem si, DataBasket db); /** * Check whether the given Stock is completely contained in this Stock. * * <p>Conceptually calls {@link #contains(data.StockItem, data.DataBasket)} for each item in the given Stock. * </p> * * @override Always * * @param st the Stock for which to check containment. * @param db the DataBasket used to determine visibility. */ public boolean containsStock (Stock st, DataBasket db); /** * Remove one StockItem with the specified key from the Stock. * * <p>If there are any StockItems with the specified key, one will be removed. There is no guarantee as to * which StockItem will be removed. The removed item, if any, will be returned.</p> * * <p>For a {@link ListenableStock} <code>canRemoveStockItems</code> and <code>removedStockItems</code> * events will be fired.</p> * * @override Always * * @param sKey the key for which to remove an item. * @param db the DataBasket relative to which to remove the item. * * @return the removed item * * @exception VetoException if a listener vetoed the removal. * @exception DataBasketConflictException if the item cannot be removed due to conflicts from DataBasket * usage. */ public StockItem remove (String sKey, DataBasket db) throws VetoException; /** * Remove the given StockItem from the Stock. * * <p>If the given StockItem is contained in the Stock, it will be removed. The removed item, if any, will * be returned.</p> * * <p>For a {@link ListenableStock} <code>canRemoveStockItems</code> and <code>removedStockItems</code> * events will be fired.</p> * * @override Always * * @param si the StockItem to be removed. * @param db the DataBasket relative to which to remove the item. * * @return the removed item * * @exception VetoException if a listener vetoed the removal. * @exception DataBasketConflictException if the item cannot be removed due to conflicts from DataBasket * usage. */ public StockItem remove (StockItem si, DataBasket db) throws VetoException; /** * Iterate all items in the Stock. * * <p>This method, together with {@link #get} is the only way of accessing the individual * {@link StockItem StockItems} contained in a Stock. The iterator will deliver all items that are visible * using the given DataBasket. Depending on the <code>fForEdit</code> parameter, the items will be retrieved * in different ways. See {@link DataBasket} for an explanation of the different possibilities.</p> * * <p>For a {@link ListenableStock} <code>canEditStockItems</code> and <code>editingStockItems</code> events * will be fired if <code>fForEdit</code> == true. {@link VetoException VetoExceptions} will be converted * into <code>UnSupportedOperationException</code>s.</p> * * @override Always * * @param db the DataBasket relative to which to retrieve the StockItems. * @param fForEdit if true, the StockItems will be retrieved for editing. */ public Iterator iterator (DataBasket db, boolean fForEdit); /** * Return the set of keys for which {@link StockItem StockItems} are visible using the given DataBasket. * * <p>The returned set is static and gives the state of the Stock at the time of the call. It will not * automatically update when the contents of the Stock changes.</p> * * @param db the DataBasket used for determining visibility. * * @override Always */ public Set keySet (DataBasket db); /** * Sum up the Stock. * * <p>The method will determine the value of each {@link CatalogItem} in the associated Catalog and * {@link Value#multiplyAccumulating(int) multiply} this by * {@link #countItems the number of StockItems for the respective key}. These products will be * {@link Value#addAccumulating added up} and the resulting total will be returned.</p> * * @override Always * * @param db the DataBasket that is used to determine visibility. * @param civ the CatalogItemValue used for determining the value of a CatalogItem. * @param vInit the initial value. The sum of the Stock will be added to this value. * * @return the resulting total. Usually the returned object is the same as the one passed as * <code>vInit</code>, only with a changed value. */ public Value sumStock (DataBasket db, CatalogItemValue civ, Value vInit); /** * Increase the {@link #sumStock Stock's value} by a given value. * * <p>The method will try to break the given value as exactly as possible into StockItems that will be * added to the Stock. The actual algorithm used for breaking up the value will be determined by the last * parameter. The return value of the method will specify the remaining value that could not be represented * by StockItems by the given algorithm.</p> * * @param db the DataBasket relative to which to perform the operation. * @param vTarget the value by which to increase the Stock's total value. * @param sfvc the strategy used to fill the Stock. * * @return the value that remained and could not be represented by StockItems. * * @override Always */ public Value fillStockWithValue (DataBasket db, Value vTarget, StockFromValueCreator sfvc); /** * Get the size of this Stock. I.e. calculate the number of StockItems that can be seen when using the * given DataBasket. * * @param db the DataBasket used to determine visibility. * * @override Always */ public int size (DataBasket db); /** * Get the Catalog associated to this Stock. * * <p>For a substock of another stock this is essentially equivalent to * <pre> * Catalog cReturn = (Catalog) {@link StockItem#getAssociatedItem getAssociatedItem} (db); * * if (cReturn != null) { * return cReturn; * } * else { * throw new {@link DataBasketConflictException}(); * } * </pre> * * @param db a DataBasket determinig visibility of the stock's catalog. * * @override Always */ public Catalog getCatalog (DataBasket db); }