如何将通过DA Ledger API接收的DAML元组转换为Java对?

时间:2018-12-12 15:08:43

标签: daml

我写了一个DAML模型,该模型生成一个元组列表,例如[(Int, Text)]。我通过DA Ledger API收到了这些数据-如何在Java中将其转换为List<Pair<Long, String>>

2 个答案:

答案 0 :(得分:6)

Java取决于您使用的是原始的已编译Protobuf类型,还是Java语言绑定提供的包装类型。

API返回的对象使用三种主要类型表示:

  • Record
  • RecordField
  • Value

稍微简化一点,RecordRecordField的列表,RecordField是标签,ValueValue可以是许多列表之一事物,包括Int64StringRecordList。像(Int, Text)这样的元组在DAML中具有特殊的符号,但在API中表示为普通的Record对象。

假设您使用的是根据protobuf定义编译的类型,并且已经准备好代表com.digitalasset.ledger.api.v1.ValueOuterClass.Value的{​​{1}},则需要执行以下操作:

  1. 使用[(Int, Text)]Value::getListValueOuterClass.List::getElementsList展开为Value
  2. 通过List<Value>解开列表中的每个Value以获得Value::getRecord
  3. 使用List<Record>提取每条记录的两个字段以获取Record::getFields
  4. List<Pair<RecordField, RecordField>>RecordFields中提取值,得到RecordFields::getValue
  5. List<Pair<Value, Value>>对象中提取Int64(它是long的别名)和String的对象,以获取最终的Value

步骤2-4.使用Java的流式接口可以轻松完成。显示的代码是针对原始gRPC类型的,从List<Pair<Long, String>>开始:

com.digitalasset.ledger.api.v1.ValueOuterClass.Value

答案 1 :(得分:5)

假设您具有以下daml模板:

template ListOfTuples
  with
    party : Party
    listOfTuples : [(Int, Text)]
  where
    signatory party

已通过java api转换为com.daml.ledger.javaapi.data.Record,您可以通过将列表中的元组也视为List<Pair<Long, String>> s来将其转换为Record

import java.util.List;
import javafx.util.Pair;
import java.util.stream.Collectors;
import com.daml.ledger.javaapi.data.Record;

public void parseListOfTuples(Record record) {

  List<Pair<Long, String>> listOfTuples =
     record.getFields().get(1).getValue().asList().get().getValues().stream()
             .map(t -> {
                 List<Record.Field> tuple = t.asRecord().get().getFields();
                 return new Pair<>(
                         tuple.get(0).getValue().asInt64().get().getValue(),
                         tuple.get(1).getValue().asText().get().getValue());
             })
             .collect(Collectors.toList());
}