001    package data.filters;
002    
003    import data.*;
004    import data.events.*;
005    
006    import java.util.*;
007    
008    /**
009     * StockFilter for StoringStocks.
010     *
011     * <p>The filter condition can be defined by overriding method
012     * {@link #contains(data.StockItem, data.DataBasket)}.</p>
013     *
014     * @author Steffen Zschaler
015     * @version 2.0 19/08/1999
016     * @since v2.0
017     */
018    public abstract class StoringStockFilter extends AbstractStockFilter implements StoringStock {
019    
020        /**
021         * Create a new StoringStockFilter.
022         *
023         * @param ssSource the source Stock.
024         */
025        public StoringStockFilter(StoringStock ssSource) {
026            super(ssSource);
027        }
028    
029        /**
030         * Get all StockItems for a given key that are contained in the filtered Stock.
031         *
032         * @override Never
033         */
034        public Iterator get(final String sKey, final DataBasket db, final boolean fForEdit) {
035            class I implements Iterator {
036                protected Iterator m_iIterator = m_stSource.get(sKey, db, fForEdit);
037                protected Object m_oCurrent;
038                protected Object m_oNext;
039    
040                public boolean hasNext() {
041                    return findNext(false);
042                }
043    
044                public Object next() {
045                    if (!findNext(true)) {
046                        throw new NoSuchElementException();
047                    }
048    
049                    return m_oCurrent;
050                }
051    
052                public void remove() {
053                    if (m_oCurrent == null) {
054                        throw new IllegalStateException();
055                    }
056    
057                    try {
058                        StoringStockFilter.this.remove((StockItem)m_oCurrent, db);
059                    }
060                    catch (VetoException ve) {
061                        throw new UnsupportedOperationException();
062                    }
063                }
064    
065                private boolean findNext(boolean fGet) {
066                    if (m_oNext != null) {
067                        if (fGet) {
068                            m_oCurrent = m_oNext;
069                            m_oNext = null;
070                        }
071    
072                        return true;
073                    }
074    
075                    while (m_iIterator.hasNext()) {
076                        StockItem si = (StockItem)m_iIterator.next();
077    
078                        if (contains(si, db)) {
079                            if (fGet) {
080                                m_oCurrent = si;
081                                m_oNext = null;
082                            } else {
083                                m_oNext = si;
084                            }
085    
086                            return true;
087                        }
088                    }
089    
090                    return false;
091                }
092            }
093    
094            return new I();
095        }
096    
097        /**
098         * Count all StockItems for a given key that are contained in the filtered Stock.
099         *
100         * @override Never
101         */
102        public int countItems(String sKey, DataBasket db) {
103            int nCount = 0;
104    
105            for (Iterator i = get(sKey, db, false); i.hasNext(); ) {
106                nCount++;
107                i.next();
108            }
109    
110            return nCount;
111        }
112    
113        /**
114         * Filter condition: Check whether a given item is contained in the filtered Stock.
115         *
116         * @override Always
117         *
118         * @param si the StockItem to be checked.
119         * @param db the DataBasket to be used to check visibility.
120         *
121         * @return true if the given item is to be contained in the filtered Stock.
122         */
123        public abstract boolean contains(StockItem si, DataBasket db);
124    
125        /**
126         * Check whether the given Stock is contained in the filtered Stock.
127         *
128         * @override Never
129         */
130        public boolean containsStock(Stock st, DataBasket db) {
131            boolean fResult = m_stSource.containsStock(st, db);
132    
133            if (fResult) {
134                for (Iterator i = st.iterator(db, false); i.hasNext(); ) {
135                    if (!contains((StockItem)i.next(), db)) {
136                        return false;
137                    }
138                }
139            }
140    
141            return fResult;
142        }
143    }