001 package data; 002 003 import java.util.Iterator; 004 import java.util.Set; 005 006 import data.events.VetoException; 007 008 /** 009 * A Stock. 010 * 011 * <p>Stocks are lists that refer to a {@link Catalog} and denote for each {@link CatalogItem} how many 012 * objects of this type are actually available. There are two basically different types of Stocks: 013 * 014 * <ol> 015 * <li><b>{@link CountingStock}</b><br> 016 * Stocks that store only the number of objects available for each CatalogItem.<br> 017 * This type of Stock will be used whenever the information given by the CatalogItem sufficiently 018 * describes the object.<br> 019 * In general this type of Stock should be sufficient.</li> 020 * <li><b>{@link StoringStock}</b><br> 021 * Stocks that store a list of actual StockItems for each CatalogItem.<br> 022 * This type of Stock is usually used to store additional information with the StockItems. E.g. to store 023 * the 'Stock' of lent books in a library you would create {@link StockItem StockItems} that can store 024 * the name of the borrower and the date of borrowing.<br> 025 * This type of Stock is also needed when implementing nested Stocks.</li> 026 * </ol> 027 * 028 * <p>To suit both types of Stock, {@link StockItem StockItems} are introduced. A StockItem refers to a 029 * CatalogItem but can store additional information as well.</p> 030 * 031 * <p>Stocks work always on StockItems. They add, remove and search StockItems. They are able to return an 032 * Iterator of StockItems for a given key, but can as well just count all StockItems for the same key.</p> 033 * 034 * @author Steffen Zschaler 035 * @version 2.0 18/08/1999 036 * @since v0.5 037 */ 038 public interface Stock extends StockItem, DataBasketEntrySource, DataBasketEntryDestination { 039 040 /** 041 * Add an item to the Stock. 042 * 043 * <p>The item will only be visible to users of the same DataBasket. Only after a {@link DataBasket#commit} 044 * was performed on the DataBasket, the item will become visible to other users.</p> 045 * 046 * <p>For a {@link ListenableStock} a <code>addedStockItems</code> event will be fired.</p> 047 * 048 * @param si the item to be added. 049 * @param db the DataBasket relative to which the item will be added. 050 * 051 * @override Always 052 * 053 * @exception CatalogConflictException if the items key is not contained in the corresponding {@link Catalog}. 054 * @exception DataBasketConflictException if the item has already been added/removed using another DataBasket. 055 */ 056 public void add(StockItem si, DataBasket db); 057 058 /** 059 * Add the contents of a Stock to this Stock. The method conceptually calls {@link #add} for each item in 060 * the source Stock so the same constraints apply and the same exceptions may be thrown. 061 * 062 * @override Always 063 * 064 * @param st the Stock whose contents is to be added to this Stock. 065 * @param db the DataBasket relative to which to perform the actions. <code>addStock</code> will add all 066 * items from the source Stock that are visible using this DataBasket. 067 * @param fRemove if true, the items will be removed from the source Stock prior to adding them to this 068 * Stock. Otherwise, they will be cloned prior to adding them to the Stock. 069 */ 070 public void addStock(Stock st, DataBasket db, boolean fRemove); 071 072 /** 073 * Iterate all items with a given key. 074 * 075 * <p>This method, together with {@link #iterator} is the only way of accessing the individual 076 * {@link StockItem StockItems} contained in a Stock. The iterator will deliver all items that have the 077 * specified key and are visible using the given DataBasket. Depending on the <code>fForEdit</code> 078 * parameter, the items will be retrieved in different ways. See {@link DataBasket} for an explanation of 079 * the different possibilities.</p> 080 * 081 * <p>For a {@link ListenableStock} <code>canEditStockItems</code> and <code>editingStockItems</code> events 082 * will be fired if <code>fForEdit</code> == true. {@link VetoException VetoExceptions} will be converted 083 * into <code>UnSupportedOperationException</code>s.</p> 084 * 085 * @override Always 086 * 087 * @param sKey the key for which to retrieve the StockItems. 088 * @param db the DataBasket relative to which to retrieve the StockItems. 089 * @param fForEdit if true, the StockItems will be retrieved for editing. 090 */ 091 public Iterator get(String sKey, DataBasket db, boolean fForEdit); 092 093 /** 094 * Count the StockItems with a given key that are visible using a given DataBasket. 095 * 096 * @override Always 097 * 098 * @param sKey the key for which to count the StockItems. 099 * @param db the DataBasket that is used to determine visibility. 100 */ 101 public int countItems(String sKey, DataBasket db); 102 103 /** 104 * Check whether the Stock contains an item with the given key. 105 * 106 * <p>Equivalent to:<code>({@link #countItems} (sKey, db) > 0)</code>.</p> 107 * 108 * @override Always 109 * 110 * @param sKey the key for which to check containment. 111 * @param db the DataBasket used to check visibility. 112 */ 113 public boolean contains(String sKey, DataBasket db); 114 115 /** 116 * Check whether the Stock contains the given StockItem. 117 * 118 * <p>Return true if the Stock contains a StockItem that is equal to the given one.</p> 119 * 120 * @param si the StockItem for which to check containment. 121 * @param db the DataBasket used to check visibility. 122 * 123 * @override Always. 124 */ 125 public boolean contains(StockItem si, DataBasket db); 126 127 /** 128 * Check whether the given Stock is completely contained in this Stock. 129 * 130 * <p>Conceptually calls {@link #contains(data.StockItem, data.DataBasket)} for each item in the given Stock. 131 * </p> 132 * 133 * @override Always 134 * 135 * @param st the Stock for which to check containment. 136 * @param db the DataBasket used to determine visibility. 137 */ 138 public boolean containsStock(Stock st, DataBasket db); 139 140 /** 141 * Remove one StockItem with the specified key from the Stock. 142 * 143 * <p>If there are any StockItems with the specified key, one will be removed. There is no guarantee as to 144 * which StockItem will be removed. The removed item, if any, will be returned.</p> 145 * 146 * <p>For a {@link ListenableStock} <code>canRemoveStockItems</code> and <code>removedStockItems</code> 147 * events will be fired.</p> 148 * 149 * @override Always 150 * 151 * @param sKey the key for which to remove an item. 152 * @param db the DataBasket relative to which to remove the item. 153 * 154 * @return the removed item 155 * 156 * @exception VetoException if a listener vetoed the removal. 157 * @exception DataBasketConflictException if the item cannot be removed due to conflicts from DataBasket 158 * usage. 159 */ 160 public StockItem remove(String sKey, DataBasket db) throws VetoException; 161 162 /** 163 * Remove the given StockItem from the Stock. 164 * 165 * <p>If the given StockItem is contained in the Stock, it will be removed. The removed item, if any, will 166 * be returned.</p> 167 * 168 * <p>For a {@link ListenableStock} <code>canRemoveStockItems</code> and <code>removedStockItems</code> 169 * events will be fired.</p> 170 * 171 * @override Always 172 * 173 * @param si the StockItem to be removed. 174 * @param db the DataBasket relative to which to remove the item. 175 * 176 * @return the removed item 177 * 178 * @exception VetoException if a listener vetoed the removal. 179 * @exception DataBasketConflictException if the item cannot be removed due to conflicts from DataBasket 180 * usage. 181 */ 182 public StockItem remove(StockItem si, DataBasket db) throws VetoException; 183 184 /** 185 * Iterate all items in the Stock. 186 * 187 * <p>This method, together with {@link #get} is the only way of accessing the individual 188 * {@link StockItem StockItems} contained in a Stock. The iterator will deliver all items that are visible 189 * using the given DataBasket. Depending on the <code>fForEdit</code> parameter, the items will be retrieved 190 * in different ways. See {@link DataBasket} for an explanation of the different possibilities.</p> 191 * 192 * <p>For a {@link ListenableStock} <code>canEditStockItems</code> and <code>editingStockItems</code> events 193 * will be fired if <code>fForEdit</code> == true. {@link VetoException VetoExceptions} will be converted 194 * into <code>UnSupportedOperationException</code>s.</p> 195 * 196 * @override Always 197 * 198 * @param db the DataBasket relative to which to retrieve the StockItems. 199 * @param fForEdit if true, the StockItems will be retrieved for editing. 200 */ 201 public Iterator iterator(DataBasket db, boolean fForEdit); 202 203 /** 204 * Return the set of keys for which {@link StockItem StockItems} are visible using the given DataBasket. 205 * 206 * <p>The returned set is static and gives the state of the Stock at the time of the call. It will not 207 * automatically update when the contents of the Stock changes.</p> 208 * 209 * @param db the DataBasket used for determining visibility. 210 * 211 * @override Always 212 */ 213 public Set keySet(DataBasket db); 214 215 /** 216 * Sum up the Stock. 217 * 218 * <p>The method will determine the value of each {@link CatalogItem} in the associated Catalog and 219 * {@link Value#multiplyAccumulating(int) multiply} this by 220 * {@link #countItems the number of StockItems for the respective key}. These products will be 221 * {@link Value#addAccumulating added up} and the resulting total will be returned.</p> 222 * 223 * @override Always 224 * 225 * @param db the DataBasket that is used to determine visibility. 226 * @param civ the CatalogItemValue used for determining the value of a CatalogItem. 227 * @param vInit the initial value. The sum of the Stock will be added to this value. 228 * 229 * @return the resulting total. Usually the returned object is the same as the one passed as 230 * <code>vInit</code>, only with a changed value. 231 */ 232 public Value sumStock(DataBasket db, CatalogItemValue civ, Value vInit); 233 234 /** 235 * Increase the {@link #sumStock Stock's value} by a given value. 236 * 237 * <p>The method will try to break the given value as exactly as possible into StockItems that will be 238 * added to the Stock. The actual algorithm used for breaking up the value will be determined by the last 239 * parameter. The return value of the method will specify the remaining value that could not be represented 240 * by StockItems by the given algorithm.</p> 241 * 242 * @param db the DataBasket relative to which to perform the operation. 243 * @param vTarget the value by which to increase the Stock's total value. 244 * @param sfvc the strategy used to fill the Stock. 245 * 246 * @return the value that remained and could not be represented by StockItems. 247 * 248 * @override Always 249 */ 250 public Value fillStockWithValue(DataBasket db, Value vTarget, StockFromValueCreator sfvc); 251 252 /** 253 * Get the size of this Stock. I.e. calculate the number of StockItems that can be seen when using the 254 * given DataBasket. 255 * 256 * @param db the DataBasket used to determine visibility. 257 * 258 * @override Always 259 */ 260 public int size(DataBasket db); 261 262 /** 263 * Get the Catalog associated to this Stock. 264 * 265 * <p>For a substock of another stock this is essentially equivalent to 266 * <pre> 267 * Catalog cReturn = (Catalog) {@link StockItem#getAssociatedItem getAssociatedItem} (db); 268 * 269 * if (cReturn != null) { 270 * return cReturn; 271 * } 272 * else { 273 * throw new {@link DataBasketConflictException}(); 274 * } 275 * </pre> 276 * 277 * @param db a DataBasket determinig visibility of the stock's catalog. 278 * 279 * @override Always 280 */ 281 public Catalog getCatalog(DataBasket db); 282 }