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 }