001    package market;
002    
003    import java.util.Iterator;
004    
005    import data.Catalog;
006    import data.CatalogItem;
007    import data.DataBasket;
008    import data.events.VetoException;
009    import data.ooimpl.CatalogImpl;
010    import data.ooimpl.CountingStockImpl;
011    
012    /**
013     * CountingStockImpl that always contains the same keys as its {@linkplain CArticleCatalog} source catalog,
014     * even if no StockItems have been added or some have been removed completely.
015     * Normally the keys of StockItems are removed when their number drops to zero. But this prevents
016     * StockItems with an amount of zero to be displayed in tables.
017     */
018    public class CSOffer extends CountingStockImpl {
019    
020        /**
021             * ID for serialization.
022             */
023            private static final long serialVersionUID = 8808619196908687323L;
024            
025            private Integer iNull = new Integer(0);
026    
027        /**
028         * @param sName the Stock's name.
029         * @param cat the source catalog.
030         */
031        public CSOffer(String sName, CatalogImpl cat) {
032            super(sName, cat);
033            addZeros(null);
034        }
035    
036        /**
037         * Removes StockItems from the Stock. If the item has been removed completely, its
038         * index is re-added and its amount is set to 0.
039         *
040         * @param sKey the ID of the StockItem to be removed.
041         * @param nCount the number of Items to be removed.
042         * @param db the belonging DataBasket.
043         */
044        public void remove(String sKey, int nCount, DataBasket db){
045            try {
046                super.remove(sKey, nCount, db);
047            }
048            catch (VetoException ve) {
049                System.err.println(ve.getMessage());
050            }
051            if (!contains(sKey, db)) {
052                getItemsContainer().put(sKey, iNull);
053            }
054        }
055    
056        /**
057         * Checks, which CatalogItems have no appropriate StockItems.
058         * If one is found the key of the item is added to the stock.
059         * The number of StockItems is set to 0.
060         *
061         * @param db the DataBasket to be used.
062         */
063        public void addZeros(DataBasket db) {
064            Iterator it = m_ciCatalog.iterator(null, false);
065            while (it.hasNext()) {
066                String sKey = ((CatalogItem)it.next()).getName();
067                if (!contains(sKey, db)) {
068                    getItemsContainer().put(sKey, iNull);
069                }
070            }
071        }
072    
073    
074        /**
075         * Changes the StockItems of this stock according to a new Catalog<br><br>
076         * All elements that appear in both the old and the new Catalog will be kept.<br>
077         * All elements that do not appear in the new Catalog will be deleted.<br>
078         * All elements that have not appeared in the old Catalog will be added
079         * and their number is set to 0.<br>
080         * This method is used by the filters that filter Stocks by their item's category.
081         *
082         * @param cat the new Catalog to be set.
083         */
084        public void changeArticleCatalog(Catalog cat) throws VetoException {
085            Iterator it = null;
086            //convert the given catalog to a CatalogImpl and make it the new base
087            Catalog oldBase = m_ciCatalog;
088            if (cat instanceof CatalogImpl) {   //Catalog instance of CatalogImpl => leave it
089                m_ciCatalog = (CatalogImpl)cat;
090            } else {                            //Catalog not instance of CatalogImpl (e.g. Filter)
091                CatalogImpl c = new CatalogImpl(m_ciCatalog.getName());
092                it = cat.keySet(null).iterator();
093                while (it.hasNext()) {                      //copy all CatalogItems from cat to new
094                    String nextKey = (String)it.next();     //created CatalogImpl
095                    CatalogItem ci = oldBase.get(nextKey, null, false);
096                    c.add(ci, null);
097                }
098                m_ciCatalog = c;                            //make new CatalogImpl the new base
099            }
100            //iterate through new base and remove all unneeded StockItems from this stock
101            it = this.keySet(null).iterator();
102            int nrOfItems = 0;
103            while (it.hasNext()) {
104                String sKey = (String)it.next();
105                nrOfItems = countItems(sKey, null);
106                if (!contains(sKey, null)) {
107                    if (nrOfItems > 0) {
108                        try {
109                            super.remove(sKey, nrOfItems, null);
110                        }
111                        catch (VetoException ve) {
112                            ve.printStackTrace();
113                            throw ve;
114                        }
115                    } else {
116                        getItemsContainer().remove(sKey);
117                    }
118                }
119                addZeros(null);
120            }
121        }
122    
123        /**
124         * @return a clone of CSOffer with its StockItems.
125         */
126        public Object clone() {
127            CSOffer cso = new CSOffer(getName(), m_ciCatalog);
128            Iterator it = this.keySet(null).iterator();
129            while (it.hasNext()) {
130                String sKey = (String)it.next();
131                int amount = countItems(sKey, null);
132                if (amount > 0) {                       //add all items with one or more elements
133                    cso.add(sKey, amount, null);        //(adding 0 elements is not allowed by the Framework)
134                }
135                addZeros(null);
136            }
137            return cso;
138        }
139    }