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    }