Skip to content

Commit 95e9034

Browse files
committed
Counter on duplicated event names
Signed-off-by: Sergio Mendoza <[email protected]>
1 parent 3814e43 commit 95e9034

File tree

2 files changed

+201
-10
lines changed

2 files changed

+201
-10
lines changed

codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,10 +418,22 @@ FieldSpec createBinaryDefinition(String binary) {
418418
.build();
419419
}
420420

421-
private FieldSpec createEventDefinition(String name, List<NamedTypeName> parameters) {
421+
private FieldSpec createEventDefinition(
422+
String name,
423+
List<NamedTypeName> parameters,
424+
Map<String, Integer> eventsCount,
425+
AbiDefinition event
426+
) {
422427

423428
CodeBlock initializer = buildVariableLengthEventInitializer(name, parameters);
424429

430+
Integer occurrences = eventsCount.get(name);
431+
if (occurrences > 1) {
432+
event.setName(name + (occurrences - 1));
433+
eventsCount.replace(name, occurrences - 1);
434+
name = event.getName();
435+
}
436+
425437
return FieldSpec.builder(Event.class, buildEventDefinitionName(name))
426438
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
427439
.initializer(initializer)
@@ -432,26 +444,50 @@ private String buildEventDefinitionName(String eventName) {
432444
return eventName.toUpperCase() + "_EVENT";
433445
}
434446

435-
private List<MethodSpec> buildFunctionDefinitions(
447+
List<MethodSpec> buildFunctionDefinitions(
436448
String className,
437449
TypeSpec.Builder classBuilder,
438450
List<AbiDefinition> functionDefinitions)
439451
throws ClassNotFoundException {
440452

441453
Set<String> duplicateFunctionNames = getDuplicateFunctionNames(functionDefinitions);
454+
Map<String, Integer> eventsCount = getDuplicatedEventNames(functionDefinitions);
442455
List<MethodSpec> methodSpecs = new ArrayList<>();
443456
for (AbiDefinition functionDefinition : functionDefinitions) {
444457
if (functionDefinition.getType().equals(TYPE_FUNCTION)) {
445458
String functionName = funcNameToConst(functionDefinition.getName(), true);
446459
boolean useUpperCase = !duplicateFunctionNames.contains(functionName);
447460
methodSpecs.addAll(buildFunctions(functionDefinition, useUpperCase));
448461
} else if (functionDefinition.getType().equals(TYPE_EVENT)) {
449-
methodSpecs.addAll(buildEventFunctions(functionDefinition, classBuilder));
462+
methodSpecs.addAll(
463+
buildEventFunctions(functionDefinition, classBuilder, eventsCount)
464+
);
450465
}
451466
}
452467
return methodSpecs;
453468
}
454469

470+
Map<String, Integer> getDuplicatedEventNames(List<AbiDefinition> functionDefinitions) {
471+
Map<String, Integer> countMap = new HashMap<>();
472+
473+
functionDefinitions.stream()
474+
.filter(
475+
function ->
476+
TYPE_EVENT.equals(function.getType()) && function.getName() != null)
477+
.forEach(
478+
function -> {
479+
String functionName = function.getName();
480+
if (countMap.containsKey(functionName)) {
481+
int count = countMap.get(functionName);
482+
countMap.put(functionName, count + 1);
483+
} else {
484+
countMap.put(functionName, 1);
485+
}
486+
});
487+
488+
return countMap;
489+
}
490+
455491
private List<TypeSpec> buildStructTypes(final List<AbiDefinition> functionDefinitions)
456492
throws ClassNotFoundException {
457493
final List<AbiDefinition.NamedType> orderedKeys = extractStructs(functionDefinitions);
@@ -1917,11 +1953,12 @@ private static String getEventFromLogFunctionName(String functionName) {
19171953
}
19181954

19191955
List<MethodSpec> buildEventFunctions(
1920-
AbiDefinition functionDefinition, TypeSpec.Builder classBuilder)
1956+
AbiDefinition functionDefinition,
1957+
TypeSpec.Builder classBuilder,
1958+
Map<String, Integer> eventsCount
1959+
)
19211960
throws ClassNotFoundException {
1922-
String functionName = functionDefinition.getName();
19231961
List<AbiDefinition.NamedType> inputs = functionDefinition.getInputs();
1924-
String responseClassName = Strings.capitaliseFirstLetter(functionName) + "EventResponse";
19251962

19261963
List<NamedTypeName> parameters = new ArrayList<>();
19271964
List<NamedTypeName> indexedParameters = new ArrayList<>();
@@ -1946,7 +1983,15 @@ List<MethodSpec> buildEventFunctions(
19461983
parameters.add(parameter);
19471984
}
19481985

1949-
classBuilder.addField(createEventDefinition(functionName, parameters));
1986+
String functionName = functionDefinition.getName();
1987+
1988+
classBuilder.addField(createEventDefinition(
1989+
functionName, parameters, eventsCount, functionDefinition
1990+
));
1991+
1992+
functionName = functionDefinition.getName();
1993+
1994+
String responseClassName = Strings.capitaliseFirstLetter(functionName) + "EventResponse";
19501995

19511996
classBuilder.addType(
19521997
buildEventResponseObject(

codegen/src/test/java/org/web3j/codegen/SolidityFunctionWrapperTest.java

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,11 @@ public void testBuildEventConstantMultipleValueReturn() throws Exception {
685685
TypeSpec.Builder builder = TypeSpec.classBuilder("testClass");
686686

687687
builder.addMethods(
688-
solidityFunctionWrapper.buildEventFunctions(functionDefinition, builder));
688+
solidityFunctionWrapper.buildEventFunctions(
689+
functionDefinition,
690+
builder,
691+
solidityFunctionWrapper.getDuplicatedEventNames(
692+
Collections.singletonList(functionDefinition))));
689693

690694
String expected =
691695
"class testClass {\n"
@@ -773,7 +777,11 @@ public void testBuildEventWithNamedAndNoNamedParameters() throws Exception {
773777
TypeSpec.Builder builder = TypeSpec.classBuilder("testClass");
774778

775779
builder.addMethods(
776-
solidityFunctionWrapper.buildEventFunctions(functionDefinition, builder));
780+
solidityFunctionWrapper.buildEventFunctions(
781+
functionDefinition,
782+
builder,
783+
solidityFunctionWrapper.getDuplicatedEventNames(
784+
Collections.singletonList(functionDefinition))));
777785

778786
String expected =
779787
"class testClass {\n"
@@ -853,7 +861,11 @@ public void testBuildEventWithNativeList() throws Exception {
853861
TypeSpec.Builder builder = TypeSpec.classBuilder("testClass");
854862

855863
builder.addMethods(
856-
solidityFunctionWrapper.buildEventFunctions(functionDefinition, builder));
864+
solidityFunctionWrapper.buildEventFunctions(
865+
functionDefinition,
866+
builder,
867+
solidityFunctionWrapper.getDuplicatedEventNames(
868+
Collections.singletonList(functionDefinition))));
857869

858870
String expected =
859871
"class testClass {\n"
@@ -926,6 +938,140 @@ public void testBuildFuncNameConstants() throws Exception {
926938
assertEquals(builder.build().toString(), (expected));
927939
}
928940

941+
@Test
942+
public void testBuildFunctionDuplicatedEventNames() throws Exception {
943+
AbiDefinition firstEventDefinition =
944+
new AbiDefinition(
945+
false,
946+
Arrays.asList(
947+
new NamedType("action", "string", false),
948+
new NamedType("pauseState", "bool", false)),
949+
"eventName",
950+
Collections.emptyList(),
951+
"event",
952+
false);
953+
AbiDefinition secondEventDefinition =
954+
new AbiDefinition(
955+
false,
956+
Arrays.asList(
957+
new NamedType("cToken", "address", false),
958+
new NamedType("action", "string", false),
959+
new NamedType("pauseState", "bool", false)),
960+
"eventName",
961+
Collections.emptyList(),
962+
"event",
963+
false);
964+
TypeSpec.Builder builder = TypeSpec.classBuilder("testClass");
965+
builder.addMethods(
966+
solidityFunctionWrapper.buildFunctionDefinitions(
967+
"testClass",
968+
builder,
969+
Arrays.asList(firstEventDefinition, secondEventDefinition)));
970+
971+
String expected =
972+
"class testClass {\n" +
973+
" public static final org.web3j.abi.datatypes.Event EVENTNAME1_EVENT = new org.web3j.abi.datatypes.Event(\"eventName\", \n" +
974+
" java.util.Arrays.<org.web3j.abi.TypeReference<?>>asList(new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.Utf8String>() {}, new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.Bool>() {}));\n" +
975+
" ;\n" +
976+
"\n" +
977+
" public static final org.web3j.abi.datatypes.Event EVENTNAME_EVENT = new org.web3j.abi.datatypes.Event(\"eventName\", \n" +
978+
" java.util.Arrays.<org.web3j.abi.TypeReference<?>>asList(new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.Address>() {}, new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.Utf8String>() {}, new org.web3j.abi.TypeReference<org.web3j.abi.datatypes.Bool>() {}));\n" +
979+
" ;\n" +
980+
"\n" +
981+
" public static java.util.List<EventName1EventResponse> getEventName1Events(\n" +
982+
" org.web3j.protocol.core.methods.response.TransactionReceipt transactionReceipt) {\n" +
983+
" java.util.List<org.web3j.tx.Contract.EventValuesWithLog> valueList = staticExtractEventParametersWithLog(EVENTNAME1_EVENT, transactionReceipt);\n" +
984+
" java.util.ArrayList<EventName1EventResponse> responses = new java.util.ArrayList<EventName1EventResponse>(valueList.size());\n" +
985+
" for (org.web3j.tx.Contract.EventValuesWithLog eventValues : valueList) {\n" +
986+
" EventName1EventResponse typedResponse = new EventName1EventResponse();\n" +
987+
" typedResponse.log = eventValues.getLog();\n" +
988+
" typedResponse.action = (java.lang.String) eventValues.getNonIndexedValues().get(0).getValue();\n" +
989+
" typedResponse.pauseState = (java.lang.Boolean) eventValues.getNonIndexedValues().get(1).getValue();\n" +
990+
" responses.add(typedResponse);\n" +
991+
" }\n" +
992+
" return responses;\n" +
993+
" }\n" +
994+
"\n" +
995+
" public static EventName1EventResponse getEventName1EventFromLog(\n" +
996+
" org.web3j.protocol.core.methods.response.Log log) {\n" +
997+
" org.web3j.tx.Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(EVENTNAME1_EVENT, log);\n" +
998+
" EventName1EventResponse typedResponse = new EventName1EventResponse();\n" +
999+
" typedResponse.log = log;\n" +
1000+
" typedResponse.action = (java.lang.String) eventValues.getNonIndexedValues().get(0).getValue();\n" +
1001+
" typedResponse.pauseState = (java.lang.Boolean) eventValues.getNonIndexedValues().get(1).getValue();\n" +
1002+
" return typedResponse;\n" +
1003+
" }\n" +
1004+
"\n" +
1005+
" public io.reactivex.Flowable<EventName1EventResponse> eventName1EventFlowable(\n" +
1006+
" org.web3j.protocol.core.methods.request.EthFilter filter) {\n" +
1007+
" return web3j.ethLogFlowable(filter).map(log -> getEventName1EventFromLog(log));\n" +
1008+
" }\n" +
1009+
"\n" +
1010+
" public io.reactivex.Flowable<EventName1EventResponse> eventName1EventFlowable(\n" +
1011+
" org.web3j.protocol.core.DefaultBlockParameter startBlock,\n" +
1012+
" org.web3j.protocol.core.DefaultBlockParameter endBlock) {\n" +
1013+
" org.web3j.protocol.core.methods.request.EthFilter filter = new org.web3j.protocol.core.methods.request.EthFilter(startBlock, endBlock, getContractAddress());\n" +
1014+
" filter.addSingleTopic(org.web3j.abi.EventEncoder.encode(EVENTNAME1_EVENT));\n" +
1015+
" return eventName1EventFlowable(filter);\n" +
1016+
" }\n" +
1017+
"\n" +
1018+
" public static java.util.List<EventNameEventResponse> getEventNameEvents(\n" +
1019+
" org.web3j.protocol.core.methods.response.TransactionReceipt transactionReceipt) {\n" +
1020+
" java.util.List<org.web3j.tx.Contract.EventValuesWithLog> valueList = staticExtractEventParametersWithLog(EVENTNAME_EVENT, transactionReceipt);\n" +
1021+
" java.util.ArrayList<EventNameEventResponse> responses = new java.util.ArrayList<EventNameEventResponse>(valueList.size());\n" +
1022+
" for (org.web3j.tx.Contract.EventValuesWithLog eventValues : valueList) {\n" +
1023+
" EventNameEventResponse typedResponse = new EventNameEventResponse();\n" +
1024+
" typedResponse.log = eventValues.getLog();\n" +
1025+
" typedResponse.cToken = (java.lang.String) eventValues.getNonIndexedValues().get(0).getValue();\n" +
1026+
" typedResponse.action = (java.lang.String) eventValues.getNonIndexedValues().get(1).getValue();\n" +
1027+
" typedResponse.pauseState = (java.lang.Boolean) eventValues.getNonIndexedValues().get(2).getValue();\n" +
1028+
" responses.add(typedResponse);\n" +
1029+
" }\n" +
1030+
" return responses;\n" +
1031+
" }\n" +
1032+
"\n" +
1033+
" public static EventNameEventResponse getEventNameEventFromLog(\n" +
1034+
" org.web3j.protocol.core.methods.response.Log log) {\n" +
1035+
" org.web3j.tx.Contract.EventValuesWithLog eventValues = staticExtractEventParametersWithLog(EVENTNAME_EVENT, log);\n" +
1036+
" EventNameEventResponse typedResponse = new EventNameEventResponse();\n" +
1037+
" typedResponse.log = log;\n" +
1038+
" typedResponse.cToken = (java.lang.String) eventValues.getNonIndexedValues().get(0).getValue();\n" +
1039+
" typedResponse.action = (java.lang.String) eventValues.getNonIndexedValues().get(1).getValue();\n" +
1040+
" typedResponse.pauseState = (java.lang.Boolean) eventValues.getNonIndexedValues().get(2).getValue();\n" +
1041+
" return typedResponse;\n" +
1042+
" }\n" +
1043+
"\n" +
1044+
" public io.reactivex.Flowable<EventNameEventResponse> eventNameEventFlowable(\n" +
1045+
" org.web3j.protocol.core.methods.request.EthFilter filter) {\n" +
1046+
" return web3j.ethLogFlowable(filter).map(log -> getEventNameEventFromLog(log));\n" +
1047+
" }\n" +
1048+
"\n" +
1049+
" public io.reactivex.Flowable<EventNameEventResponse> eventNameEventFlowable(\n" +
1050+
" org.web3j.protocol.core.DefaultBlockParameter startBlock,\n" +
1051+
" org.web3j.protocol.core.DefaultBlockParameter endBlock) {\n" +
1052+
" org.web3j.protocol.core.methods.request.EthFilter filter = new org.web3j.protocol.core.methods.request.EthFilter(startBlock, endBlock, getContractAddress());\n" +
1053+
" filter.addSingleTopic(org.web3j.abi.EventEncoder.encode(EVENTNAME_EVENT));\n" +
1054+
" return eventNameEventFlowable(filter);\n" +
1055+
" }\n" +
1056+
"\n" +
1057+
" public static class EventName1EventResponse extends org.web3j.protocol.core.methods.response.BaseEventResponse {\n" +
1058+
" public java.lang.String action;\n" +
1059+
"\n" +
1060+
" public java.lang.Boolean pauseState;\n" +
1061+
" }\n" +
1062+
"\n" +
1063+
" public static class EventNameEventResponse extends org.web3j.protocol.core.methods.response.BaseEventResponse {\n" +
1064+
" public java.lang.String cToken;\n" +
1065+
"\n" +
1066+
" public java.lang.String action;\n" +
1067+
"\n" +
1068+
" public java.lang.Boolean pauseState;\n" +
1069+
" }\n" +
1070+
"}\n";
1071+
1072+
assertEquals(builder.build().toString(), (expected));
1073+
}
1074+
9291075
@Test
9301076
public void testBuildFunctionTransactionAndCall() throws Exception {
9311077
AbiDefinition functionDefinition =

0 commit comments

Comments
 (0)