/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.cache;
import it.unimi.dsi.fastutil.longs.AbstractLongList;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.LongList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.fudgemsg.FudgeContext;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.FudgeMsgEnvelope;
import org.fudgemsg.MutableFudgeMsg;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.fudgemsg.mapping.FudgeSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.engine.cache.msg.CacheMessage;
import com.opengamma.engine.cache.msg.CacheMessageVisitor;
import com.opengamma.engine.cache.msg.IdentifierLookupRequest;
import com.opengamma.engine.cache.msg.IdentifierLookupResponse;
import com.opengamma.engine.cache.msg.SpecificationLookupRequest;
import com.opengamma.engine.cache.msg.SpecificationLookupResponse;
import com.opengamma.engine.value.ValueSpecification;
import com.opengamma.transport.FudgeRequestReceiver;
/**
* Server for a {@link RemoteIdentifierMap}.
*/
public class IdentifierMapServer extends CacheMessageVisitor implements FudgeRequestReceiver {
private static final Logger s_logger = LoggerFactory.getLogger(IdentifierMapServer.class);
private final IdentifierMap _underlying;
public IdentifierMapServer(final IdentifierMap underlying) {
_underlying = underlying;
}
protected IdentifierMap getUnderlying() {
return _underlying;
}
@Override
protected IdentifierLookupResponse visitIdentifierLookupRequest(final IdentifierLookupRequest request) {
final List<ValueSpecification> spec = request.getSpecification();
final Collection<Long> identifiers;
if (spec.size() == 1) {
identifiers = Collections.singleton(getUnderlying().getIdentifier(spec.get(0)));
} else {
final Map<ValueSpecification, Long> identifierMap = getUnderlying().getIdentifiers(spec);
identifiers = new ArrayList<Long>(identifierMap.size());
for (ValueSpecification specEntry : spec) {
identifiers.add(identifierMap.get(specEntry));
}
}
final IdentifierLookupResponse response = new IdentifierLookupResponse(identifiers);
return response;
}
@Override
protected SpecificationLookupResponse visitSpecificationLookupRequest(final SpecificationLookupRequest request) {
final LongList identifiers = new AbstractLongList() {
private List<Long> _raw = request.getIdentifier();
@Override
public long getLong(int index) {
return _raw.get(index);
}
@Override
public int size() {
return _raw.size();
}
};
final Collection<ValueSpecification> specifications;
if (identifiers.size() == 1) {
specifications = Collections.singleton(getUnderlying().getValueSpecification(identifiers.getLong(0)));
} else {
final Long2ObjectMap<ValueSpecification> specificationMap = getUnderlying().getValueSpecifications(identifiers);
specifications = new ArrayList<ValueSpecification>(specificationMap.size());
for (Long identifier : identifiers) {
specifications.add(specificationMap.get(identifier));
}
}
final SpecificationLookupResponse response = new SpecificationLookupResponse(specifications);
return response;
}
@Override
public FudgeMsg requestReceived(final FudgeDeserializer deserializer, final FudgeMsgEnvelope requestEnvelope) {
final CacheMessage request = deserializer.fudgeMsgToObject(CacheMessage.class, requestEnvelope.getMessage());
final FudgeContext fudgeContext = deserializer.getFudgeContext();
CacheMessage response = request.accept(this);
if (response == null) {
response = new CacheMessage();
}
response.setCorrelationId(request.getCorrelationId());
final FudgeSerializer ctx = new FudgeSerializer(fudgeContext);
final MutableFudgeMsg responseMsg = ctx.objectToFudgeMsg(response);
// We have only one response for each request type, so don't need the headers
// FudgeSerializer.addClassHeader(responseMsg, response.getClass(), IdentifierMapResponse.class);
return responseMsg;
}
@Override
protected <T extends CacheMessage> T visitUnexpectedMessage(final CacheMessage message) {
s_logger.warn("Unexpected message {}", message);
return null;
}
}