Google Protobufs(3) - 使用反射机制给Message赋值

写一下大致的思路,就是根据map中的key去匹配Message中的field,如果有就根据类型去赋值。 有需要的可以参考下这个思路。

    

public static void main(String[] args) throws IOException {
        Map<String, String> value = new HashedMap();
        value.put("int_value","11");
        value.put("enum_value","1");
        value.put("rep_int_value","22");
        value.put("map","1:2");
        value.put("message","{inner_string_value=abc}");
        EventOuterClass.Event.Builder eventBuilder = EventOuterClass.Event.newBuilder();
        System.out.println(buildMessage(eventBuilder, value));

}

// build MessageType
 private static Object buildMessage(Message.Builder eventBuilder, Map<String, String> value){
        Descriptors.Descriptor eventDesc = eventBuilder.getDescriptorForType();
        for (Map.Entry<String, String> entry : value.entrySet()) {
            final String fieldName = entry.getKey();
            final String fieldValue = entry.getValue();
            final Descriptors.FieldDescriptor fieldDesc = eventDesc.findFieldByName(fieldName);
            if (fieldDesc != null) {
                if (fieldDesc.isMapField()){
                    buildMapType(eventBuilder, fieldDesc, fieldValue);
                }else if (fieldDesc.isRepeated()) {
                    if (Descriptors.FieldDescriptor.JavaType.MESSAGE.equals(fieldDesc.getJavaType())){
                        final Message.Builder subBuilder = eventBuilder.newBuilderForField(fieldDesc);
                        Map<String, String> subValue=null;//TODO fileldValue converted to map

                        eventBuilder.addRepeatedField(fieldDesc, buildMessage(subBuilder, subValue));
                    }else {
                        eventBuilder.addRepeatedField(fieldDesc, buildValue(fieldDesc, fieldValue));
                    }
                } else {
                    if (Descriptors.FieldDescriptor.JavaType.MESSAGE.equals(fieldDesc.getJavaType())){
                        final Message.Builder subBuilder = eventBuilder.newBuilderForField(fieldDesc);
                        Map<String, String> subValue=null;//TODO fileldValue converted to map
                        eventBuilder.setField(fieldDesc, buildMessage(subBuilder, subValue));
                    }else {
                        eventBuilder.setField(fieldDesc,  buildValue(fieldDesc, fieldValue));
                    }
                }
            }
        }
        return eventBuilder.build();
    }

    private static void buildMapType(Message.Builder currentBuilder, Descriptors.FieldDescriptor field, String realVal) {
        //split by :
        final String[] kv = realVal.split(":");
        String key = kv[0].trim();
        String value = kv[1].trim();
        MapEntry.Builder mapEntryBuilder = (MapEntry.Builder) currentBuilder.newBuilderForField(field);
        final Descriptors.FieldDescriptor keyFieldDesc = mapEntryBuilder.getDescriptorForType().findFieldByName("key");
        final Descriptors.FieldDescriptor valueFieldDesc = mapEntryBuilder.getDescriptorForType().findFieldByName("value");
        mapEntryBuilder.setKey(buildValue(keyFieldDesc, key));
        mapEntryBuilder.setField(valueFieldDesc, buildValue(valueFieldDesc, value));
        currentBuilder.addRepeatedField(field, mapEntryBuilder.build());
    }

    public static Object buildValue(Descriptors.FieldDescriptor fieldDesc, String value){
        final Descriptors.FieldDescriptor.JavaType javaType = fieldDesc.getJavaType();
        switch (javaType) {
            case ENUM:
                return fieldDesc.getEnumType().findValueByNumber(Integer.valueOf(value));
            case FLOAT:
                return Float.valueOf(value);
            case INT:
                return Integer.valueOf(value);
            case LONG:
                return Long.valueOf(value);
            case DOUBLE:
                return Double.valueOf(value);
            case BOOLEAN:
                return Boolean.valueOf(value);
            case BYTE_STRING:
                return ByteString.copyFrom(DataConverters.hexString2ByteArray(value));
            default:
                return value;
        }
    }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值