[
https://issues.apache.org/jira/browse/SCB-946?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16714645#comment-16714645
]
ASF GitHub Bot commented on SCB-946:
------------------------------------
liubao68 closed pull request #1025: [SCB-946] serialize/deseriaze
List<List<X>>/List<Map<X, Y>>/Map<X, List<Y>>/Map<X, Map<Y, Z>>
URL: https://github.com/apache/servicecomb-java-chassis/pull/1025
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
index 860a9f6f0..0af2afb88 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
@@ -20,7 +20,9 @@
import java.util.Map;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
+import
org.apache.servicecomb.foundation.protobuf.internal.RootPropertyWrapDeserializer;
import
org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptorManager;
+import
org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.DeserializerSchemaManager;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.SerializerSchemaManager;
@@ -105,4 +107,17 @@ public RootDeserializer createRootDeserializer(JavaType
javaType, String shortMe
public RootDeserializer createRootDeserializer(JavaType javaType, Message
message) {
return deserializerSchemaManager.createRootDeserializer(javaType, message);
}
+
+ public RootDeserializer createPropertyRootDeserializer(String
shortWrapMessageName, Type propertyType) {
+ Message message = proto.getMessage(shortWrapMessageName);
+ if (!deserializerSchemaManager.isWrapProperty(message)) {
+ return createRootDeserializer(propertyType, shortWrapMessageName);
+ }
+
+ JavaType propertyWrapJavaType =
TypeFactory.defaultInstance().constructParametricType(
+ PropertyWrapper.class,
+ TypeFactory.defaultInstance().constructType(propertyType));
+ RootDeserializer rootDeserializer =
createRootDeserializer(propertyWrapJavaType, message);
+ return new RootPropertyWrapDeserializer(rootDeserializer);
+ }
}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
index 53ec0c2f6..72f376490 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
@@ -30,6 +30,8 @@
private ProtoConst() {
}
+ public static String ANNOTATION_WRAP_PROPERTY = "@WrapProperty";
+
public static String OP_HINT = " scb:";
public static String PACK_SCHEMA = "type.googleapis.com/";
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/RootPropertyWrapDeserializer.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/RootPropertyWrapDeserializer.java
new file mode 100644
index 000000000..ab646993e
--- /dev/null
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/RootPropertyWrapDeserializer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.protobuf.internal;
+
+import java.io.IOException;
+
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import
org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
+
+public class RootPropertyWrapDeserializer extends RootDeserializer {
+ private final RootDeserializer rootDeserializer;
+
+ public RootPropertyWrapDeserializer(RootDeserializer rootDeserializer) {
+ super(null, null);
+ this.rootDeserializer = rootDeserializer;
+ }
+
+ @Override
+ public <T> T deserialize(byte[] bytes) throws IOException {
+ PropertyWrapper<T> propertyWrapper = rootDeserializer.deserialize(bytes);
+ return propertyWrapper.value;
+ }
+}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyWrapper.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyWrapper.java
new file mode 100644
index 000000000..17b8d41dd
--- /dev/null
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/bean/PropertyWrapper.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.protobuf.internal.bean;
+
+public class PropertyWrapper<T> {
+ public T value;
+}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/MessageAsFieldSchema.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/MessageAsFieldSchema.java
index 6ab4b8e68..cb5df01bf 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/MessageAsFieldSchema.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/MessageAsFieldSchema.java
@@ -24,7 +24,7 @@
import io.protostuff.compiler.model.Field;
public class MessageAsFieldSchema extends FieldSchema {
- private Schema<Object> schema;
+ protected Schema<Object> schema;
public MessageAsFieldSchema(Field protoField, Schema<Object> schema) {
super(protoField);
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageAsFieldSchema.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageAsFieldSchema.java
new file mode 100644
index 000000000..0a1e7c043
--- /dev/null
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageAsFieldSchema.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.protobuf.internal.schema;
+
+import java.io.IOException;
+import java.util.List;
+
+import io.protostuff.Input;
+import io.protostuff.Output;
+import io.protostuff.Schema;
+import io.protostuff.compiler.model.Field;
+import io.protostuff.runtime.MessageSchema;
+
+/**
+ *
+ */
+public class PropertyWrapMessageAsFieldSchema extends MessageAsFieldSchema {
+ private PropertyWrapMessageSchema propertyWrapMessageSchema;
+
+ private FieldSchema fieldSchema;
+
+ public PropertyWrapMessageAsFieldSchema(Field protoField, Schema<Object>
schema) {
+ super(protoField, schema);
+
+ List<io.protostuff.runtime.Field<Object>> list = ((MessageSchema)
schema).getFields();
+ this.fieldSchema = (FieldSchema) list.get(0);
+
+ propertyWrapMessageSchema = new PropertyWrapMessageSchema();
+ propertyWrapMessageSchema.setFieldSchema(fieldSchema);
+ }
+
+ @Override
+ public void writeTo(Output output, Object value) throws IOException {
+ output.writeObject(number, value, propertyWrapMessageSchema, false);
+ }
+
+ @Override
+ public Object readFrom(Input input) throws IOException {
+ Object instance = schema.newMessage();
+ input.mergeObject(instance, schema);
+ return fieldSchema.getter.get(instance);
+ }
+
+ @Override
+ public void mergeFrom(Input input, Object message) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageSchema.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageSchema.java
new file mode 100644
index 000000000..b585d64d1
--- /dev/null
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/PropertyWrapMessageSchema.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.protobuf.internal.schema;
+
+import java.io.IOException;
+
+import io.protostuff.Output;
+import io.protostuff.runtime.MessageSchema;
+
+public class PropertyWrapMessageSchema extends MessageSchema {
+ private FieldSchema fieldSchema;
+
+ public void setFieldSchema(FieldSchema fieldSchema) {
+ this.fieldSchema = fieldSchema;
+ }
+
+ @Override
+ public void writeTo(Output output, Object message) throws IOException {
+ fieldSchema.writeTo(output, message);
+ }
+}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
index 5e7d50726..fe9978d58 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
@@ -35,8 +35,11 @@
import
org.apache.servicecomb.foundation.protobuf.internal.schema.scalar.UInt64Schema;
import io.protostuff.compiler.model.Field;
+import io.protostuff.compiler.model.FieldContainer;
+import io.protostuff.compiler.model.Message;
import io.protostuff.compiler.model.Proto;
import io.protostuff.compiler.model.ScalarFieldType;
+import io.protostuff.runtime.MessageSchema;
public class SchemaManager {
protected final ProtoMapper protoMapper;
@@ -52,6 +55,14 @@ protected boolean isAnyField(Field protoField, boolean
repeated) {
return !repeated &&
protoField.getType().getCanonicalName().equals(ProtoConst.ANY.getCanonicalName());
}
+ public boolean isWrapProperty(FieldContainer fieldContainer) {
+ return
fieldContainer.getCommentLines().contains(ProtoConst.ANNOTATION_WRAP_PROPERTY);
+ }
+
+ protected MessageSchema newMessageSchema(Message message) {
+ return new MessageSchema();
+ }
+
protected FieldSchema createScalarField(Field protoField) {
switch ((ScalarFieldType) protoField.getType()) {
case INT32:
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
index b42efc089..1bfb0d58b 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
@@ -28,10 +28,12 @@
import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;
import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanFactory;
import
org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
+import
org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
import org.apache.servicecomb.foundation.protobuf.internal.schema.AnySchema;
import org.apache.servicecomb.foundation.protobuf.internal.schema.FieldSchema;
import org.apache.servicecomb.foundation.protobuf.internal.schema.MapSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.MessageAsFieldSchema;
+import
org.apache.servicecomb.foundation.protobuf.internal.schema.PropertyWrapMessageAsFieldSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.RepeatedSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaCreateContext;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaManager;
@@ -39,6 +41,7 @@
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
import io.protostuff.compiler.model.Field;
import io.protostuff.compiler.model.Message;
@@ -69,14 +72,13 @@ public RootDeserializer createRootDeserializer(JavaType
javaType, Message messag
return new RootDeserializer(beanDescriptor, schema);
}
- protected MessageSchema createSchema(SchemaCreateContext context, JavaType
javaType,
- Message message) {
+ public MessageSchema createSchema(SchemaCreateContext context, JavaType
javaType, Message message) {
MessageSchema schema = context.getSchemas().get(message.getName());
if (schema != null) {
return schema;
}
- schema = new MessageSchema();
+ schema = newMessageSchema(message);
context.getSchemas().put(message.getName(), schema);
doCreateSchema(context, schema, javaType, message);
@@ -87,11 +89,17 @@ protected MessageSchema createSchema(SchemaCreateContext
context, JavaType javaT
protected void doCreateSchema(SchemaCreateContext context, MessageSchema
schema,
JavaType javaType,
Message message) {
+ if (javaType.isJavaLangObject()) {
+ javaType = TypeFactory.defaultInstance().constructType(Map.class);
+ }
if (Map.class.isAssignableFrom(javaType.getRawClass())) {
doCreateSchemaToMap(context, schema, javaType, message);
return;
}
+ if (isWrapProperty(message) &&
(!javaType.getRawClass().equals(PropertyWrapper.class))) {
+ javaType =
TypeFactory.defaultInstance().constructParametricType(PropertyWrapper.class,
javaType);
+ }
BeanDescriptor beanDescriptor =
protoMapper.getBeanDescriptorManager().getOrCreateBeanDescriptor(javaType);
List<io.protostuff.runtime.Field<Object>> fieldSchemas = new ArrayList<>();
@@ -177,7 +185,12 @@ protected FieldSchema
createSchemaField(SchemaCreateContext context, JavaType ja
// message
MessageSchema messageSchema = createSchema(context, javaType, (Message)
protoField.getType());
- MessageAsFieldSchema messageAsFieldSchema = new
MessageAsFieldSchema(protoField, messageSchema);
+ MessageAsFieldSchema messageAsFieldSchema;
+ if (isWrapProperty((Message) protoField.getType())) {
+ messageAsFieldSchema = new PropertyWrapMessageAsFieldSchema(protoField,
messageSchema);
+ } else {
+ messageAsFieldSchema = new MessageAsFieldSchema(protoField,
messageSchema);
+ }
return messageAsFieldSchema;
}
}
diff --git
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
index 296e1bcc8..85cf7a94a 100644
---
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
+++
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
@@ -27,6 +27,8 @@
import org.apache.servicecomb.foundation.protobuf.internal.schema.FieldSchema;
import org.apache.servicecomb.foundation.protobuf.internal.schema.MapSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.MessageAsFieldSchema;
+import
org.apache.servicecomb.foundation.protobuf.internal.schema.PropertyWrapMessageAsFieldSchema;
+import
org.apache.servicecomb.foundation.protobuf.internal.schema.PropertyWrapMessageSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.RepeatedSchema;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaCreateContext;
import
org.apache.servicecomb.foundation.protobuf.internal.schema.SchemaManager;
@@ -66,7 +68,11 @@ protected void buildSchemas() {
protected RootSerializer createRootSerializer(SchemaCreateContext context,
Message message) {
MessageSchema schema = createSchema(context, message);
-
+ if (isWrapProperty(message)) {
+ FieldSchema fieldSchema = (FieldSchema) schema.getFields().get(0);
+ schema = new PropertyWrapMessageSchema();
+ ((PropertyWrapMessageSchema) schema).setFieldSchema(fieldSchema);
+ }
return new RootSerializer(schema);
}
@@ -76,7 +82,7 @@ protected MessageSchema createSchema(SchemaCreateContext
context, Message messag
return schema;
}
- schema = new MessageSchema();
+ schema = newMessageSchema(message);
context.getSchemas().put(message.getName(), schema);
List<io.protostuff.runtime.Field<Object>> fieldSchemas = new ArrayList<>();
@@ -119,7 +125,12 @@ protected FieldSchema
createSchemaField(SchemaCreateContext context, Field proto
// message
MessageSchema messageSchema = createSchema(context, (Message)
protoField.getType());
- MessageAsFieldSchema messageAsFieldSchema = new
MessageAsFieldSchema(protoField, messageSchema);
+ MessageAsFieldSchema messageAsFieldSchema;
+ if (isWrapProperty((Message) protoField.getType())) {
+ messageAsFieldSchema = new PropertyWrapMessageAsFieldSchema(protoField,
messageSchema);
+ } else {
+ messageAsFieldSchema = new MessageAsFieldSchema(protoField,
messageSchema);
+ }
return messageAsFieldSchema;
}
}
diff --git
a/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestModelWrap.java
b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestModelWrap.java
new file mode 100644
index 000000000..94937c255
--- /dev/null
+++
b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestModelWrap.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.protobuf.internal;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.vertx.core.json.Json;
+
+public class TestModelWrap {
+ protected static ProtoMapperFactory factory = new ProtoMapperFactory();
+
+ protected static ProtoMapper modelProtoMapper =
factory.createFromName("model.proto");
+
+ public static class User {
+ public String name;
+
+ public User(String name) {
+ this.name = name;
+ }
+ }
+
+ static User user = new User("uName");
+
+ public static class PojoModel {
+ public List<List<User>> listListUser;
+
+ public List<Map<String, User>> listMapUser;
+
+ public Map<String, List<User>> mapListUser;
+
+ public Map<String, Map<String, User>> mapMapUser;
+
+ public List<List<List<User>>> listListListUser;
+
+ public List<List<Map<String, User>>> listListMapUser;
+
+ public List<Map<String, List<User>>> listMapListUser;
+
+ public List<Map<String, Map<String, User>>> listMapMapUser;
+
+ public Map<String, List<List<User>>> mapListListUser;
+
+ public Map<String, List<Map<String, User>>> mapListMapUser;
+
+ public Map<String, Map<String, List<User>>> mapMapListUser;
+
+ public Map<String, Map<String, Map<String, User>>> mapMapMapUser;
+
+ public void init() {
+ listListUser = Arrays.asList(Arrays.asList(user));
+ listMapUser = Arrays.asList(Collections.singletonMap(user.name, user));
+ mapListUser = Collections.singletonMap("k1", Arrays.asList(user));
+ mapMapUser = Collections.singletonMap("k1",
Collections.singletonMap(user.name, user));
+
+ listListListUser = Arrays.asList(Arrays.asList(Arrays.asList(user)));
+ listListMapUser =
Arrays.asList(Arrays.asList(Collections.singletonMap(user.name, user)));
+ listMapListUser = Arrays.asList(Collections.singletonMap("k1",
Arrays.asList(user)));
+ listMapMapUser = Arrays.asList(Collections.singletonMap("k1",
Collections.singletonMap(user.name, user)));
+ mapListListUser = Collections.singletonMap("k1",
Arrays.asList(Arrays.asList(user)));
+ mapListMapUser = Collections.singletonMap("k1",
Arrays.asList(Collections.singletonMap(user.name, user)));
+ mapMapListUser = Collections.singletonMap("k1",
Collections.singletonMap("k1", Arrays.asList(user)));
+ mapMapMapUser = Collections
+ .singletonMap("k1", Collections.singletonMap("k1",
Collections.singletonMap(user.name, user)));
+ }
+ }
+
+ public static class ProtoModel {
+ public List<ProtoListUser> listListUser;
+
+ public List<ProtoMapUser> listMapUser;
+
+ public Map<String, ProtoListUser> mapListUser;
+
+ public Map<String, ProtoMapUser> mapMapUser;
+
+ public List<ProtoListListUser> listListListUser;
+
+ public List<ProtoListMapUser> listListMapUser;
+
+ public List<ProtoMapListUser> listMapListUser;
+
+ public List<ProtoMapMapUser> listMapMapUser;
+
+ public Map<String, ProtoListListUser> mapListListUser;
+
+ public Map<String, ProtoListMapUser> mapListMapUser;
+
+ public Map<String, ProtoMapListUser> mapMapListUser;
+
+ public Map<String, ProtoMapMapUser> mapMapMapUser;
+
+ public void init() {
+ ProtoListUser protoListUser = new ProtoListUser();
+ protoListUser.init();
+
+ ProtoMapUser protoMapUser = new ProtoMapUser();
+ protoMapUser.init();
+
+ ProtoListListUser protoListListUser = new ProtoListListUser();
+ protoListListUser.init();
+
+ ProtoListMapUser protoListMapUser = new ProtoListMapUser();
+ protoListMapUser.init();
+
+ ProtoMapListUser protoMapListUser = new ProtoMapListUser();
+ protoMapListUser.init();
+
+ ProtoMapMapUser protoMapMapUser = new ProtoMapMapUser();
+ protoMapMapUser.init();
+
+ listListUser = Arrays.asList(protoListUser);
+ listMapUser = Arrays.asList(protoMapUser);
+ mapListUser = Collections.singletonMap("k1", protoListUser);
+ mapMapUser = Collections.singletonMap("k1", protoMapUser);
+
+ listListListUser = Arrays.asList(protoListListUser);
+ listListMapUser = Arrays.asList(protoListMapUser);
+ listMapListUser = Arrays.asList(protoMapListUser);
+ listMapMapUser = Arrays.asList(protoMapMapUser);
+ mapListListUser = Collections.singletonMap("k1", protoListListUser);
+ mapListMapUser = Collections.singletonMap("k1", protoListMapUser);
+ mapMapListUser = Collections.singletonMap("k1", protoMapListUser);
+ mapMapMapUser = Collections.singletonMap("k1", protoMapMapUser);
+ }
+ }
+
+ public static class ProtoListListUser {
+ public List<ProtoListUser> value;
+
+ public void init() {
+ ProtoListUser protoListUser = new ProtoListUser();
+ protoListUser.init();
+ value = Arrays.asList(protoListUser);
+ }
+ }
+
+ public static class ProtoListMapUser {
+ public List<ProtoMapUser> value;
+
+ public void init() {
+ ProtoMapUser protoMapUser = new ProtoMapUser();
+ protoMapUser.init();
+ value = Arrays.asList(protoMapUser);
+ }
+ }
+
+ public static class ProtoMapListUser {
+ public Map<String, ProtoListUser> value;
+
+ public void init() {
+ ProtoListUser protoListUser = new ProtoListUser();
+ protoListUser.init();
+ value = Collections.singletonMap("k1", protoListUser);
+ }
+ }
+
+ public static class ProtoMapMapUser {
+ public Map<String, ProtoMapUser> value;
+
+ public void init() {
+ ProtoMapUser protoMapUser = new ProtoMapUser();
+ protoMapUser.init();
+ value = Collections.singletonMap("k1", protoMapUser);
+ }
+ }
+
+ public static class ProtoListUser {
+ public List<User> value;
+
+ public void init() {
+ value = Arrays.asList(user);
+ }
+ }
+
+ public static class ProtoMapUser {
+ public Map<String, User> value;
+
+ public void init() {
+ value = Collections.singletonMap(user.name, user);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void pojoModel() throws IOException {
+ RootSerializer pojoSerializer =
modelProtoMapper.findRootSerializer("PojoModel");
+ RootDeserializer pojoMapDeserializer =
modelProtoMapper.createRootDeserializer(Map.class, "PojoModel");
+ RootDeserializer pojoModelDeserializer =
modelProtoMapper.createRootDeserializer(PojoModel.class, "PojoModel");
+
+ RootSerializer protoSerializer =
modelProtoMapper.findRootSerializer("ProtoModel");
+ RootDeserializer protoMapDeserializer =
modelProtoMapper.createRootDeserializer(Map.class, "ProtoModel");
+ RootDeserializer protoModelDeserializer =
modelProtoMapper.createRootDeserializer(ProtoModel.class, "ProtoModel");
+
+ PojoModel pojoModel = new PojoModel();
+ pojoModel.init();
+ String jsonPojoModel = Json.encode(pojoModel);
+ Map<String, Object> mapFromPojoModel = (Map<String, Object>)
Json.decodeValue(jsonPojoModel, Map.class);
+
+ ProtoModel protoModel = new ProtoModel();
+ protoModel.init();
+ String jsonProtoModel = Json.encode(protoModel);
+ Map<String, Object> mapFromProtoModel = (Map<String, Object>)
Json.decodeValue(jsonProtoModel, Map.class);
+
+ // serialize
+ byte[] bytes = protoSerializer.serialize(protoModel);
+ Assert.assertArrayEquals(bytes,
protoSerializer.serialize(mapFromProtoModel));
+ Assert.assertArrayEquals(bytes, pojoSerializer.serialize(pojoModel));
+ Assert.assertArrayEquals(bytes,
pojoSerializer.serialize(mapFromPojoModel));
+
+ // deserialize pojoModel
+ PojoModel newPojoModel = pojoModelDeserializer.deserialize(bytes);
+ Assert.assertEquals(jsonPojoModel, Json.encode(newPojoModel));
+ Map<String, Object> mapFromNewPojoModel =
pojoMapDeserializer.deserialize(bytes);
+ Assert.assertEquals(jsonPojoModel, Json.encode(mapFromNewPojoModel));
+
+ // deserialize protoModel
+ ProtoModel newProtoModel = protoModelDeserializer.deserialize(bytes);
+ Assert.assertEquals(jsonProtoModel, Json.encode(newProtoModel));
+ Map<String, Object> mapFromNewProtoModel =
protoMapDeserializer.deserialize(bytes);
+ Assert.assertEquals(jsonProtoModel, Json.encode(mapFromNewProtoModel));
+ }
+}
diff --git a/foundations/foundation-protobuf/src/test/resources/model.proto
b/foundations/foundation-protobuf/src/test/resources/model.proto
new file mode 100644
index 000000000..c72ec7dd8
--- /dev/null
+++ b/foundations/foundation-protobuf/src/test/resources/model.proto
@@ -0,0 +1,108 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+syntax = "proto3";
+
+message PojoModel {
+ repeated PojoListUser listListUser = 1;
+ repeated PojoMapUser listMapUser = 2;
+ map<string, PojoListUser> mapListUser = 3;
+ map<string, PojoMapUser> mapMapUser = 4;
+
+ repeated PojoListListUser listListListUser = 5;
+ repeated PojoListMapUser listListMapUser = 6;
+ repeated PojoMapListUser listMapListUser = 7;
+ repeated PojoMapMapUser listMapMapUser = 8;
+ map<string, PojoListListUser> mapListListUser = 9;
+ map<string, PojoListMapUser> mapListMapUser = 10;
+ map<string, PojoMapListUser> mapMapListUser = 11;
+ map<string, PojoMapMapUser> mapMapMapUser = 12;
+}
+
+message ProtoModel {
+ repeated ProtoListUser listListUser = 1;
+ repeated ProtoMapUser listMapUser = 2;
+ map<string, ProtoListUser> mapListUser = 3;
+ map<string, ProtoMapUser> mapMapUser = 4;
+
+ repeated ProtoListListUser listListListUser = 5;
+ repeated ProtoListMapUser listListMapUser = 6;
+ repeated ProtoMapListUser listMapListUser = 7;
+ repeated ProtoMapMapUser listMapMapUser = 8;
+ map<string, ProtoListListUser> mapListListUser = 9;
+ map<string, ProtoListMapUser> mapListMapUser = 10;
+ map<string, ProtoMapListUser> mapMapListUser = 11;
+ map<string, ProtoMapMapUser> mapMapMapUser = 12;
+}
+
+//@WrapProperty
+message PojoListListUser {
+ repeated PojoListUser value = 1;
+}
+
+//@WrapProperty
+message PojoListMapUser {
+ repeated PojoMapUser value = 1;
+}
+
+//@WrapProperty
+message PojoMapListUser {
+ map<string, PojoListUser> value = 1;
+}
+
+//@WrapProperty
+message PojoMapMapUser {
+ map<string, PojoMapUser> value = 1;
+}
+
+//@WrapProperty
+message PojoListUser {
+ repeated User value = 1;
+}
+
+//@WrapProperty
+message PojoMapUser {
+ map<string, User> value = 1;
+}
+
+message User {
+ string name = 1;
+}
+
+message ProtoListListUser {
+ repeated ProtoListUser value = 1;
+}
+
+message ProtoListMapUser {
+ repeated ProtoMapUser value = 1;
+}
+
+message ProtoMapListUser {
+ map<string, ProtoListUser> value = 1;
+}
+
+message ProtoMapMapUser {
+ map<string, ProtoMapUser> value = 1;
+}
+
+message ProtoListUser {
+ repeated User value = 1;
+}
+
+message ProtoMapUser {
+ map<string, User> value = 1;
+}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> serialize/deseriaze List<List<X>>/List<Map<X, Y>>/Map<X, List<Y>>/Map<X,
> Map<Y, Z>>
> -----------------------------------------------------------------------------------
>
> Key: SCB-946
> URL: https://issues.apache.org/jira/browse/SCB-946
> Project: Apache ServiceComb
> Issue Type: Sub-task
> Components: Java-Chassis
> Reporter: wujimin
> Assignee: wujimin
> Priority: Major
> Fix For: java-chassis-1.2.0
>
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)