/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.integration.swing; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import com.google.common.collect.Lists; import com.opengamma.core.position.Portfolio; import com.opengamma.core.position.PortfolioNode; import com.opengamma.core.position.Position; import com.opengamma.core.position.PositionSource; import com.opengamma.core.position.Trade; import com.opengamma.core.security.Security; import com.opengamma.core.security.SecuritySource; import com.opengamma.engine.view.compilation.PortfolioCompiler; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.integration.tool.IntegrationToolContext; import com.opengamma.util.tuple.Pair; /** * Swing TreeModel for browsing a resolved portfolio */ public class PortfolioTreeModel implements TreeModel { private static final int THREAD_POOL_SIZE = 20; private final PositionSource _positionSource; private final SecuritySource _securitySource; private UniqueId _portfolioId; private volatile Portfolio _portfolio; private List<TreeModelListener> _listeners = new ArrayList<TreeModelListener>(); public PortfolioTreeModel(final UniqueId portfolioId, final IntegrationToolContext toolContext) { _portfolioId = portfolioId; _positionSource = toolContext.getPositionSource(); _securitySource = toolContext.getSecuritySource(); SwingWorker<Portfolio, Pair<UniqueId, SecuritySource>> worker = new SwingWorker<Portfolio, Pair<UniqueId, SecuritySource>>() { @Override protected Portfolio doInBackground() throws Exception { Portfolio portfolio = _positionSource.getPortfolio(portfolioId, VersionCorrection.LATEST); Portfolio resolvedPortfolio = PortfolioCompiler.resolvePortfolio(portfolio, Executors.newFixedThreadPool(THREAD_POOL_SIZE), _securitySource); return resolvedPortfolio; } protected void done() { try { _portfolio = get(); if (_portfolio != null) { for (TreeModelListener listener : _listeners) { listener.treeStructureChanged(new TreeModelEvent(PortfolioTreeModel.this, new TreePath(_portfolio.getRootNode()))); } } } catch (InterruptedException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error getting portfolio", JOptionPane.ERROR_MESSAGE); } catch (ExecutionException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error getting portfolio", JOptionPane.ERROR_MESSAGE); } } }; worker.execute(); } @Override public Object getRoot() { if (_portfolio == null) { return null; } else { return _portfolio.getRootNode(); } } @Override public Object getChild(Object parent, int index) { if (parent instanceof PortfolioNode) { PortfolioNode portfolioNode = (PortfolioNode) parent; List<PortfolioNode> childNodes = portfolioNode.getChildNodes(); if (index < childNodes.size()) { return childNodes.get(index); } else { // we get a position List<Position> positions = portfolioNode.getPositions(); int positionIndex = index - childNodes.size(); if (positionIndex < positions.size()) { return positions.get(positionIndex); } else { return null; } } } else if (parent instanceof Position) { Position position = (Position) parent; Collection<Trade> trades = position.getTrades(); if (trades.size() > 0) { // position has trades, so return them as children if (index < trades.size()) { return Lists.newArrayList(trades).get(index); } else { return null; } } else { // if this position has no trades, return the security as a sub-node if (index == 0) { return position.getSecurity(); } } } else if (parent instanceof Trade) { Trade trade = (Trade) parent; if ((trade.getSecurity() != null) && (index == 0)) { return trade.getSecurity(); } } // shouldn't encounter securities here as they are always leaf nodes. return null; } @Override public int getChildCount(Object parent) { if (parent instanceof PortfolioNode) { PortfolioNode portfolioNode = (PortfolioNode) parent; List<PortfolioNode> childNodes = portfolioNode.getChildNodes(); return portfolioNode.getChildNodes().size() + portfolioNode.getPositions().size(); } else if (parent instanceof Position) { Position position = (Position) parent; return position.getTrades().size() == 0 ? 1 : position.getTrades().size(); } else if (parent instanceof Trade) { Trade trade = (Trade) parent; if ((trade.getSecurity() != null)) { return 1; } else { return 0; } } else if (parent instanceof Security) { return 0; } return 0; } @Override public boolean isLeaf(Object node) { if (node instanceof PortfolioNode) { PortfolioNode portfolioNode = (PortfolioNode) node; return portfolioNode.getChildNodes().size() == 0 && portfolioNode.getPositions().size() == 0; } else if (node instanceof Position) { Position position = (Position) node; return position.getTrades().size() == 0 && position.getSecurity() == null; } else if (node instanceof Trade) { Trade trade = (Trade) node; return trade.getSecurity() == null; } else if (node instanceof Security) { return true; } else { return true; } } @Override public void valueForPathChanged(TreePath path, Object newValue) { throw new UnsupportedOperationException("Tree editing is not supported by this model"); } @Override public int getIndexOfChild(Object parent, Object child) { if (parent instanceof PortfolioNode) { PortfolioNode parentNode = (PortfolioNode) parent; if (child instanceof PortfolioNode) { PortfolioNode childNode = (PortfolioNode) child; return parentNode.getChildNodes().indexOf(childNode); } else if (child instanceof Position) { Position childPosition = (Position) child; int positionIndex = parentNode.getPositions().indexOf(childPosition); if (positionIndex == -1) { return -1; } else { return parentNode.getChildNodes().size() + parentNode.getPositions().indexOf(childPosition); } } else { return -1; } } else if (parent instanceof Position) { Position parentPosition = (Position) parent; if (child instanceof Trade) { Trade childTrade = (Trade) child; return Lists.newArrayList(parentPosition.getTrades()).indexOf(childTrade); // indexOf returns -1 as expected by this interface if not present } else if (child instanceof Security) { return 0; } } else if (parent instanceof Trade) { Trade parentTrade = (Trade) parent; if (child instanceof Security) { return 0; } else { return -1; } } else if (parent instanceof Security) { return -1; } return -1; } @Override public void addTreeModelListener(TreeModelListener l) { _listeners.add(l); } @Override public void removeTreeModelListener(TreeModelListener l) { _listeners.remove(l); } }