001    package data;
002    
003    import java.util.*;
004    
005    /**
006     * StockFromValueCreator that tries to fill a Stock using only items from another Stock.
007     *
008     * @author Steffen Zschaler
009     * @version 2.0 18/08/1999
010     * @since v0.5
011     */
012    public class StockFromStockCreator extends Object implements StockFromValueCreator {
013    
014        /**
015         * The CatalogItemValue used to determine the CatalogItems' values.
016         */
017        protected CatalogItemValue m_civEvaluator;
018    
019        /**
020         * The source Stock.
021         */
022        protected Stock m_stSource;
023    
024        /**
025         * Create a new StockFromStockCreator.
026         *
027         * @param stSource the source Stock.
028         * @param civ the CatalogItemValue used to determine the CatalogItems' values.
029         */
030        public StockFromStockCreator(Stock stSource, CatalogItemValue civ) {
031            super();
032    
033            m_stSource = stSource;
034            m_civEvaluator = civ;
035        }
036    
037        /**
038         * Try to fill the given Stock using only items from the source Stock.
039         *
040         * <p>As this algorithm does not use backtracking, it may not always find a solution even if one would be
041         * possible.</p>
042         *
043         * <p><strong>Attention</strong>: The items that are added to the destination Stock will be removed from the
044         * source Stock.</p>
045         *
046         * @override Never
047         */
048        public Value fillStock(Stock st, Value v, DataBasket db) {
049            Catalog c = st.getCatalog(db);
050    
051            if (c != m_stSource.getCatalog(db)) {
052                throw new CatalogConflictException();
053            }
054    
055            List<CatalogItem> lCI = new LinkedList<CatalogItem>(); // get the catalog's items
056            for (Iterator<CatalogItem> i = c.iterator(db, false); i.hasNext(); ) {
057                lCI.add(i.next());
058            }
059    
060            if (lCI.size() == 0) {
061                return v;
062            }
063    
064            Collections.sort(lCI, DefaultCountingStockFromValueCreator.invertedCIValueOrder(m_civEvaluator)); // Sort the items, greates first
065    
066            // building the Stock
067            for (Iterator<CatalogItem> i = lCI.iterator(); i.hasNext(); ) {
068    
069                CatalogItem ci = i.next();
070                Value vItemValue = m_civEvaluator.getValue(ci);
071    
072                for (Iterator<StockItem> j = m_stSource.get(ci.getName(), db, false); j.hasNext(); ) {
073                    if (vItemValue.compareTo(v) <= 0) {
074                        StockItem si = j.next();
075    
076                        try {
077                            j.remove();
078    
079                            st.add(si, db);
080    
081                            v.subtractAccumulating(vItemValue);
082                        }
083                        catch (UnsupportedOperationException uoe) {}
084                    }
085                }
086            }
087    
088            return v;
089        }
090    }