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