Skip to content

Commit

Permalink
Merge pull request rgushel#8 from ppoffice/protobuf-converter
Browse files Browse the repository at this point in the history
Fix two parsing problems
  • Loading branch information
jsjem authored Nov 22, 2017
2 parents c0aa141 + 1a4baef commit e9ec547
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,40 @@ public <T extends Message> MappingResult mapToDomainField(final FieldResolver fi
final Object domain) throws MappingException {
Object protobufFieldValue = getFieldValue(FieldUtils.createProtobufGetterName(fieldResolver), protobuf);
if (FieldUtils.isComplexType(fieldResolver.getField())) {
return new MappingResult(MappingResult.Result.NESTED_MAPPING, protobufFieldValue, domain);
boolean hasFieldValue = true;
try {
String hasserName = FieldUtils.createProtobufHasserName(fieldResolver);
if (hasserName != null) {
hasFieldValue = hasFieldValue(hasserName, protobuf);
}
} catch (MappingException ignored) {} // not `has` method, continue
if (hasFieldValue) {
return new MappingResult(MappingResult.Result.NESTED_MAPPING, protobufFieldValue, domain);
}
return new MappingResult(MappingResult.Result.MAPPED, null, domain);
}
if (FieldUtils.isCollectionType(fieldResolver.getField())) {
return new MappingResult(MappingResult.Result.COLLECTION_MAPPING, protobufFieldValue, domain);
}
return new MappingResult(MappingResult.Result.MAPPED, protobufFieldValue, domain);
}

private boolean hasFieldValue(final String hasserName, final Object source) throws MappingException {
Class<?> sourceClass = source.getClass();
try {
return (boolean) sourceClass.getMethod(hasserName).invoke(source);
} catch (IllegalAccessException e) {
throw new MappingException(
String.format("Access denied. '%s.%s()'", sourceClass.getName(), hasserName));
} catch (InvocationTargetException e) {
throw new MappingException(
String.format("Can't decide if field has value through '%s.%s()'", sourceClass.getName(), hasserName));
} catch (NoSuchMethodException e) {
throw new MappingException(
String.format("Hasser not found. '%s.%s()'", sourceClass.getName(), hasserName));
}
}

