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