Skip to content

Commit de907f0

Browse files
committed
Add equals and hashCode to generate classes
Fixes #377 (cherry picked from commit 22ca4c8)
1 parent 6fecb1c commit de907f0

File tree

3 files changed

+185
-1
lines changed

3 files changed

+185
-1
lines changed

codegen.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ def printGetter(fieldType, fieldName):
368368
print(" public int getClassId() { return %i; }" % (c.index))
369369
print(" public String getClassName() { return \"%s\"; }" % (c.name))
370370

371+
if c.fields:
372+
equalsHashCode(spec, c.fields, java_class_name(c.name), 'Properties', False)
373+
371374
printPropertiesBuilder(c)
372375

373376
#accessor methods
@@ -400,6 +403,49 @@ def printPropertiesClasses():
400403

401404
#--------------------------------------------------------------------------------
402405

406+
def equalsHashCode(spec, fields, jClassName, classSuffix, usePrimitiveType):
407+
print()
408+
print()
409+
print(" @Override")
410+
print(" public boolean equals(Object o) {")
411+
print(" if (this == o)")
412+
print(" return true;")
413+
print(" if (o == null || getClass() != o.getClass())")
414+
print(" return false;")
415+
print(" %s%s that = (%s%s) o;" % (jClassName, classSuffix, jClassName, classSuffix))
416+
417+
for f in fields:
418+
(fType, fName) = (java_field_type(spec, f.domain), java_field_name(f.name))
419+
if usePrimitiveType and fType in javaScalarTypes:
420+
print(" if (%s != that.%s)" % (fName, fName))
421+
else:
422+
print(" if (%s != null ? !%s.equals(that.%s) : that.%s != null)" % (fName, fName, fName, fName))
423+
424+
print(" return false;")
425+
426+
print(" return true;")
427+
print(" }")
428+
429+
print()
430+
print(" @Override")
431+
print(" public int hashCode() {")
432+
print(" int result = 0;")
433+
434+
for f in fields:
435+
(fType, fName) = (java_field_type(spec, f.domain), java_field_name(f.name))
436+
if usePrimitiveType and fType in javaScalarTypes:
437+
if fType == 'boolean':
438+
print(" result = 31 * result + (%s ? 1 : 0);" % fName)
439+
elif fType == 'long':
440+
print(" result = 31 * result + (int) (%s ^ (%s >>> 32));" % (fName, fName))
441+
else:
442+
print(" result = 31 * result + %s;" % fName)
443+
else:
444+
print(" result = 31 * result + (%s != null ? %s.hashCode() : 0);" % (fName, fName))
445+
446+
print(" return result;")
447+
print(" }")
448+
403449
def genJavaImpl(spec):
404450
def printHeader():
405451
printFileHeader()
@@ -503,6 +549,8 @@ def write_arguments():
503549
getters()
504550
constructors()
505551
others()
552+
if m.arguments:
553+
equalsHashCode(spec, m.arguments, java_class_name(m.name), '', True)
506554

507555
argument_debug_string()
508556
write_arguments()

