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    }