/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.core.position;
import java.util.Collection;
import org.fudgemsg.FudgeField;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.MutableFudgeMsg;
import org.fudgemsg.mapping.FudgeBuilder;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.fudgemsg.mapping.GenericFudgeBuilderFor;
import org.fudgemsg.wire.types.FudgeWireType;
import com.opengamma.core.position.impl.SimplePortfolioNode;
import com.opengamma.core.position.impl.SimplePosition;
import com.opengamma.id.UniqueId;
/**
* Fudge message builder for {@code PortfolioNode}. This is tightly coupled with the behavior of {@link PositionFudgeBuilder} so
* that the parent identifiers are not duplicated throughout the tree. Only the outer {@code PortfolioNode} will have its
* parent identifier written - all others can be inferred during tree construction.
*/
@GenericFudgeBuilderFor(PortfolioNode.class)
public class PortfolioNodeFudgeBuilder implements FudgeBuilder<PortfolioNode> {
/** Field name. */
public static final String POSITIONS_FIELD_NAME = "positions";
/** Field name. */
public static final String SUBNODES_FIELD_NAME = "subNodes";
/** Field name. */
public static final String NAME_FIELD_NAME = "name";
/** Field name. */
public static final String IDENTIFIER_FIELD_NAME = "identifier";
/** Field name. */
public static final String PARENT_FIELD_NAME = "parent";
// -------------------------------------------------------------------------
private static void encodePositions(final MutableFudgeMsg message, final FudgeSerializer serializer, final Collection<Position> collection) {
if (!collection.isEmpty()) {
final MutableFudgeMsg msg = serializer.newMessage();
for (Position position : collection) {
msg.add(null, null, PositionFudgeBuilder.buildMessageImpl(serializer, position));
}
message.add(POSITIONS_FIELD_NAME, msg);
}
}
private static void encodeSubNodes(final MutableFudgeMsg message, final FudgeSerializer serializer, final Collection<PortfolioNode> collection) {
if (!collection.isEmpty()) {
final MutableFudgeMsg msg = serializer.newMessage();
for (PortfolioNode node : collection) {
msg.add(null, null, buildMessageImpl(serializer, node));
}
message.add(SUBNODES_FIELD_NAME, msg);
}
}
private static MutableFudgeMsg buildMessageImpl(final FudgeSerializer serializer, final PortfolioNode node) {
final MutableFudgeMsg message = serializer.newMessage();
serializer.addToMessage(message, IDENTIFIER_FIELD_NAME, null, node.getUniqueId());
message.add(NAME_FIELD_NAME, node.getName());
encodePositions(message, serializer, node.getPositions());
encodeSubNodes(message, serializer, node.getChildNodes());
return message;
}
@Override
public MutableFudgeMsg buildMessage(final FudgeSerializer serializer, final PortfolioNode node) {
final MutableFudgeMsg message = buildMessageImpl(serializer, node);
serializer.addToMessage(message, PARENT_FIELD_NAME, null, node.getParentNodeId());
message.add(null, FudgeSerializer.TYPES_HEADER_ORDINAL, FudgeWireType.STRING, PortfolioNode.class.getName());
return message;
}
// -------------------------------------------------------------------------
private static void readPositions(FudgeDeserializer deserializer, FudgeMsg message, SimplePortfolioNode node) {
if (message != null) {
for (FudgeField field : message) {
if (field.getValue() instanceof FudgeMsg) {
final SimplePosition position = PositionFudgeBuilder.buildObjectImpl(deserializer, (FudgeMsg) field.getValue());
node.addPosition(position);
}
}
}
}
private static void readSubNodes(FudgeDeserializer deserializer, FudgeMsg message, SimplePortfolioNode node) {
if (message != null) {
for (FudgeField field : message) {
if (field.getValue() instanceof FudgeMsg) {
final SimplePortfolioNode child = buildObjectImpl(deserializer, (FudgeMsg) field.getValue());
child.setParentNodeId(node.getUniqueId());
node.addChildNode(child);
}
}
}
}
private static SimplePortfolioNode buildObjectImpl(final FudgeDeserializer deserializer, final FudgeMsg message) {
final FudgeField idField = message.getByName(IDENTIFIER_FIELD_NAME);
final UniqueId id = idField != null ? deserializer.fieldValueToObject(UniqueId.class, idField) : null;
final String name = message.getFieldValue(String.class, message.getByName(NAME_FIELD_NAME));
final SimplePortfolioNode node = new SimplePortfolioNode(name);
if (id != null) {
node.setUniqueId(id);
}
readPositions(deserializer, message.getFieldValue(FudgeMsg.class, message.getByName(POSITIONS_FIELD_NAME)), node);
readSubNodes(deserializer, message.getFieldValue(FudgeMsg.class, message.getByName(SUBNODES_FIELD_NAME)), node);
return node;
}
@Override
public PortfolioNode buildObject(FudgeDeserializer deserializer, FudgeMsg message) {
final SimplePortfolioNode node = buildObjectImpl(deserializer, message);
final FudgeField parentField = message.getByName(PARENT_FIELD_NAME);
final UniqueId parentId = (parentField != null) ? deserializer.fieldValueToObject(UniqueId.class, parentField) : null;
if (parentId != null) {
node.setParentNodeId(parentId);
}
return node;
}
}