package org.marketcetera.event.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.annotation.concurrent.ThreadSafe;
import org.marketcetera.event.AskEvent;
import org.marketcetera.event.BidEvent;
import org.marketcetera.event.QuoteEvent;
import org.marketcetera.event.TopOfBookEvent;
import org.marketcetera.event.beans.EventBean;
import org.marketcetera.event.beans.HasEventBean;
import org.marketcetera.event.util.EventServices;
import org.marketcetera.marketdata.DateUtils;
import org.marketcetera.trade.Instrument;
import org.marketcetera.util.log.I18NBoundMessage2P;
import org.marketcetera.util.misc.ClassVersion;
/* $License$ */
/**
* Provides a {@link TopOfBookEvent} implementation.
*
* @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a>
* @version $Id: TopOfBookEventImpl.java 16854 2014-03-12 01:54:42Z colin $
* @since 2.0.0
*/
@ThreadSafe
@ClassVersion("$Id: TopOfBookEventImpl.java 16854 2014-03-12 01:54:42Z colin $")
public class TopOfBookEventImpl
implements TopOfBookEvent, HasEventBean
{
/* (non-Javadoc)
* @see org.marketcetera.event.HasInstrument#getInstrument()
*/
@Override
public Instrument getInstrument()
{
return instrument;
}
/* (non-Javadoc)
* @see org.marketcetera.event.HasInstrument#getInstrumentAsString()
*/
@Override
public String getInstrumentAsString()
{
return instrument.getSymbol();
}
/* (non-Javadoc)
* @see org.marketcetera.event.beans.HasEventBean#getEventBean()
*/
@Override
public EventBean getEventBean()
{
return event;
}
/* (non-Javadoc)
* @see org.marketcetera.event.TopOfBook#getAsk()
*/
@Override
public AskEvent getAsk()
{
return ask;
}
/* (non-Javadoc)
* @see org.marketcetera.event.TopOfBook#getBid()
*/
@Override
public BidEvent getBid()
{
return bid;
}
/* (non-Javadoc)
* @see org.marketcetera.event.AggregateEvent#decompose()
*/
@Override
public List<QuoteEvent> decompose()
{
List<QuoteEvent> output = new ArrayList<QuoteEvent>();
if(bid != null) {
output.add(bid);
}
if(ask != null) {
output.add(ask);
}
return Collections.unmodifiableList(output);
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#getMessageId()
*/
@Override
public long getMessageId()
{
return event.getMessageId();
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#getSource()
*/
@Override
public Object getSource()
{
return event.getSource();
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#getTimestamp()
*/
@Override
public Date getTimestamp()
{
return event.getTimestamp();
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#setSource(java.lang.Object)
*/
@Override
public void setSource(Object inSource)
{
event.setSource(inSource);
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#getProvider()
*/
@Override
public String getProvider()
{
return event.getProvider();
}
/* (non-Javadoc)
* @see org.marketcetera.event.Event#setProvider(java.lang.String)
*/
@Override
public void setProvider(String inProvider)
{
event.setProvider(inProvider);
}
/* (non-Javadoc)
* @see org.marketcetera.event.TimestampCarrier#getTimeMillis()
*/
@Override
public long getTimeMillis()
{
return event.getTimeMillis();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public final int hashCode()
{
return EventServices.eventHashCode(this);
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public final boolean equals(Object obj)
{
return EventServices.eventEquals(this,
obj);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
return String.format("TopOfBook for %s at %s: %s %s-%s %sx%s %s", //$NON-NLS-1$
getInstrument(),
DateUtils.dateToString(getTimestamp()),
getExchange(bid),
getPriceAsString(bid),
getPriceAsString(ask),
getSizeAsString(bid),
getSizeAsString(ask),
getExchange(ask));
}
/**
* Create a new TopOfBookImpl instance.
*
* @param inEvent an <code>EventBean</code> value
* @param inInstrument an <code>Instrument</code> value
* @param inBid a <code>BidEvent</code> value or <code>null</code>
* @param inAsk an <code>AskEvent</code> value or <code>null</code>
* @throws IllegalArgumentException if <code>MessageId</code> < 0
* @throws IllegalArgumentException if <code>Timestamp</code> is <code>null</code>
* @throws IllegalArgumentException if <code>Instrument</code> is <code>null</code>
* @throws IllegalArgumentException if an entry in the list is for a different instrument than the one given
*/
TopOfBookEventImpl(EventBean inEvent,
Instrument inInstrument,
BidEvent inBid,
AskEvent inAsk)
{
event = EventBean.copy(inEvent);
event.setDefaults();
event.validate();
if(inInstrument == null) {
EventServices.error(VALIDATION_NULL_INSTRUMENT);
}
instrument = inInstrument;
bid = inBid;
ask = inAsk;
if(bid != null &&
!bid.getInstrument().equals(instrument)) {
EventServices.error(new I18NBoundMessage2P(VALIDATION_BID_INCORRECT_INSTRUMENT,
bid.getInstrument(),
instrument));
}
if(ask != null &&
!ask.getInstrument().equals(instrument)) {
EventServices.error(new I18NBoundMessage2P(VALIDATION_ASK_INCORRECT_INSTRUMENT,
ask.getInstrument(),
instrument));
}
}
/**
* Returns the exchange of the given event or null.
*
* @param inEvent a <code>QuoteEvent</code> value
* @return a <code>String</code> value
*/
private static String getExchange(QuoteEvent inEvent)
{
if(inEvent != null) {
return inEvent.getExchange();
}
return null;
}
/**
* Returns the price of the given event as a <code>String</code>.
*
* @param inEvent a <code>QuoteEvent</code> value
* @return a <code>String</code> value
*/
private static String getPriceAsString(QuoteEvent inEvent)
{
if(inEvent != null) {
return inEvent.getPrice().toPlainString();
}
return NO_QUANTITY;
}
/**
* Returns the size of the given event as a <code>String</code>.
*
* @param inEvent a <code>QuoteEvent</code> value
* @return a <code>String</code> value
*/
private static String getSizeAsString(QuoteEvent inEvent)
{
if(inEvent != null) {
return inEvent.getSize().toPlainString();
}
return NO_QUANTITY;
}
/**
* the event attributes
*/
private final EventBean event;
/**
* the event instrument
*/
private final Instrument instrument;
/**
* the top bid or <code>null</code>
*/
private final BidEvent bid;
/**
* the top ask or <code>null</code>
*/
private final AskEvent ask;
/**
* value to display if the source is null
*/
private static String NO_QUANTITY = "---"; //$NON-NLS-1$
private static final long serialVersionUID = 1L;
}