private Object getFieldValue(final String getterName, final Object source) throws MappingException {
Class<?> sourceClass = source.getClass();
try {
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/net/badata/protobuf/converter/utils/FieldUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/
public final class FieldUtils {

private static final String HASSER_PREFIX = "has";
private static final String GETTER_PREFIX = "get";
private static final String SETTER_PREFIX = "set";
private static final String BOOLEAN_GETTER_PREFIX = "is";
Expand Down Expand Up @@ -80,6 +81,19 @@ public static boolean isCollectionType(final Class<?> type) {
return Collection.class.isAssignableFrom(type);
}

/**
* Create protobuf getter name for domain field.
*
* @param fieldResolver Domain object field resolver.
* @return Protobuf field getter name.
*/
public static String createProtobufHasserName(final FieldResolver fieldResolver) {
if (isCollectionType(fieldResolver.getProtobufType())) {
return null;
}
return StringUtils.createMethodName(HASSER_PREFIX, fieldResolver.getProtobufName());
}

/**
* Create protobuf getter name for domain field.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,26 @@ protected void write(final Object destination, final FieldResolver fieldResolver


private void writeValue(final Object destination, final FieldResolver fieldResolver, final Object value) throws WriteException {
String setterName = FieldUtils.createProtobufSetterName(fieldResolver);
try {
destinationClass.getMethod(setterName, extractValueClass(value)).invoke(destination, value);
} catch (IllegalAccessException e) {
throw new WriteException(
String.format("Access denied. '%s.%s()'", destinationClass.getName(), setterName));
} catch (InvocationTargetException e) {
throw new WriteException(
String.format("Can't set field value through '%s.%s()'", destinationClass.getName(), setterName));
} catch (NoSuchMethodException e) {
throw new WriteException(
String.format("Setter not found: '%s.%s()'", destinationClass.getName(), setterName));
Class<?> valueClass = extractValueClass(value);
while (valueClass != null) {
String setterName = FieldUtils.createProtobufSetterName(fieldResolver);
try {
destinationClass.getMethod(setterName, valueClass).invoke(destination, value);
break;
} catch (IllegalAccessException e) {
throw new WriteException(
String.format("Access denied. '%s.%s(%s)'", destinationClass.getName(), setterName, valueClass));
} catch (InvocationTargetException e) {
throw new WriteException(
String.format("Can't set field value through '%s.%s(%s)'", destinationClass.getName(), setterName, valueClass));
} catch (NoSuchMethodException e) {
if (valueClass.getSuperclass() != null) {
valueClass = valueClass.getSuperclass();
} else {
throw new WriteException(
String.format("Setter not found: '%s.%s(%s)'", destinationClass.getName(), setterName, valueClass));
}
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/test/java/net/badata/protobuf/converter/ConverterTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.badata.protobuf.converter;

import com.google.protobuf.ByteString;
import net.badata.protobuf.converter.domain.ConverterDomain;
import net.badata.protobuf.converter.proto.ConverterProto;
import org.junit.Assert;
Expand Down Expand Up @@ -55,6 +56,8 @@ private void createTestProtobuf() {
.addStringListValue("10")
.addComplexListValue(ConverterProto.PrimitiveTest.newBuilder().setIntValue(1001))
.addComplexSetValue(ConverterProto.PrimitiveTest.newBuilder().setIntValue(1002))
.setBytesValue(ByteString.copyFrom(new byte[]{ 0, 1, 3, 7 }))
.setRecursiveValue(ConverterProto.ConverterTest.newBuilder().setIntValue(1))
.build();
}

Expand Down Expand Up @@ -91,6 +94,12 @@ private void createTestDomain() {
primitiveTestItem.setIntValue(-1002);
testDomain.setComplexSetValue(new HashSet<ConverterDomain.PrimitiveTest>(Arrays.asList(primitiveTestSItem)));
testDomain.setComplexNullableCollectionValue(null);

testDomain.setBytesValue(ByteString.copyFrom(new byte[]{ 0, 1, 3, 7 }));

ConverterDomain.Test nestedValue = new ConverterDomain.Test();
nestedValue.setIntValue(1);
testDomain.setRecursiveValue(nestedValue);
}

private void createIgnoredFieldsMap() {
Expand Down Expand Up @@ -146,6 +155,9 @@ public void testProtobufToDomain() {
result.getComplexSetValue().iterator().next().getIntValue());

Assert.assertTrue(result.getComplexNullableCollectionValue().isEmpty());

Assert.assertEquals(testProtobuf.getBytesValue(), result.getBytesValue());
Assert.assertEquals((Object) testProtobuf.getRecursiveValue().getIntValue(), result.getRecursiveValue().getIntValue());
}

@Test
Expand Down Expand Up @@ -202,6 +214,7 @@ public void testDomainToProtobuf() {
result.getComplexSetValue(0).getIntValue());

Assert.assertTrue(result.getComplexNullableCollectionValueList().isEmpty());
Assert.assertEquals((Object) testDomain.getRecursiveValue().getIntValue(), result.getRecursiveValue().getIntValue());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.badata.protobuf.converter.domain;

import com.google.protobuf.ByteString;
import com.google.protobuf.Message;
import net.badata.protobuf.converter.annotation.ProtoClass;
import net.badata.protobuf.converter.annotation.ProtoField;
Expand Down Expand Up @@ -55,6 +56,10 @@ public static class Test {
private Set<PrimitiveTest> complexSetValue;
@ProtoField
private List<PrimitiveTest> complexNullableCollectionValue;
@ProtoField
private ByteString bytesValue;
@ProtoField
private Test recursiveValue;


public Long getLongValue() {
Expand Down Expand Up @@ -161,6 +166,22 @@ public List<PrimitiveTest> getComplexNullableCollectionValue() {
public void setComplexNullableCollectionValue(final List<PrimitiveTest> complexNullableCollectionValue) {
this.complexNullableCollectionValue = complexNullableCollectionValue;
}

public ByteString getBytesValue() {
return bytesValue;
}

public void setBytesValue(ByteString bytesValue) {
this.bytesValue = bytesValue;
}

public Test getRecursiveValue() {
return recursiveValue;
}

public void setRecursiveValue(Test recursiveValue) {
this.recursiveValue = recursiveValue;
}
}

@ProtoClass(ConverterProto.PrimitiveTest.class)
Expand Down
Loading

0 comments on commit e9ec547

Please sign in to comment.