/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.master.portfolio; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; import org.apache.commons.collections.CollectionUtils; import org.joda.beans.Bean; import org.joda.beans.BeanBuilder; import org.joda.beans.BeanDefinition; import org.joda.beans.JodaBeanUtils; import org.joda.beans.MetaProperty; import org.joda.beans.Property; import org.joda.beans.PropertyDefinition; import org.joda.beans.impl.direct.DirectBean; import org.joda.beans.impl.direct.DirectBeanBuilder; import org.joda.beans.impl.direct.DirectMetaBean; import org.joda.beans.impl.direct.DirectMetaProperty; import org.joda.beans.impl.direct.DirectMetaPropertyMap; import com.opengamma.id.MutableUniqueIdentifiable; import com.opengamma.id.ObjectId; import com.opengamma.id.ObjectIdentifiable; import com.opengamma.id.UniqueId; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.PublicSPI; /** * A node in a portfolio tree allowing an arbitrary structure within an organization * for the management of positions. * <p> * Each node can have child nodes forming a tree structure. * Each node can also have a collection of positions referred to by identifier. * The details of each position is held in the position master. */ @PublicSPI @BeanDefinition public class ManageablePortfolioNode extends DirectBean implements MutableUniqueIdentifiable { /** * The portfolio node unique identifier. * This must be null when adding to a master and not null when retrieved from a master. */ @PropertyDefinition private UniqueId _uniqueId; /** * The parent node unique identifier, null if the root node. * This field is managed by the master. */ @PropertyDefinition private UniqueId _parentNodeId; /** * The portfolio unique identifier. * This field is managed by the master. */ @PropertyDefinition private UniqueId _portfolioId; /** * The portfolio node name. * This field must not be null for the object to be valid. */ @PropertyDefinition private String _name = ""; /** * The root node of the tree, not null. */ @PropertyDefinition private final List<ManageablePortfolioNode> _childNodes = new ArrayList<ManageablePortfolioNode>(); /** * The object identifiers of positions attached to this node, not null. * The identifiers should not have versions. */ @PropertyDefinition private final List<ObjectId> _positionIds = new ArrayList<ObjectId>(); /** * Creates a node. */ public ManageablePortfolioNode() { } /** * Creates a node specifying the name. * * @param name the name, not null */ public ManageablePortfolioNode(final String name) { ArgumentChecker.notNull(name, "name"); setName(name); } //------------------------------------------------------------------------- /** * Adds a position object identifier to this node. * * @param positionId the object identifier of the position, not null */ public void addPosition(final ObjectIdentifiable positionId) { ArgumentChecker.notNull(positionId, "positionId"); getPositionIds().add(positionId.getObjectId()); } //------------------------------------------------------------------------- /** * Adds a child node to this node. * * @param childNode the child node, not null */ public void addChildNode(final ManageablePortfolioNode childNode) { ArgumentChecker.notNull(childNode, "childNode"); getChildNodes().add(childNode); } //------------------------------------------------------------------------- /** * Checks if any node object identifier matches one in the specified list. * * @param nodeObjectIds the object identifiers to match against, not null * @return true if at least one identifier matches */ public boolean matchesAnyNode(List<ObjectId> nodeObjectIds) { ArgumentChecker.notNull(nodeObjectIds, "objectIds"); if (nodeObjectIds.contains(getUniqueId().getObjectId())) { return true; } for (ManageablePortfolioNode childNode : getChildNodes()) { if (childNode.matchesAnyNode(nodeObjectIds)) { return true; } } return false; } /** * Checks if any position object identifier matches one in the specified list. * * @param positionObjectIds the position object identifiers to match against, not null * @return true if at least one identifier matches */ public boolean matchesAnyPosition(List<ObjectId> positionObjectIds) { ArgumentChecker.notNull(positionObjectIds, "positionObjectIds"); if (CollectionUtils.containsAny(positionObjectIds, getPositionIds())) { return true; } for (ManageablePortfolioNode childNode : getChildNodes()) { if (childNode.matchesAnyPosition(positionObjectIds)) { return true; } } return false; } //------------------------------------------------------------------------- /** * Finds a node with the specified object identifier, which may be this node. * This scans all child nodes depth-first until the node is found. * * @param nodeObjectId the node object identifier, not null * @return the node with the identifier, null if not found */ public ManageablePortfolioNode findNodeByObjectId(final ObjectIdentifiable nodeObjectId) { ArgumentChecker.notNull(nodeObjectId, "nodeObjectId"); return findNodeByObjectId0(nodeObjectId.getObjectId()); } /** * Finds a node with the specified object identifier, which may be this node. * This scans all child nodes depth-first until the node is found. * * @param nodeObjectId the node object identifier, not null * @return the node with the identifier, null if not found */ private ManageablePortfolioNode findNodeByObjectId0(final ObjectId nodeObjectId) { if (getUniqueId().equalObjectId(nodeObjectId)) { return this; } for (ManageablePortfolioNode childNode : getChildNodes()) { ManageablePortfolioNode found = childNode.findNodeByObjectId0(nodeObjectId); if (found != null) { return found; } } return null; } //------------------------------------------------------------------------- /** * Finds a node with the specified name, which may be this node. * This scans all child nodes depth-first until the node is found. * * @param name the node name, not null * @return the node with the name, null if not found */ public ManageablePortfolioNode findNodeByName(final String name) { ArgumentChecker.notNull(name, "name"); if (name.equals(getName())) { return this; } for (ManageablePortfolioNode child : getChildNodes()) { ManageablePortfolioNode found = child.findNodeByName(name); if (found != null) { return found; } } return null; } //------------------------------------------------------------------------- /** * Finds the stack of nodes from the tree below this node by identifier. * This performs a recursive scan of the child nodes returning all the nodes * in the hierarchy from the root node to the specified node. * The specified node is at the top of the stack. * * @param nodeObjectId the node object identifier, not null * @return the node stack, empty if not found, not null */ public Stack<ManageablePortfolioNode> findNodeStackByObjectId(final ObjectIdentifiable nodeObjectId) { ArgumentChecker.notNull(nodeObjectId, "nodeObjectId"); Stack<ManageablePortfolioNode> stack = new Stack<ManageablePortfolioNode>(); Stack<ManageablePortfolioNode> result = findNodeStackByObjectId0(stack, nodeObjectId.getObjectId()); return result == null ? stack : result; } /** * Finds the stack of nodes from the tree below this node by identifier. * * @param stack the stack of nodes, not null * @param nodeObjectId the node object identifier, not null * @return the node with the identifier, null if not found */ private Stack<ManageablePortfolioNode> findNodeStackByObjectId0(final Stack<ManageablePortfolioNode> stack, final ObjectId nodeObjectId) { stack.push(this); if (getUniqueId().equalObjectId(nodeObjectId)) { return stack; } for (ManageablePortfolioNode childNode : getChildNodes()) { Stack<ManageablePortfolioNode> found = childNode.findNodeStackByObjectId0(stack, nodeObjectId); if (found != null) { return found; } } stack.pop(); return null; } //------------------------------------------------------------------------- /** * Removes a node from the tree below this node by identifier. * This performs a recursive scan of the child nodes. * * @param nodeObjectId the node object identifier, not null * @return true if a node was removed */ public boolean removeNode(final ObjectIdentifiable nodeObjectId) { ArgumentChecker.notNull(nodeObjectId, "nodeObjectId"); return removeNode0(nodeObjectId.getObjectId()); } /** * Removes a node from the tree below this node by identifier. * This performs a recursive scan of the child nodes. * * @param nodeObjectId the node object identifier, not null * @return true if a node was removed */ private boolean removeNode0(final ObjectId nodeObjectId) { for (Iterator<ManageablePortfolioNode> it = _childNodes.iterator(); it.hasNext(); ) { final ManageablePortfolioNode child = it.next(); if (child.getUniqueId().equalObjectId(nodeObjectId)) { it.remove(); return true; } if (child.removeNode0(nodeObjectId)) { return true; } } return false; } //------------------------- AUTOGENERATED START ------------------------- ///CLOVER:OFF /** * The meta-bean for {@code ManageablePortfolioNode}. * @return the meta-bean, not null */ public static ManageablePortfolioNode.Meta meta() { return ManageablePortfolioNode.Meta.INSTANCE; } static { JodaBeanUtils.registerMetaBean(ManageablePortfolioNode.Meta.INSTANCE); } @Override public ManageablePortfolioNode.Meta metaBean() { return ManageablePortfolioNode.Meta.INSTANCE; } //----------------------------------------------------------------------- /** * Gets the portfolio node unique identifier. * This must be null when adding to a master and not null when retrieved from a master. * @return the value of the property */ public UniqueId getUniqueId() { return _uniqueId; } /** * Sets the portfolio node unique identifier. * This must be null when adding to a master and not null when retrieved from a master. * @param uniqueId the new value of the property */ public void setUniqueId(UniqueId uniqueId) { this._uniqueId = uniqueId; } /** * Gets the the {@code uniqueId} property. * This must be null when adding to a master and not null when retrieved from a master. * @return the property, not null */ public final Property<UniqueId> uniqueId() { return metaBean().uniqueId().createProperty(this); } //----------------------------------------------------------------------- /** * Gets the parent node unique identifier, null if the root node. * This field is managed by the master. * @return the value of the property */ public UniqueId getParentNodeId() { return _parentNodeId; } /** * Sets the parent node unique identifier, null if the root node. * This field is managed by the master. * @param parentNodeId the new value of the property */ public void setParentNodeId(UniqueId parentNodeId) { this._parentNodeId = parentNodeId; } /** * Gets the the {@code parentNodeId} property. * This field is managed by the master. * @return the property, not null */ public final Property<UniqueId> parentNodeId() { return metaBean().parentNodeId().createProperty(this); } //----------------------------------------------------------------------- /** * Gets the portfolio unique identifier. * This field is managed by the master. * @return the value of the property */ public UniqueId getPortfolioId() { return _portfolioId; } /** * Sets the portfolio unique identifier. * This field is managed by the master. * @param portfolioId the new value of the property */ public void setPortfolioId(UniqueId portfolioId) { this._portfolioId = portfolioId; } /** * Gets the the {@code portfolioId} property. * This field is managed by the master. * @return the property, not null */ public final Property<UniqueId> portfolioId() { return metaBean().portfolioId().createProperty(this); } //----------------------------------------------------------------------- /** * Gets the portfolio node name. * This field must not be null for the object to be valid. * @return the value of the property */ public String getName() { return _name; } /** * Sets the portfolio node name. * This field must not be null for the object to be valid. * @param name the new value of the property */ public void setName(String name) { this._name = name; } /** * Gets the the {@code name} property. * This field must not be null for the object to be valid. * @return the property, not null */ public final Property<String> name() { return metaBean().name().createProperty(this); } //----------------------------------------------------------------------- /** * Gets the root node of the tree, not null. * @return the value of the property, not null */ public List<ManageablePortfolioNode> getChildNodes() { return _childNodes; } /** * Sets the root node of the tree, not null. * @param childNodes the new value of the property, not null */ public void setChildNodes(List<ManageablePortfolioNode> childNodes) { JodaBeanUtils.notNull(childNodes, "childNodes"); this._childNodes.clear(); this._childNodes.addAll(childNodes); } /** * Gets the the {@code childNodes} property. * @return the property, not null */ public final Property<List<ManageablePortfolioNode>> childNodes() { return metaBean().childNodes().createProperty(this); } //----------------------------------------------------------------------- /** * Gets the object identifiers of positions attached to this node, not null. * The identifiers should not have versions. * @return the value of the property, not null */ public List<ObjectId> getPositionIds() { return _positionIds; } /** * Sets the object identifiers of positions attached to this node, not null. * The identifiers should not have versions. * @param positionIds the new value of the property, not null */ public void setPositionIds(List<ObjectId> positionIds) { JodaBeanUtils.notNull(positionIds, "positionIds"); this._positionIds.clear(); this._positionIds.addAll(positionIds); } /** * Gets the the {@code positionIds} property. * The identifiers should not have versions. * @return the property, not null */ public final Property<List<ObjectId>> positionIds() { return metaBean().positionIds().createProperty(this); } //----------------------------------------------------------------------- @Override public ManageablePortfolioNode clone() { return JodaBeanUtils.cloneAlways(this); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && obj.getClass() == this.getClass()) { ManageablePortfolioNode other = (ManageablePortfolioNode) obj; return JodaBeanUtils.equal(getUniqueId(), other.getUniqueId()) && JodaBeanUtils.equal(getParentNodeId(), other.getParentNodeId()) && JodaBeanUtils.equal(getPortfolioId(), other.getPortfolioId()) && JodaBeanUtils.equal(getName(), other.getName()) && JodaBeanUtils.equal(getChildNodes(), other.getChildNodes()) && JodaBeanUtils.equal(getPositionIds(), other.getPositionIds()); } return false; } @Override public int hashCode() { int hash = getClass().hashCode(); hash = hash * 31 + JodaBeanUtils.hashCode(getUniqueId()); hash = hash * 31 + JodaBeanUtils.hashCode(getParentNodeId()); hash = hash * 31 + JodaBeanUtils.hashCode(getPortfolioId()); hash = hash * 31 + JodaBeanUtils.hashCode(getName()); hash = hash * 31 + JodaBeanUtils.hashCode(getChildNodes()); hash = hash * 31 + JodaBeanUtils.hashCode(getPositionIds()); return hash; } @Override public String toString() { StringBuilder buf = new StringBuilder(224); buf.append("ManageablePortfolioNode{"); int len = buf.length(); toString(buf); if (buf.length() > len) { buf.setLength(buf.length() - 2); } buf.append('}'); return buf.toString(); } protected void toString(StringBuilder buf) { buf.append("uniqueId").append('=').append(JodaBeanUtils.toString(getUniqueId())).append(',').append(' '); buf.append("parentNodeId").append('=').append(JodaBeanUtils.toString(getParentNodeId())).append(',').append(' '); buf.append("portfolioId").append('=').append(JodaBeanUtils.toString(getPortfolioId())).append(',').append(' '); buf.append("name").append('=').append(JodaBeanUtils.toString(getName())).append(',').append(' '); buf.append("childNodes").append('=').append(JodaBeanUtils.toString(getChildNodes())).append(',').append(' '); buf.append("positionIds").append('=').append(JodaBeanUtils.toString(getPositionIds())).append(',').append(' '); } //----------------------------------------------------------------------- /** * The meta-bean for {@code ManageablePortfolioNode}. */ public static class Meta extends DirectMetaBean { /** * The singleton instance of the meta-bean. */ static final Meta INSTANCE = new Meta(); /** * The meta-property for the {@code uniqueId} property. */ private final MetaProperty<UniqueId> _uniqueId = DirectMetaProperty.ofReadWrite( this, "uniqueId", ManageablePortfolioNode.class, UniqueId.class); /** * The meta-property for the {@code parentNodeId} property. */ private final MetaProperty<UniqueId> _parentNodeId = DirectMetaProperty.ofReadWrite( this, "parentNodeId", ManageablePortfolioNode.class, UniqueId.class); /** * The meta-property for the {@code portfolioId} property. */ private final MetaProperty<UniqueId> _portfolioId = DirectMetaProperty.ofReadWrite( this, "portfolioId", ManageablePortfolioNode.class, UniqueId.class); /** * The meta-property for the {@code name} property. */ private final MetaProperty<String> _name = DirectMetaProperty.ofReadWrite( this, "name", ManageablePortfolioNode.class, String.class); /** * The meta-property for the {@code childNodes} property. */ @SuppressWarnings({"unchecked", "rawtypes" }) private final MetaProperty<List<ManageablePortfolioNode>> _childNodes = DirectMetaProperty.ofReadWrite( this, "childNodes", ManageablePortfolioNode.class, (Class) List.class); /** * The meta-property for the {@code positionIds} property. */ @SuppressWarnings({"unchecked", "rawtypes" }) private final MetaProperty<List<ObjectId>> _positionIds = DirectMetaProperty.ofReadWrite( this, "positionIds", ManageablePortfolioNode.class, (Class) List.class); /** * The meta-properties. */ private final Map<String, MetaProperty<?>> _metaPropertyMap$ = new DirectMetaPropertyMap( this, null, "uniqueId", "parentNodeId", "portfolioId", "name", "childNodes", "positionIds"); /** * Restricted constructor. */ protected Meta() { } @Override protected MetaProperty<?> metaPropertyGet(String propertyName) { switch (propertyName.hashCode()) { case -294460212: // uniqueId return _uniqueId; case 915246087: // parentNodeId return _parentNodeId; case -5186429: // portfolioId return _portfolioId; case 3373707: // name return _name; case 1339293429: // childNodes return _childNodes; case -137459505: // positionIds return _positionIds; } return super.metaPropertyGet(propertyName); } @Override public BeanBuilder<? extends ManageablePortfolioNode> builder() { return new DirectBeanBuilder<ManageablePortfolioNode>(new ManageablePortfolioNode()); } @Override public Class<? extends ManageablePortfolioNode> beanType() { return ManageablePortfolioNode.class; } @Override public Map<String, MetaProperty<?>> metaPropertyMap() { return _metaPropertyMap$; } //----------------------------------------------------------------------- /** * The meta-property for the {@code uniqueId} property. * @return the meta-property, not null */ public final MetaProperty<UniqueId> uniqueId() { return _uniqueId; } /** * The meta-property for the {@code parentNodeId} property. * @return the meta-property, not null */ public final MetaProperty<UniqueId> parentNodeId() { return _parentNodeId; } /** * The meta-property for the {@code portfolioId} property. * @return the meta-property, not null */ public final MetaProperty<UniqueId> portfolioId() { return _portfolioId; } /** * The meta-property for the {@code name} property. * @return the meta-property, not null */ public final MetaProperty<String> name() { return _name; } /** * The meta-property for the {@code childNodes} property. * @return the meta-property, not null */ public final MetaProperty<List<ManageablePortfolioNode>> childNodes() { return _childNodes; } /** * The meta-property for the {@code positionIds} property. * @return the meta-property, not null */ public final MetaProperty<List<ObjectId>> positionIds() { return _positionIds; } //----------------------------------------------------------------------- @Override protected Object propertyGet(Bean bean, String propertyName, boolean quiet) { switch (propertyName.hashCode()) { case -294460212: // uniqueId return ((ManageablePortfolioNode) bean).getUniqueId(); case 915246087: // parentNodeId return ((ManageablePortfolioNode) bean).getParentNodeId(); case -5186429: // portfolioId return ((ManageablePortfolioNode) bean).getPortfolioId(); case 3373707: // name return ((ManageablePortfolioNode) bean).getName(); case 1339293429: // childNodes return ((ManageablePortfolioNode) bean).getChildNodes(); case -137459505: // positionIds return ((ManageablePortfolioNode) bean).getPositionIds(); } return super.propertyGet(bean, propertyName, quiet); } @SuppressWarnings("unchecked") @Override protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) { switch (propertyName.hashCode()) { case -294460212: // uniqueId ((ManageablePortfolioNode) bean).setUniqueId((UniqueId) newValue); return; case 915246087: // parentNodeId ((ManageablePortfolioNode) bean).setParentNodeId((UniqueId) newValue); return; case -5186429: // portfolioId ((ManageablePortfolioNode) bean).setPortfolioId((UniqueId) newValue); return; case 3373707: // name ((ManageablePortfolioNode) bean).setName((String) newValue); return; case 1339293429: // childNodes ((ManageablePortfolioNode) bean).setChildNodes((List<ManageablePortfolioNode>) newValue); return; case -137459505: // positionIds ((ManageablePortfolioNode) bean).setPositionIds((List<ObjectId>) newValue); return; } super.propertySet(bean, propertyName, newValue, quiet); } @Override protected void validate(Bean bean) { JodaBeanUtils.notNull(((ManageablePortfolioNode) bean)._childNodes, "childNodes"); JodaBeanUtils.notNull(((ManageablePortfolioNode) bean)._positionIds, "positionIds"); } } ///CLOVER:ON //-------------------------- AUTOGENERATED END -------------------------- }