text: package com.thomsonreuters.upa.shared.provider;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import com.thomsonreuters.upa.codec.CodecFactory;
  import com.thomsonreuters.upa.codec.CodecReturnCodes;
  import com.thomsonreuters.upa.codec.DataDictionary;
  import com.thomsonreuters.upa.codec.DataStates;
  import com.thomsonreuters.upa.codec.EncodeIterator;
  import com.thomsonreuters.upa.codec.Enum;
  import com.thomsonreuters.upa.codec.QosRates;
  import com.thomsonreuters.upa.codec.QosTimeliness;
  import com.thomsonreuters.upa.codec.StateCodes;
  import com.thomsonreuters.upa.codec.StreamStates;
  import com.thomsonreuters.upa.shared.rdm.marketbyprice.MarketByPriceItem;
  import com.thomsonreuters.upa.shared.rdm.marketbyprice.MarketByPriceRefresh;
  import com.thomsonreuters.upa.shared.rdm.marketbyprice.MarketByPriceUpdate;
  import com.thomsonreuters.upa.transport.Channel;
  import com.thomsonreuters.upa.transport.Error;
  import com.thomsonreuters.upa.transport.TransportBuffer;
  
  /**
   * This handles storage of all market by price items.
   * 
   * <p>
   * Provides methods generation of market by price data, for managing the list, and a method for encoding a
   * market by price message and payload.
   */
  public class MarketByPriceItems
  {
      private static final int MAX_MARKET_PRICE_ITEM_LIST_SIZE = 100;
  
      // item information list
      private List<MarketByPriceItem> _marketByPriceList;
  
      private static Enum USD_ENUM;
      private static Enum BBO_ENUM;
      
      protected static final int MAX_ORDERS = 3; //Number of order in a single message
      
      protected MarketByPriceRefresh _marketByPriceRefresh;
      protected MarketByPriceUpdate _marketByPriceUpdate;
  
      protected EncodeIterator _encodeIter = CodecFactory.createEncodeIterator();
      
      static
      {
          USD_ENUM = CodecFactory.createEnum();
          USD_ENUM.value(840);
          BBO_ENUM = CodecFactory.createEnum();
          BBO_ENUM.value(20);
      }
  
  
      /**
       * Instantiates a new market by price items.
       */
      public MarketByPriceItems()
      {
          _marketByPriceList = new ArrayList<MarketByPriceItem>(MAX_MARKET_PRICE_ITEM_LIST_SIZE);
          for (int i = 0; i < MAX_MARKET_PRICE_ITEM_LIST_SIZE; i++)
          {
              _marketByPriceList.add(new MarketByPriceItem());
          }
  
          _marketByPriceUpdate = new MarketByPriceUpdate();
          _marketByPriceRefresh = new MarketByPriceRefresh();
      }
  
      /**
       * Initializes market price item list.
       */
      public void init()
      {
          // clear item information list 
          for (MarketByPriceItem mbpItem : _marketByPriceList)
          {
              mbpItem.clear();
          }
      }
  
      /**
       * Updates any item that's currently in use.
       */
      void update()
      {
          for (MarketByPriceItem mbpItem : _marketByPriceList)
          {
              if(mbpItem.isInUse)
                  mbpItem.updateFields();
          }
      }
  
      /**
       * Gets storage for a market by price item from the list.
       *
       * @param itemName the item name
       * @return the market by price item
       */
      public MarketByPriceItem get(String itemName)
      {
          // first try to find one with same name and reuse
          for (MarketByPriceItem mbpItem : _marketByPriceList)
          {
              if (mbpItem.isInUse && mbpItem.itemName != null && mbpItem.itemName.equals(itemName))
              {
                  return mbpItem;
              }
          }
          
          // next get a new one
          for (MarketByPriceItem mbpItem : _marketByPriceList)
          {
              if (!mbpItem.isInUse)
              {
                  mbpItem.initFields();
                  mbpItem.itemName = itemName;
                  return mbpItem;
              }
          }
  
          return null;
      }
  
      /**
       * Clears the item information.
       */
      public void clear()
      {
          for (MarketByPriceItem mbpItem : _marketByPriceList)
          {
              mbpItem.clear();
          }
      }
  
      /**
       * Encodes the market by price refresh. Returns success if encoding succeeds
       * or failure if encoding fails.
       *
       * @param channel - The channel to send a market by price refresh to
       * @param itemInfo - The item information
       * @param msgBuf - The message buffer to encode the market by price refresh
       *            into
       * @param isSolicited - The refresh is solicited if set
       * @param streamId - The stream id of the market by price refresh
       * @param isStreaming - Flag for streaming or snapshot
       * @param isPrivateStream the is private stream
       * @param serviceId - The service id of the market by price refresh
       * @param dictionary - The dictionary used for encoding
       * @param multiPartNo the multi part no
       * @param error the error
       * @return {@link CodecReturnCodes}
       */
      public int encodeRefresh(Channel channel, ItemInfo itemInfo, TransportBuffer msgBuf, boolean isSolicited, int streamId, boolean isStreaming, boolean isPrivateStream, int serviceId, DataDictionary dictionary, int multiPartNo, Error error)
      {
          _marketByPriceRefresh.clear();
          _marketByPriceRefresh.dictionary(dictionary);
          _marketByPriceRefresh.itemName().data(itemInfo.itemName.data(), itemInfo.itemName.position(), itemInfo.itemName.length());
          _marketByPriceRefresh.streamId(streamId);
          _marketByPriceRefresh.applyHasServiceId();
          _marketByPriceRefresh.serviceId(serviceId);
          if (isSolicited)
          {
              _marketByPriceRefresh.applySolicited();
              
              // set clear cache on first part of all solicted refreshes.
              if(multiPartNo == 0)
              {
                  _marketByPriceRefresh.applyClearCache();
              }
          }
  
          if (isPrivateStream)
              _marketByPriceRefresh.applyPrivateStream();
  
          
          _marketByPriceRefresh.dictionary(dictionary);
          
          // QoS 
          _marketByPriceRefresh.qos().dynamic(false);
          _marketByPriceRefresh.qos().timeliness(QosTimeliness.REALTIME);
          _marketByPriceRefresh.qos().rate(QosRates.TICK_BY_TICK);
          _marketByPriceRefresh.applyHasQos();
  
          // State 
          _marketByPriceRefresh.state().streamState(isStreaming ? StreamStates.OPEN : StreamStates.NON_STREAMING);
          _marketByPriceRefresh.state().dataState(DataStates.OK);
          _marketByPriceRefresh.state().code(StateCodes.NONE);
          
          // multi-part refresh complete when multiPartNo hits max
          if (multiPartNo == MAX_ORDERS - 1)
          {
              _marketByPriceRefresh.applyRefreshComplete();
              _marketByPriceRefresh.state().text().data("Item Refresh Completed");
          }
          else
          {
              _marketByPriceRefresh.state().text().data("Item Refresh In Progress");
          }
          _marketByPriceRefresh.partNo(multiPartNo);
          _marketByPriceRefresh.marketByPriceItem((MarketByPriceItem)itemInfo.itemData);
          _encodeIter.clear();
          int ret = _encodeIter.setBufferAndRWFVersion(msgBuf, channel.majorVersion(), channel.minorVersion());
          if (ret != CodecReturnCodes.SUCCESS)
          {
              error.text("EncodeIterator.setBufferAndRWFVersion() failed with return code: " + CodecReturnCodes.toString(ret));
              return ret;
          }
          ret = _marketByPriceRefresh.encode(_encodeIter);
          if (ret != CodecReturnCodes.SUCCESS)
              error.text("MarketByPriceRefresh.encode() failed");
          
          return ret;
      }
  
      /**
       * Encodes the market by price update. Returns success if encoding succeeds
       * or failure if encoding fails.
       *
       * @param channel - The channel to send a market by price update to
       * @param itemInfo - The item information
       * @param msgBuf - The message buffer to encode the market by price update
       *            into
       * @param isSolicited - The update is solicited if set
       * @param streamId - The stream id of the market by price update
       * @param isStreamingRequest - Flag for streaming or snapshot
       * @param isPrivateStreamRequest - Flag for private stream request
       * @param serviceId - The service id of the market by price update
       * @param dictionary - The dictionary used for encoding
       * @param error - error in case of encoding failure
       * @return the int
       */
      public int encodeUpdate(Channel channel, ItemInfo itemInfo, TransportBuffer msgBuf, boolean isSolicited, int streamId, boolean isStreamingRequest, boolean isPrivateStreamRequest, int serviceId, DataDictionary dictionary, Error error)
      {
          _marketByPriceUpdate.clear();
          _marketByPriceUpdate.applyRefreshComplete();
          if(isPrivateStreamRequest)
              _marketByPriceUpdate.applyPrivateStream();
          
          _marketByPriceUpdate.dictionary(dictionary);
          _marketByPriceUpdate.itemName().data(itemInfo.itemName.data(), itemInfo.itemName.position(), itemInfo.itemName.length());
          _marketByPriceUpdate.streamId(streamId);
          _marketByPriceUpdate.dictionary(dictionary);
          _marketByPriceUpdate.marketByPriceItem((MarketByPriceItem)itemInfo.itemData);
          _encodeIter.clear();
          int ret = _encodeIter.setBufferAndRWFVersion(msgBuf, channel.majorVersion(), channel.minorVersion());
          if (ret != CodecReturnCodes.SUCCESS)
          {
              error.text("EncodeIterator.setBufferAndRWFVersion() failed with return code: " + CodecReturnCodes.toString(ret));
              return ret;
          }
          ret = _marketByPriceUpdate.encode(_encodeIter);
          if (ret != CodecReturnCodes.SUCCESS)
              error.text("MarketByPriceUpdate.encode() failed");
  
          return ret;
      }
  }