001 package data.filters;
002
003 import data.*;
004 import data.events.*;
005
006 import java.util.*;
007
008 /**
009 * StockFilter for CountingStocks.
010 *
011 * <p>The filter condition will be defined by overriding method {@link #countItems}.</p>
012 *
013 * @author Steffen Zschaler
014 * @version 2.0 19/08/1999
015 * @since v2.0
016 */
017 public abstract class CountingStockFilter<T extends StockItem, CT extends CatalogItem>
018 extends AbstractStockFilter<T, CT> implements CountingStock<T, CT> {
019
020 /**
021 * Create a new CountingStockFilter.
022 *
023 * @param csSource the source Stock.
024 */
025 public CountingStockFilter(CountingStock<T, CT> csSource) {
026 super(csSource);
027 }
028
029 /**
030 * Return all items with the given key that are contained in the filtered Stock.
031 *
032 * @override Never
033 */
034 public Iterator<T> get(final String sKey, final DataBasket db, final boolean fForEdit) {
035 class I implements Iterator<T> {
036 protected int m_nMaxCount = countItems(sKey, db);
037 protected Iterator<T> m_iIterator = m_stSource.get(sKey, db, fForEdit);
038
039 public boolean hasNext() {
040 return ((m_iIterator.hasNext()) && (m_nMaxCount > 0));
041 }
042
043 public T next() {
044 if (m_nMaxCount <= 0) {
045 throw new NoSuchElementException();
046 }
047
048 m_nMaxCount--;
049
050 return m_iIterator.next();
051 }
052
053 public void remove() {
054 m_iIterator.remove();
055 }
056 }
057
058 return new I();
059 }
060
061 /**
062 * Count the items of the given key in the filtered Stock.
063 *
064 * <p>This method must be overridden, as it represents the filter condition. All other methods that use or
065 * return filtered values will call this method.</p>
066 *
067 * @override Always This method must be overridden, as it represents the filter condition. All other methods
068 * that use or return filtered values will call this method.
069 */
070 public abstract int countItems(String sKey, DataBasket db);
071
072 /**
073 * Check whether the filtered Stock contains the given StockItem.
074 *
075 * @override Never
076 */
077 public boolean contains(T si, DataBasket db) {
078 return contains(si.getName(), db);
079 }
080
081 /**
082 * Check whether the filtered Stock contains the given Stock.
083 *
084 * @override Never
085 */
086 public boolean containsStock(Stock<T, CT> st, DataBasket db) {
087 boolean fResult = m_stSource.containsStock(st, db);
088
089 if (fResult) {
090 for (Iterator<String> i = st.keySet(db).iterator(); i.hasNext(); ) {
091 String sKey = i.next();
092
093 if (countItems(sKey, db) < st.countItems(sKey, db)) {
094 return false;
095 }
096 }
097 }
098
099 return fResult;
100 }
101
102 /**
103 * Add the specified number of items to the source Stock.
104 *
105 * @override Never
106 */
107 public void add(String sKey, int nCount, DataBasket db) {
108 ((CountingStock<T,CT>)m_stSource).add(sKey, nCount, db);
109 }
110
111 /**
112 * Remove at most the specified number of items from the source Stock. If the filtered Stock contains fewer
113 * items than specified only as many items as are contained in the filtered Stock will be removed from the
114 * source Stock.
115 *
116 * @override Never
117 */
118 public void remove(String sKey, int nCount, DataBasket db) throws VetoException {
119 int nFilteredCount = countItems(sKey, db);
120 if (nFilteredCount > nCount) {
121 nFilteredCount = nCount;
122 }
123
124 if (nFilteredCount > 0) {
125 ((CountingStock<T,CT>)m_stSource).remove(sKey, nFilteredCount, db);
126 }
127 }
128 }