src/test/java/com/rabbitmq/client/test/ClientTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
JacksonJsonRpcTest.class,
6767
AddressTest.class,
6868
DefaultRetryHandlerTest.class,
69-
NioDeadlockOnConnectionClosing.class
69+
NioDeadlockOnConnectionClosing.class,
70+
GeneratedClassesTest.class
7071
})
7172
public class ClientTests {
7273

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright (c) 2018 Pivotal Software, Inc. All rights reserved.
2+
//
3+
// This software, the RabbitMQ Java client library, is triple-licensed under the
4+
// Mozilla Public License 1.1 ("MPL"), the GNU General Public License version 2
5+
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
6+
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL,
7+
// please see LICENSE-APACHE2.
8+
//
9+
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
10+
// either express or implied. See the LICENSE file for specific language governing
11+
// rights and limitations of this software.
12+
//
13+
// If you have any questions regarding licensing, please contact us at
14+
15+
16+
package com.rabbitmq.client.test;
17+
18+
import com.rabbitmq.client.AMQP;
19+
import com.rabbitmq.client.impl.AMQImpl;
20+
import org.junit.Test;
21+
22+
import java.util.Calendar;
23+
import java.util.Date;
24+
25+
import static java.util.Collections.singletonMap;
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertNotEquals;
28+
29+
/**
30+
*
31+
*/
32+
public class GeneratedClassesTest {
33+
34+
@Test
35+
public void amqpPropertiesEqualsHashCode() {
36+
checkEquals(
37+
new AMQP.BasicProperties.Builder().correlationId("one").build(),
38+
new AMQP.BasicProperties.Builder().correlationId("one").build()
39+
);
40+
checkNotEquals(
41+
new AMQP.BasicProperties.Builder().correlationId("one").build(),
42+
new AMQP.BasicProperties.Builder().correlationId("two").build()
43+
);
44+
Date date = Calendar.getInstance().getTime();
45+
checkEquals(
46+
new AMQP.BasicProperties.Builder()
47+
.deliveryMode(1)
48+
.headers(singletonMap("one", "two"))
49+
.correlationId("123")
50+
.expiration("later")
51+
.priority(10)
52+
.replyTo("me")
53+
.contentType("text/plain")
54+
.contentEncoding("UTF-8")
55+
.userId("jdoe")
56+
.appId("app1")
57+
.clusterId("cluster1")
58+
.messageId("message123")
59+
.timestamp(date)
60+
.type("type")
61+
.build(),
62+
new AMQP.BasicProperties.Builder()
63+
.deliveryMode(1)
64+
.headers(singletonMap("one", "two"))
65+
.correlationId("123")
66+
.expiration("later")
67+
.priority(10)
68+
.replyTo("me")
69+
.contentType("text/plain")
70+
.contentEncoding("UTF-8")
71+
.userId("jdoe")
72+
.appId("app1")
73+
.clusterId("cluster1")
74+
.messageId("message123")
75+
.timestamp(date)
76+
.type("type")
77+
.build()
78+
);
79+
checkNotEquals(
80+
new AMQP.BasicProperties.Builder()
81+
.deliveryMode(1)
82+
.headers(singletonMap("one", "two"))
83+
.correlationId("123")
84+
.expiration("later")
85+
.priority(10)
86+
.replyTo("me")
87+
.contentType("text/plain")
88+
.contentEncoding("UTF-8")
89+
.userId("jdoe")
90+
.appId("app1")
91+
.clusterId("cluster1")
92+
.messageId("message123")
93+
.timestamp(date)
94+
.type("type")
95+
.build(),
96+
new AMQP.BasicProperties.Builder()
97+
.deliveryMode(2)
98+
.headers(singletonMap("one", "two"))
99+
.correlationId("123")
100+
.expiration("later")
101+
.priority(10)
102+
.replyTo("me")
103+
.contentType("text/plain")
104+
.contentEncoding("UTF-8")
105+
.userId("jdoe")
106+
.appId("app1")
107+
.clusterId("cluster1")
108+
.messageId("message123")
109+
.timestamp(date)
110+
.type("type")
111+
.build()
112+
);
113+
114+
}
115+
116+
@Test public void amqImplEqualsHashCode() {
117+
checkEquals(
118+
new AMQImpl.Basic.Deliver("tag", 1L, false, "amq.direct","rk"),
119+
new AMQImpl.Basic.Deliver("tag", 1L, false, "amq.direct","rk")
120+
);
121+
checkNotEquals(
122+
new AMQImpl.Basic.Deliver("tag", 1L, false, "amq.direct","rk"),
123+
new AMQImpl.Basic.Deliver("tag", 2L, false, "amq.direct","rk")
124+
);
125+
}
126+
127+
private void checkEquals(Object o1, Object o2) {
128+
assertEquals(o1, o2);
129+
assertEquals(o1.hashCode(), o2.hashCode());
130+
}
131+
132+
private void checkNotEquals(Object o1, Object o2) {
133+
assertNotEquals(o1, o2);
134+
}
135+
}

0 commit comments

Comments
 (0)