package org.marketcetera.marketdata;
import static org.marketcetera.core.Util.ESCAPED_KEY_VALUE_DELIMITER;
import static org.marketcetera.core.Util.ESCAPED_KEY_VALUE_SEPARATOR;
import static org.marketcetera.core.Util.KEY_VALUE_DELIMITER;
import static org.marketcetera.core.Util.KEY_VALUE_SEPARATOR;
import static org.marketcetera.marketdata.MarketDataRequestBuilder.*;
import java.io.Serializable;
import java.util.*;
import javax.annotation.concurrent.ThreadSafe;
import javax.xml.bind.annotation.*;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.marketcetera.util.misc.ClassVersion;
/* $License$ */
/**
* Contains the data necessary to compose a {@link MarketDataRequest}.
*
* @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a>
* @version $Id: MarketDataRequestBean.java 16854 2014-03-12 01:54:42Z colin $
* @since 2.1.0
*/
@ThreadSafe
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name="marketDataRequestBean")
@ClassVersion("$Id: MarketDataRequestBean.java 16854 2014-03-12 01:54:42Z colin $")
public final class MarketDataRequestBean
implements Serializable, Cloneable
{
/**
* Get the provider value.
*
* @return a <code>String</code> value
*/
public String getProvider()
{
return provider;
}
/**
* Sets the provider value.
*
* @param inProvider a <code>String</code> value
*/
public void setProvider(String inProvider)
{
provider = inProvider;
}
/**
* Get the exchange value.
*
* @return a <code>String</code> value
*/
public String getExchange()
{
return exchange;
}
/**
* Sets the exchange value.
*
* @param inExchange a <code>String</code> value
*/
public void setExchange(String inExchange)
{
exchange = inExchange;
}
/**
* Get the assetClass value.
*
* @return an <code>AssetClass</code> value
*/
public AssetClass getAssetClass()
{
return assetClass;
}
/**
* Sets the assetClass value.
*
* @param inAssetClass a <code>AssetClass</code> value
*/
public void setAssetClass(AssetClass inAssetClass)
{
assetClass = inAssetClass;
}
/**
* Get the symbols value.
*
* @return a <code>Set<String></code> value
*/
public Set<String> getSymbols()
{
synchronized(symbols) {
return Collections.unmodifiableSet(symbols);
}
}
/**
* Sets the symbols value.
*
* <p>The given values replace the existing values. Duplicate values
* are discarded. The values will be retained in their given order.
* Null and empty values are allowed.
*
* @param inSymbols a <code>Collection<String></code> value
*/
public void setSymbols(Collection<String> inSymbols)
{
synchronized(symbols) {
symbols.clear();
symbols.addAll(inSymbols);
}
}
/**
* Get the underlyingSymbols value.
*
* @return a <code>Set<String></code> value
*/
public Set<String> getUnderlyingSymbols()
{
synchronized(underlyingSymbols) {
return Collections.unmodifiableSet(underlyingSymbols);
}
}
/**
* Sets the underlying symbols value.
*
* <p>The given values replace the existing values. Duplicate values
* are discarded. The values will be retained in their given order.
* Null and empty values are allowed.
*
* @param inUnderlyingSymbols a <code>Collection<String></code> value
*/
public void setUnderlyingSymbols(Collection<String> inUnderlyingSymbols)
{
synchronized(underlyingSymbols) {
underlyingSymbols.clear();
underlyingSymbols.addAll(inUnderlyingSymbols);
}
}
/**
* Sets the parameter specified by the given key to the given value.
*
* @param inKey a <code>String</code> value or <code>null</code>
* @param inValue a <code>String</code> value or <code>null</code>
*/
public void setParameter(String inKey,
String inValue)
{
synchronized(parameters) {
parameters.put(inKey,
inValue);
}
}
/**
* Sets the parameters value.
*
* <p>The given values replace the existing values. Duplicate values
* are discarded. The values will be retained in their given order.
*
* @param inParameters a <code>Map<String,String></code> value
*/
public void setParameters(Map<String,String> inParameters)
{
synchronized(parameters) {
parameters.clear();
parameters.putAll(inParameters);
}
}
/**
* Get the parameters value.
*
* @return a <code>Map<String,String></code> value
*/
public Map<String,String> getParameters()
{
synchronized(parameters) {
return Collections.unmodifiableMap(parameters);
}
}
/**
* Get the content value.
*
* @return a <code>Set<Content></code> value
*/
public Set<Content> getContent()
{
synchronized(content) {
return Collections.unmodifiableSet(content);
}
}
/**
* Sets the contents value.
*
* <p>The given values replace the existing values. Duplicate values
* are discarded. The values will be retained in their given order.
* Null values are allowed.
*
* @param inContent a <code>Collection<Content></code> value
*/
public void setContent(Collection<Content> inContent)
{
synchronized(content) {
content.clear();
content.addAll(inContent);
}
}
/* (non-Javadoc)
* @see java.lang.Object#clone()
*/
@Override
public MarketDataRequestBean clone()
throws CloneNotSupportedException
{
// intentionally not calling super.clone in order to establish different collections
MarketDataRequestBean newBean = new MarketDataRequestBean();
// simple attributes
newBean.setAssetClass(assetClass);
newBean.setExchange(exchange);
newBean.setProvider(provider);
newBean.setContent(content);
newBean.setParameters(parameters);
newBean.setSymbols(symbols);
newBean.setUnderlyingSymbols(underlyingSymbols);
return newBean;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return new HashCodeBuilder(17,
53).append(assetClass)
.append(exchange)
.append(provider)
.append(content)
.append(parameters)
.append(symbols)
.append(underlyingSymbols).toHashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if(obj == null) {
return false;
}
if(obj == this) {
return true;
}
if(!(obj instanceof MarketDataRequestBean)) {
return false;
}
MarketDataRequestBean rhs = (MarketDataRequestBean)obj;
return new EqualsBuilder().append(assetClass,
rhs.assetClass)
.append(exchange,
rhs.exchange)
.append(provider,
rhs.provider)
.append(content,
rhs.content)
.append(parameters,
rhs.parameters)
.append(symbols,
rhs.symbols)
.append(underlyingSymbols,
rhs.underlyingSymbols).isEquals();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{
StringBuilder output = new StringBuilder();
boolean delimiterNeeded = false;
Set<String> symbols = getSymbols();
if(symbols != null &&
!symbols.isEmpty()) {
boolean symbolListDelimiterNeeded = false;
output.append(SYMBOLS_KEY).append(KEY_VALUE_SEPARATOR);
for(String symbol : symbols) {
if(symbolListDelimiterNeeded) {
output.append(SYMBOL_DELIMITER);
}
output.append(symbol.trim());
symbolListDelimiterNeeded = true;
}
delimiterNeeded = true;
}
Set<String> underlyingSymbols = getUnderlyingSymbols();
if(underlyingSymbols != null &&
!underlyingSymbols.isEmpty()) {
boolean symbolListDelimiterNeeded = false;
output.append(UNDERLYINGSYMBOLS_KEY).append(KEY_VALUE_SEPARATOR);
for(String underlyingSymbol : underlyingSymbols) {
if(symbolListDelimiterNeeded) {
output.append(SYMBOL_DELIMITER);
}
output.append(underlyingSymbol.trim());
symbolListDelimiterNeeded = true;
}
delimiterNeeded = true;
}
String provider = getProvider();
if(provider != null) {
if(delimiterNeeded) {
output.append(KEY_VALUE_DELIMITER);
}
output.append(PROVIDER_KEY).append(KEY_VALUE_SEPARATOR).append(String.valueOf(provider));
delimiterNeeded = true;
}
Set<Content> content = getContent();
if(!content.isEmpty()) {
if(delimiterNeeded) {
output.append(KEY_VALUE_DELIMITER);
}
output.append(CONTENT_KEY).append(KEY_VALUE_SEPARATOR).append(content.toString().replaceAll("[\\[\\] ]", //$NON-NLS-1$
"")); //$NON-NLS-1$
delimiterNeeded = true;
}
String exchange = getExchange();
if(exchange != null) {
if(delimiterNeeded) {
output.append(KEY_VALUE_DELIMITER);
}
output.append(EXCHANGE_KEY).append(KEY_VALUE_SEPARATOR).append(String.valueOf(exchange));
delimiterNeeded = true;
}
AssetClass assetClass = getAssetClass();
if(assetClass != null) {
if(delimiterNeeded) {
output.append(KEY_VALUE_DELIMITER);
}
output.append(ASSETCLASS_KEY).append(KEY_VALUE_SEPARATOR).append(String.valueOf(assetClass));
delimiterNeeded = true;
}
Map<String,String> parameters = getParameters();
if(!parameters.isEmpty()) {
if(delimiterNeeded) {
output.append(KEY_VALUE_DELIMITER);
}
output.append(PARAMETERS_KEY).append(KEY_VALUE_SEPARATOR);
boolean parameterDelimiterNeeded = false;
for(Map.Entry<String,String> entry : parameters.entrySet()) {
if(parameterDelimiterNeeded) {
output.append(ESCAPED_KEY_VALUE_DELIMITER);
}
output.append(entry.getKey()).append(ESCAPED_KEY_VALUE_SEPARATOR).append(entry.getValue());
parameterDelimiterNeeded = true;
}
delimiterNeeded = true;
}
return output.toString();
}
/**
* the symbols for which to request data
*/
@XmlElementWrapper(name="symbolList")
private final Set<String> symbols = new LinkedHashSet<String>();
/**
* the underlying symbols for which to request data
*/
@XmlElementWrapper(name="underlyingSymbolList")
private final Set<String> underlyingSymbols = new LinkedHashSet<String>();
/**
* the map of custom request parameters
*/
@XmlElementWrapper(name="parameterist")
private final Map<String,String> parameters = new HashMap<String, String>();
/**
* the request content
*/
@XmlElementWrapper(name="contentList")
private final Set<Content> content = new LinkedHashSet<Content>();
/**
* the provider key from which to request data
*/
@XmlAttribute
private volatile String provider;
/**
* the exchange from which to request data
*/
@XmlAttribute
private volatile String exchange;
/**
* the asset class
*/
@XmlAttribute
private volatile AssetClass assetClass;
private static final long serialVersionUID = 1L;
}