89 lines
4.0 KiB
Java
89 lines
4.0 KiB
Java
/*
|
|
* Copyright 2025 Google. This software is provided as-is, without warranty or representation for any use or purpose.
|
|
* Your use of it is subject to your agreement with Google.
|
|
*/
|
|
|
|
package com.example.util;
|
|
|
|
import com.google.protobuf.ListValue;
|
|
import com.google.protobuf.NullValue;
|
|
import com.google.protobuf.Struct;
|
|
import com.google.protobuf.Value;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
public class ProtobufUtil {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ProtobufUtil.class);
|
|
|
|
/**
|
|
* Converts a Java Object to a Protobuf Value.
|
|
* Supports primitive types, String, Map, and List.
|
|
* Maps will be converted to Protobuf Structs.
|
|
* Lists will be converted to Protobuf ListValues.
|
|
*/
|
|
@SuppressWarnings("rawtypes")
|
|
public static Value convertJavaObjectToProtobufValue(Object obj) {
|
|
if (obj == null) {
|
|
return Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build();
|
|
} else if (obj instanceof Boolean) {
|
|
return Value.newBuilder().setBoolValue((Boolean) obj).build();
|
|
} else if (obj instanceof Integer) {
|
|
return Value.newBuilder().setNumberValue(((Integer) obj).doubleValue()).build();
|
|
} else if (obj instanceof Long) {
|
|
return Value.newBuilder().setNumberValue(((Long) obj).doubleValue()).build();
|
|
} else if (obj instanceof Double) {
|
|
return Value.newBuilder().setNumberValue((Double) obj).build();
|
|
} else if (obj instanceof String) {
|
|
return Value.newBuilder().setStringValue((String) obj).build();
|
|
} else if (obj instanceof Enum) {
|
|
return Value.newBuilder().setStringValue(((Enum) obj).name()).build();
|
|
} else if (obj instanceof Map) {
|
|
Struct.Builder structBuilder = Struct.newBuilder();
|
|
((Map<?, ?>) obj).forEach((key, val) ->
|
|
structBuilder.putFields(String.valueOf(key), convertJavaObjectToProtobufValue(val))
|
|
);
|
|
return Value.newBuilder().setStructValue(structBuilder.build()).build();
|
|
} else if (obj instanceof List) {
|
|
ListValue.Builder listValueBuilder = ListValue.newBuilder();
|
|
((List<?>) obj).forEach(item ->
|
|
listValueBuilder.addValues(convertJavaObjectToProtobufValue(item))
|
|
);
|
|
return Value.newBuilder().setListValue(listValueBuilder.build()).build();
|
|
}
|
|
logger.warn("Unsupported type for Protobuf conversion: {}. Converting to String.", obj.getClass().getName());
|
|
return Value.newBuilder().setStringValue(obj.toString()).build();
|
|
}
|
|
|
|
/**
|
|
* Converts a Protobuf Value to a Java Object.
|
|
* Supports Null, Boolean, Number, String, Struct (to Map), and ListValue (to List).
|
|
*/
|
|
public static Object convertProtobufValueToJavaObject(Value protobufValue) {
|
|
return switch (protobufValue.getKindCase()) {
|
|
case NULL_VALUE -> null;
|
|
case BOOL_VALUE -> protobufValue.getBoolValue();
|
|
case NUMBER_VALUE -> protobufValue.getNumberValue();
|
|
case STRING_VALUE -> protobufValue.getStringValue();
|
|
case STRUCT_VALUE -> protobufValue.getStructValue().getFieldsMap().entrySet().stream()
|
|
.collect(Collectors.toMap(
|
|
Map.Entry::getKey,
|
|
entry -> convertProtobufValueToJavaObject(entry.getValue()),
|
|
(oldValue, newValue) -> oldValue,
|
|
LinkedHashMap::new
|
|
));
|
|
case LIST_VALUE -> protobufValue.getListValue().getValuesList().stream()
|
|
.map(ProtobufUtil::convertProtobufValueToJavaObject) // Use static method reference
|
|
.collect(Collectors.toList());
|
|
default -> {
|
|
logger.warn("Unsupported Protobuf Value type: {}. Returning null.", protobufValue.getKindCase());
|
|
yield null;
|
|
}
|
|
};
|
|
}
|
|
} |