001 package data; 002 003 import java.util.*; 004 005 import util.SerializableComparator; 006 007 /** 008 * A StockFromValueCreator for {@link CountingStock CountingStocks}. 009 * 010 * <p>This StockFromValueCreator assumes a potentially infinite source of available items and adds exactly 011 * as many items of each type (i.e. corresponding CatalogItem) as needed to fulfil the requirement.</p> 012 * 013 * @author Steffen Zschaler 014 * @version 2.0 18/08/1999 015 * @since v2.0 016 */ 017 public class DefaultCountingStockFromValueCreator extends Object implements StockFromValueCreator { 018 019 /** 020 * The CatalogItemValue used to determine the CatalogItems' values. 021 */ 022 protected CatalogItemValue m_civEvaluator; 023 024 /** 025 * Create a new DefaultCountingStockFromValueCreator. 026 * 027 * @param civ the CatalogItemValue used to determine the CatalogItems' values. 028 */ 029 public DefaultCountingStockFromValueCreator(CatalogItemValue civ) { 030 super(); 031 032 m_civEvaluator = civ; 033 } 034 035 /** 036 * This StockFromValueCreator assumes a potentially infinite source of available items and adds exactly 037 * as many items of each type (i.e. corresponding CatalogItem) as needed to fulfil the requirement. 038 * 039 * @override Never 040 */ 041 public Value fillStock(Stock st, Value v, DataBasket db) { 042 CountingStock cs = (CountingStock)st; 043 Catalog c = st.getCatalog(db); 044 045 List<CatalogItem> lCI = new LinkedList<CatalogItem>(); // Get items from Catalog 046 for (Iterator<CatalogItem> i = c.iterator(db, false); i.hasNext(); ) { 047 lCI.add(i.next()); 048 } 049 050 if (lCI.size() == 0) { 051 return v; 052 } 053 054 Collections.sort(lCI, invertedCIValueOrder(m_civEvaluator)); // Sort the items, greates first 055 056 // building the Stock 057 for (Iterator i = lCI.iterator(); i.hasNext(); ) { 058 CatalogItem ciCurrent = (CatalogItem)i.next(); 059 Value vItemValue = m_civEvaluator.getValue(ciCurrent); 060 Value vCurrent = (Value)vItemValue.clone(); 061 062 int nCount = 1; 063 while (vCurrent.compareTo(v) < 0) { 064 vCurrent.addAccumulating(vItemValue); 065 nCount++; 066 } 067 068 if (vCurrent.compareTo(v) > 0) { 069 nCount--; // correct, if we went too far. 070 vCurrent.subtractAccumulating(vItemValue); 071 } 072 073 if (nCount > 0) { 074 cs.add(ciCurrent.getName(), nCount, db); 075 v.subtractAccumulating(vCurrent); 076 } 077 } 078 079 return v; 080 } 081 082 /** 083 * Helper method that creates a Comparator that orders CatalogItems, highest value first. 084 */ 085 public static final Comparator<CatalogItem> invertedCIValueOrder(final CatalogItemValue civ) { 086 return new SerializableComparator<CatalogItem>() { 087 /** 088 * ID for serialization. 089 */ 090 private static final long serialVersionUID = -6668458235599836268L; 091 092 public int compare(CatalogItem ci1, CatalogItem ci2) { 093 return civ.getValue(ci2).compareTo(civ.getValue(ci1)); 094 } 095 }; 096 } 097 }