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 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 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 }