001 package data; 002 003 import java.io.Serializable; 004 import java.util.Iterator; 005 006 import log.LogContext; 007 008 /** 009 * An object collecting information about a activities on data objects in a 010 * {@link sale.Shop shop}. 011 * 012 * <p>The DataBasket is used in the manner of a "transcation handle", 013 * i.e. all actions with data containers (e.g. {@link Catalog Catalogs}, 014 * {@link Stock Stocks} etc.) are processed relative to this DataBasket. The 015 * following rules apply:</p> 016 * 017 * <ul> 018 * <li><strong>Adding items to data containers:</strong><br> 019 * All adding of items is only temporary until an explicit 020 * {@link #commit commit} is performed on the DataBasket. Freshly added 021 * items are only visible to the owner of the DataBasket relative to 022 * which they were added. However, there may be cases when the temporary 023 * adding of an entry to a data container prevents other entries (e.g., 024 * of the same key) from being added. This is, for example, the case with 025 * Catalogs, because there can always be at most one CatalogItem for any 026 * given key in any given Catalog. The resulting conflict is 027 * conventionally resolved by throwing a DataBasketConflictException that 028 * also states the reason for the conflict in its detail message.</li> 029 * <li><strong>Removing items from a data container:</strong><br> 030 * All removing of items is only temporary until an explicit 031 * {@link #commit commit} is performed on the DataBasket. Usually, adding 032 * an item just removed using the same DataBasket, will roll back the 033 * activity. However, this is container specific behavior that may differ 034 * between containers.</li> 035 * <li><strong>Looking at an item from a data container:</strong><br> 036 * Only items that are really in the container, plus items that have been 037 * added using the same DataBasket are visible. Usually there are two 038 * different modes of looking at an item: just for reading or for 039 * editing the item. These differ in several ways: 040 * <ol> 041 * <li>There is no guarantee that an item just got for reading will 042 * still be in the container the next time you look. For items that 043 * you got for editing purposes this guarantee can be given. 044 * </li> 045 * <li>Items you got for editing will no longer be visible for users 046 * of different DataBaskets. This is the reason why the former 047 * assertion can be given. The items will become visible again, 048 * when a {@link #commit commit} is performed.</li> 049 * <li>Although you can edit items that you just got for reading, by 050 * doing so, you loose the ability to undo the action and, because 051 * others can see the changing in progress, you risk 052 * inconsistencies in your data. Therefore, such behavior is 053 * considered bad style and is not recommended.</li> 054 * </ol> 055 * </li> 056 * </ul> 057 * 058 * <p>DataBaskets provide the capability to undo whole blocks of activities 059 * without having to consider the single activities. To do so, you simply call 060 * {@link #rollback one of the rollback methods} on the DataBasket relative to 061 * which the activities where performed. On the other hand, you will have to 062 * call {@link #commit commit} to fix changes and make them visible to owners 063 * of other DataBaskets. Once commited, a change can no longer be rolled back. 064 * </p> 065 * 066 * <p>Additionally, you can define subsections in a DataBasket, which can be 067 * commited or rolled back individually and independently. Also you can commit 068 * or rollback an arbitrary subset of elements by defining a selecting 069 * condition. These operations are, however, optional, and may not be 070 * implemented in all concrete implementations of the DataBasket interface.</p> 071 * 072 * <p>In addition to their useability as "transaction handles", 073 * DataBaskets can be inspected, thus allowing for applications where customers 074 * can roam the Shop freely, deciding to take things and to put them back, and 075 * will only be charged at the end, based on the contents of their DataBasket. 076 * To implement such strategies, see {@link #iterator}, {@link #sumBasket}.</p> 077 * 078 * <p>DataBaskets allow for a {@link LogContext} to be defined. Operations on 079 * the DataBasket can be logged using the current LogContext of the DataBasket. 080 * You can decide which actions are being logged by setting the appropriate 081 * parameter in a call to {@link #setLogMode}.</p> 082 * 083 * @author Steffen Zschaler 084 * @version 2.0 10/06/1999 085 * @since v2.0 086 */ 087 public interface DataBasket extends Serializable { 088 089 /** 090 * Commit the entire contents of the DataBasket. 091 * 092 * <p>All temporarily added or removed items will be finally added or removed from their 093 * respective containers. All items got for editing will be put back into their container 094 * and any changes to them will be fixed. All items that have only been visible to users 095 * of this DataBasket will henceforward be visible for every user. Every item that was 096 * committed will be removed from the DataBasket and, thus, the DataBasket will be empty. 097 * </p> 098 * 099 * @see #rollback 100 * 101 * @override Always 102 */ 103 public void commit(); 104 105 /** 106 * Roll back the entire contents of the DataBasket. 107 * 108 * <p>All temporarily added or removed items will be removed from, or put back into, 109 * their respective containers, resp. All changes that where made to items that were 110 * edited will be undone. All items will be restored to their original visibility. 111 * Every item that was rolled back will be removed from the DataBasket and, thus, the 112 * DataBasket will be empty.</p> 113 * 114 * @see #commit 115 * 116 * @override Always 117 */ 118 public void rollback(); 119 120 /** 121 * Commit the contents of the named subbasket. 122 * 123 * <p>All items in the named subbasket will be commited, and the subbasket will be empty 124 * afterwards. Any item that is not in the subbasket will not be touched, unless 125 * dependencies between the items require so. For a description of the commit process 126 * refer to {@link #commit()}.</p> 127 * 128 * <p>This is an optional operation that does not need to be supported by concrete 129 * implementations of the interface. To indicate that this method is not supported, such 130 * implementations must throw an UnSupportedOperationException.</p> 131 * 132 * @param sName the name of the subbasket to be commited. 133 * 134 * @exception UnsupportedOperationException to indicate that this method is not 135 * implemented in a certain implementation of the interface. 136 * 137 * @see #setCurrentSubBasket 138 * @see #rollbackSubBasket 139 * 140 * @override Always 141 */ 142 public void commitSubBasket(String sName); 143 144 /** 145 * Commit the contents of the current subbasket. 146 * 147 * <p>All items in the current subbasket will be commited, and the subbasket will be empty 148 * afterwards. Any item that is not in the subbasket will not be touched, unless 149 * dependencies between the items require so. For a description of the commit process 150 * refer to {@link #commit()}.</p> 151 * 152 * <p>This is an optional operation that does not need to be supported by concrete 153 * implementations of the interface. To indicate that this method is not supported, such 154 * implementations must throw an UnSupportedOperationException.</p> 155 * 156 * @exception UnsupportedOperationException to indicate that this method is not 157 * implemented in a certain implementation of the interface. 158 * 159 * @see #setCurrentSubBasket 160 * @see #rollbackCurrentSubBasket 161 * 162 * @override Always 163 */ 164 public void commitCurrentSubBasket(); 165 166 /** 167 * Roll back the contents of the named subbasket. 168 * 169 * <p>All items in the named subbasket will be rolled back, and the subbasket will be 170 * empty afterwards. Any item that is not in the subbasket will not be touched, unless 171 * dependencies between the items require so. For a description of the rollback process 172 * refer to {@link #rollback()}.</p> 173 * 174 * <p>This is an optional operation that does not need to be supported by concrete 175 * implementations of the interface. To indicate that this method is not supported, such 176 * implementations must throw a UnSupportedOperationException.</p> 177 * 178 * @param sName the name of the subbasket to be rolled back. 179 * 180 * @exception UnsupportedOperationException to indicate that this method is not 181 * implemented in a certain implementation of the interface. 182 * 183 * @see #setCurrentSubBasket 184 * @see #commitSubBasket 185 * 186 * @override Always 187 */ 188 public void rollbackSubBasket(String sName); 189 190 /** 191 * Roll back the contents of the current subbasket. 192 * 193 * <p>All items in the current subbasket will be rolled back, and the subbasket will be 194 * empty afterwards. Any item that is not in the subbasket will not be touched, unless 195 * dependencies between the items require so. For a description of the rollback process 196 * refer to {@link #rollback()}.</p> 197 * 198 * <p>This is an optional operation that does not need to be supported by concrete 199 * implementations of the interface. To indicate that this method is not supported, such 200 * implementations must throw an UnSupportedOperationException.</p> 201 * 202 * @exception UnsupportedOperationException to indicate that this method is not 203 * implemented in a certain implementation of the interface. 204 * 205 * @see #setCurrentSubBasket 206 * @see #commitCurrentSubBasket 207 * 208 * @override Always 209 */ 210 public void rollbackCurrentSubBasket(); 211 212 /** 213 * Commit all items that match the given condition. 214 * 215 * <p>All items matching the condition will be commited and removed from the DataBasket. 216 * No other item will be touched, unless dependencies between the items require so. For a 217 * description of the commit process refer to {@link #commit()}.</p> 218 * 219 * <p>This is an optional operation that does not need to be supported by concrete 220 * implementations of the interface. To indicate that this method is not supported, such 221 * implementations must throw an UnSupportedOperationException.</p> 222 * 223 * @exception UnsupportedOperationException to indicate that this method is not 224 * implemented in a certain implementation of the interface. 225 * 226 * @override Always 227 */ 228 public void commit(DataBasketCondition dbc); 229 230 /** 231 * Roll back all items that match the given condition. 232 * 233 * <p>All items matching the condition will be rolled back and removed from the 234 * DataBasket. No other item will be touched, unless dependencies between the items 235 * require so. For a description of the rollback process refer to {@link #rollback()}. 236 * </p> 237 * 238 * <p>This is an optional operation that does not need to be supported by concrete 239 * implementations of the interface. To indicate that this method is not supported, such 240 * implementations must throw an UnSupportedOperationException.</p> 241 * 242 * @exception UnsupportedOperationException to indicate that this method is not 243 * implemented in a certain implementation of the interface. 244 * 245 * @override Always 246 */ 247 public void rollback(DataBasketCondition dbc); 248 249 /** 250 * Set the current subbasket. 251 * 252 * <p>If no SubBasket of the given name exists, an empty one will be created and made 253 * the current SubBasket.</p> 254 * 255 * <p>All {@link #put put} operations put entries into the current subbasket of a 256 * DataBasket.</p> 257 * 258 * <p>SubBaskets can be used to define sets of independently commitable (or rollbackable, 259 * resp.) entries in a DataBasket. Thus you can build something similar to nested 260 * Transactions or SafePoints. However, when using SubBaskets, it is at least partly 261 * your responsibility to make sure, there are no dependencies between the contents of 262 * different SubBaskets. If you don't, or if you do not take measures to resolve such 263 * situations, using SubBaskets may result in inconsistent data in your system.</p> 264 * 265 * <p>This is an optional operation that does not need to be supported by concrete 266 * implementations of the interface. To indicate that this method is not supported, such 267 * implementations must throw an UnSupportedOperationException. Implementations may also 268 * choose to implement this method (and any other methods related to SubBaskets) in part, 269 * i.e. with more rigid preconditions defined. Such implementations would still throw an 270 * UnsupportedOperationException if the preconditions are not met. For example, an 271 * implementation based on relational databases might want to allow LIFO usage of 272 * SubBaskets as this can be modelled by nesting database transactions. It will throw an 273 * exception, however, when a client tries to use SubBaskets in a more random way.</p> 274 * 275 * @exception UnsupportedOperationException to indicate that this method is not 276 * implemented in a certain implementation of the interface. 277 * 278 * @see #commitSubBasket 279 * @see #rollbackSubBasket 280 * @see #commitCurrentSubBasket 281 * @see #rollbackCurrentSubBasket 282 * @see #DEFAULTSUBBASKET_NAME 283 * 284 * @override Always 285 */ 286 public void setCurrentSubBasket(String sName); 287 288 /** 289 * The name of the default subbasket. 290 * 291 * <p>Every DataBasket has at least one SubBasket, that is used as long as no other 292 * SubBasket has been specified. This is the default subbasket and its name is stored 293 * in this constant.</p> 294 * 295 * @see #setCurrentSubBasket 296 */ 297 public static final String DEFAULTSUBBASKET_NAME = "__TAG:_DEFAULT_SUBBASKET"; 298 299 /** 300 * Iterate the contents of this DataBasket. 301 * 302 * <p>The iterator will iterate the entire contents of the DataBasket, but will return 303 * only such items, that match the given condition.</p> 304 * 305 * @param dbc a condition, that items must match to be returned by the iterator. 306 * 307 * @override Always 308 */ 309 public Iterator<DataBasketEntry> iterator(DataBasketCondition dbc); 310 311 /** 312 * Iterate the contents of a given SubBasket. 313 * 314 * <p>The iterator will iterate all items in the given SubBasket that match the given 315 * condition.</p> 316 * 317 * @param sName the name of the SubBasket. A {@link NullPointerException} may 318 * be thrown if this SubBasket does not exist. 319 * @param dbc the condition that must be matched by items that are to be returned by the 320 * iterator 321 * 322 * @override Always 323 */ 324 public Iterator<DataBasketEntry> subBasketIterator(String sName, DataBasketCondition dbc); 325 326 /** 327 * Sum up the values of all items in this DataBasket that match the condition. 328 * 329 * @param dbc the condition that must be matched by all entries that are to be used in the 330 * process of adding up the DataBasket. 331 * @param bev an object helping in determining the value of a single entry. 332 * @param vInit the value that is to be used for adding up. All adding is performed by calling 333 * {@link Value#addAccumulating} on this object. 334 * 335 * @return the sum in <code>vInit</code>. 336 * 337 * @override Always 338 */ 339 public Value sumBasket(DataBasketCondition dbc, BasketEntryValue bev, Value vInit); 340 341 /** 342 * Sum up the values of all items in the given subbasket that match the condition. 343 * 344 * @param sName the name of the subbasket whose items are to be used. 345 * @param dbc the condition that must be matched by all entries that are to be used in the 346 * process of adding up the DataBasket. 347 * @param bev an object helping in determining the value of a single entry. 348 * @param vInit the value that is to be used for adding up. All adding is performed by calling 349 * {@link Value#addAccumulating} on this object. 350 * 351 * @return the sum in <code>vInit</code>. 352 * 353 * @override Always 354 */ 355 public Value sumSubBasket(String sName, DataBasketCondition dbc, BasketEntryValue bev, Value vInit); 356 357 /** 358 * Sum up the values of all items in the current subbasket that match the condition. 359 * 360 * @param dbc the condition that must be matched by all entries that are to be used in the 361 * process of adding up the DataBasket. 362 * @param bev an object helping in determining the value of a single entry. 363 * @param vInit the value that is to be used for adding up. All adding is performed by calling 364 * {@link Value#addAccumulating} on this object. 365 * 366 * @return the sum in <code>vInit</code>. 367 * 368 * @override Always 369 */ 370 public Value sumCurrentSubBasket(DataBasketCondition dbc, BasketEntryValue bev, Value vInit); 371 372 /** 373 * Return true if the DataBasket contains an entry that matches the condition. The entire 374 * DataBasket will be searched. 375 * 376 * @param dbc the condition to be matched. 377 * 378 * @return whether or not the DataBasket currently contains such an entry. 379 * 380 * @override Always 381 */ 382 public boolean contains(DataBasketCondition dbc); 383 384 /** 385 * Get the first entry found that matches the given condition. The entire DataBasket will 386 * be searched. 387 * 388 * <p>In this context, "first" does not mean the first entry added or anything 389 * similar; it simply refers to the first entry found when searching the DataBasket. 390 * Although this may be the first entry added, no assertions are given.</p> 391 * 392 * @param dbc the condition to be matched. 393 * 394 * @return an entry matching the condition, if any. 395 * 396 * @override Always 397 */ 398 public DataBasketEntry get(DataBasketCondition dbc); 399 400 /** 401 * Put an entry into the DataBasket's current subbasket. 402 * 403 * <p>This method is vital for the correct functioning of the DataBasket and, therefore, 404 * must never be called directly. Instead, call appropriate methods in the data containers 405 * ({@link Stock}, {@link Catalog}, etc.) you use. These will in turn call put 406 * on the DataBasket, thus making sure, that the DataBasket contains valid information only 407 * at all times.</p> 408 * 409 * <p>The <code>put</code> method will take the given entry as is and put it into the 410 * current subbasket. This is to say, that the caller is responsible for correctly setting 411 * up the fields in the entry - so that the information stored is meaningful to the client. 412 * In particular, resolving put after remove or remove after put of the same object and 413 * with regard to the same container is the responsibility of the caller.</p> 414 * 415 * @param dbe the entry to be put into the DataBasket. 416 * 417 * @override Always 418 */ 419 public void put(DataBasketEntry dbe); 420 421 /** 422 * Exchange a DataBasketEntry existing in the DataBasket with a new one. 423 * 424 * <p>This method is vital for the correct functioning of the DataBasket and, therefore, 425 * must never be called directly. Instead, call appropriate methods in the data containers 426 * ({@link Stock}, {@link Catalog}, etc.) you use. These will in turn call 427 * exchange on the DataBasket, thus making sure, that the DataBasket contains valid 428 * information only at all times.</p> 429 * 430 * @param dbeOrg the original DataBasketEntry, to be replaced. If the original entry is 431 * not found in the DataBasket, <code>exchange()</code> is equivalent to 432 * {@link #put put (dbeNew)}. 433 * @param dbeNew the replacement. 434 * 435 * @override Always 436 */ 437 public void exchange(DataBasketEntry dbeOrg, DataBasketEntry dbeNew); 438 439 /** 440 * Set the log context for this DataBasket. 441 * 442 * <p>All operations as defined through {@link #setLogMode} will be logged using the given log context. If 443 * the current log context is <code>null</code> no logging of any kind will occur.</p> 444 * 445 * @param lcNew the new log context 446 * 447 * @return the previous log context, if any. 448 * 449 * @override Always 450 */ 451 public LogContext setLogContext(LogContext lcNew); 452 453 /** 454 * Set the log mode for this DataBasket. 455 * 456 * <p>The current log mode decides what operations on the DataBasket are being logged. The default value is 457 * {@link #LOG_MODE_NONE}, indicating that no logging occurs. Other possibilities are:</p> 458 * 459 * <ul> 460 * <li><strong>{@link #LOG_MODE_ALL}</strong> All operations on the DataBasket are being logged.</li> 461 * <li><strong>{@link #LOG_MODE_COMMITS_ONLY}</strong> Only commits are being logged. There will be one 462 * entry for each single step in the commit process.</li> 463 * <li><strong>{@link #LOG_MODE_ROLLBACKS_ONLY}</strong> Only rollbacks are being logged. There will be 464 * one entry for each single step in the rollback process.</li> 465 * </ul> 466 * 467 * <p>For details on the concrete implementation for log entries, please refer to the concrete 468 * implementation of the DataBasket.</p> 469 * 470 * @param nLogMode the new log mode. 471 * 472 * @return the previous log mode. 473 * 474 * @override Always 475 */ 476 public int setLogMode(int nLogMode); 477 478 /** 479 * Return the current log mode of the DataBasket. For information on the possible values and their meaning, 480 * please refer to {@link #setLogMode}. 481 * 482 * @override Always 483 */ 484 public int getLogMode(); 485 486 /** 487 * Log mode constant. 488 * 489 * @see #setLogMode 490 * @see #getLogMode 491 */ 492 public static final int LOG_MODE_NONE = 0; 493 494 /** 495 * Log mode constant. 496 * 497 * @see #setLogMode 498 * @see #getLogMode 499 */ 500 public static final int LOG_MODE_ALL = 1; 501 502 /** 503 * Log mode constant. 504 * 505 * @see #setLogMode 506 * @see #getLogMode 507 */ 508 public static final int LOG_MODE_COMMITS_ONLY = 2; 509 510 /** 511 * Log mode constant. 512 * 513 * @see #setLogMode 514 * @see #getLogMode 515 */ 516 public static final int LOG_MODE_ROLLBACKS_ONLY = 4; 517 }