/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.analytics;
import java.util.List;
import com.opengamma.core.security.Security;
import com.opengamma.engine.target.ComputationTargetReference;
import com.opengamma.engine.target.ComputationTargetType;
import com.opengamma.financial.security.FinancialSecurity;
import com.opengamma.id.UniqueId;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.web.analytics.formatting.TypeFormatter;
/**
* Renders cells in the portfolio grid label column.
*/
/* package */ class PortfolioLabelRenderer implements GridColumn.CellRenderer {
/** The rows in the grid. */
private final List<PortfolioGridRow> _rows;
// TODO it would be better to pass in an interface so the renderers don't have to be rebuilt when the rows change
/* package */ PortfolioLabelRenderer(List<PortfolioGridRow> rows) {
ArgumentChecker.notNull(rows, "rows");
_rows = rows;
}
@Override
public ResultsCell getResults(int rowIndex,
TypeFormatter.Format format,
ResultsCache cache,
Class<?> columnType,
Object inlineKey) {
PortfolioGridRow row = _rows.get(rowIndex);
ComputationTargetReference target = row.getTarget();
ComputationTargetType targetType = target.getType();
// TODO do I need to use the target type to figure out the row type? can I just have different row types?
if (targetType.isTargetType(ComputationTargetType.POSITION)) {
RowTarget rowTarget;
UniqueId securityId = row.getSecurityId();
ResultsCache.Result securityResult = cache.getEntity(securityId.getObjectId());
Security security = (Security) securityResult.getValue();
if (isOtc(security)) {
// TODO different type for OTC positions with no trades? they are effecively the same but the client
// needs to know when a position has no trades because it will be a different endpoint to trigger editing
// OTC trades and positions are shown as a single row as there's always one trade per position
rowTarget = new OtcTradeTarget(row.getName(), row.getNodeId(), row.getPositionId(), row.getTradeId());
} else {
// Positions in fungible trades can contain multiple trades so the position has its own row and child rows
// for each of its trades
rowTarget = new PositionTarget(row.getName(), row.getNodeId(), row.getPositionId());
}
// TODO check the cache items for the position, security, underlying to find out whether they've been updated
return ResultsCell.forStaticValue(rowTarget, columnType, format);
} else if (targetType.isTargetType(ComputationTargetType.PORTFOLIO_NODE)) {
return ResultsCell.forStaticValue(new NodeTarget(row.getName(), row.getNodeId()), columnType, format);
} else if (targetType.isTargetType(ComputationTargetType.TRADE)) {
// only fungible trades have their own row, OTC trades are shown on the same row as their parent position
FungibleTradeTarget tradeTarget =
new FungibleTradeTarget(row.getName(), row.getNodeId(), row.getPositionId(), row.getTradeId());
// TODO check cache item for trade to see if it's been updated
return ResultsCell.forStaticValue(tradeTarget, columnType, format);
}
throw new IllegalArgumentException("Unexpected target type for row: " + targetType);
}
private static boolean isOtc(Security security) {
if (security instanceof FinancialSecurity) {
return ((FinancialSecurity) security).accept(new OtcSecurityVisitor());
} else {
return false;
}
}
}