From aeb6f86bcdec061ee9c6be96066fa19c56523490 Mon Sep 17 00:00:00 2001 From: Felipe Adorno Date: Sun, 3 May 2015 15:59:00 -0300 Subject: [PATCH 1/3] EqualsExlcude notation, HashCodeExclude notation and ToStringExludeNotation --- .../commons/lang3/builder/EqualsBuilder.java | 3 +- .../commons/lang3/builder/EqualsExclude.java | 33 ++++++++++ .../lang3/builder/HashCodeBuilder.java | 3 +- .../lang3/builder/HashCodeExclude.java | 33 ++++++++++ .../builder/ReflectionToStringBuilder.java | 3 + .../lang3/builder/ToStringExclude.java | 33 ++++++++++ .../lang3/builder/EqualsBuilderTest.java | 32 ++++++++++ .../lang3/builder/HashCodeBuilderTest.java | 47 ++++++++++++++ ...tringBuilderExcludeWithAnnotationTest.java | 63 +++++++++++++++++++ 9 files changed, 248 insertions(+), 2 deletions(-) create mode 100755 src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java create mode 100755 src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java create mode 100755 src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java create mode 100755 src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java diff --git a/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java b/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java index b44976632..be8f4f1ce 100644 --- a/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java @@ -411,7 +411,8 @@ public class EqualsBuilder implements Builder { if (!ArrayUtils.contains(excludeFields, f.getName()) && !f.getName().contains("$") && (useTransients || !Modifier.isTransient(f.getModifiers())) - && !Modifier.isStatic(f.getModifiers())) { + && (!Modifier.isStatic(f.getModifiers())) + && (!f.isAnnotationPresent(EqualsExclude.class))) { try { builder.append(f.get(lhs), f.get(rhs)); } catch (final IllegalAccessException e) { diff --git a/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java b/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java new file mode 100755 index 000000000..bbe2bb01b --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java @@ -0,0 +1,33 @@ +/* + * 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.commons.lang3.builder; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Use this annotation to builds a equals excluding the annotated field. + * @author Felipe Adorno (felipeadsc@gmail.com) + */ +@Retention(RUNTIME) +@Target(ElementType.FIELD) +public @interface EqualsExclude { + +} diff --git a/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java b/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java index 537b9f579..fbbd110a6 100644 --- a/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java @@ -192,7 +192,8 @@ public class HashCodeBuilder implements Builder { if (!ArrayUtils.contains(excludeFields, field.getName()) && !field.getName().contains("$") && (useTransients || !Modifier.isTransient(field.getModifiers())) - && !Modifier.isStatic(field.getModifiers())) { + && (!Modifier.isStatic(field.getModifiers())) + && (!field.isAnnotationPresent(HashCodeExclude.class))) { try { final Object fieldValue = field.get(object); builder.append(fieldValue); diff --git a/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java b/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java new file mode 100755 index 000000000..2984808bb --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java @@ -0,0 +1,33 @@ +/* + * 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.commons.lang3.builder; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Use this annotation to builds a hash code excluding the annotated field. + * @author Felipe Adorno (felipeadsc@gmail.com) + */ +@Retention(RUNTIME) +@Target(ElementType.FIELD) +public @interface HashCodeExclude { + +} diff --git a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java index 5b992bd53..59044699e 100644 --- a/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/ReflectionToStringBuilder.java @@ -494,6 +494,9 @@ public class ReflectionToStringBuilder extends ToStringBuilder { // Reject fields from the getExcludeFieldNames list. return false; } + if(field.isAnnotationPresent(ToStringExclude.class)) { + return false; + } return true; } diff --git a/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java b/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java new file mode 100755 index 000000000..b0bf98a56 --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java @@ -0,0 +1,33 @@ +/* + * 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.commons.lang3.builder; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Use this annotation to builds a String excluding the annotated field. + * @author Felipe Adorno (felipeadsc@gmail.com) + */ +@Retention(RUNTIME) +@Target(ElementType.FIELD) +public @interface ToStringExclude { + +} diff --git a/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java index 30e2e22f3..702c5a2c8 100644 --- a/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java @@ -1150,5 +1150,37 @@ public class EqualsBuilderTest { assertTrue(EqualsBuilder.reflectionEquals(d1, d3)); } + static class TestObjectEqualsExclude { + @EqualsExclude + private int a; + private int b; + + public TestObjectEqualsExclude(int a, int b) { + this.a = a; + this.b = b; + } + + public int getA() { + return a; + } + + public int getB() { + return b; + } + } + + @Test + public void testToEqualsExclude() { + TestObjectEqualsExclude one = new TestObjectEqualsExclude(1, 2); + TestObjectEqualsExclude two = new TestObjectEqualsExclude(1, 3); + + assertFalse(EqualsBuilder.reflectionEquals(one, two)); + + one = new TestObjectEqualsExclude(1, 2); + two = new TestObjectEqualsExclude(2, 2); + + assertTrue(EqualsBuilder.reflectionEquals(one, two)); + } + } diff --git a/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java index 12aba9ee3..9009fbde4 100644 --- a/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java @@ -622,4 +622,51 @@ public class HashCodeBuilderTest { hcb.toHashCode(), hcb.hashCode()); } + static class TestObjectHashCodeExclude { + @HashCodeExclude + private int a; + private int b; + + public TestObjectHashCodeExclude(int a, int b) { + this.a = a; + this.b = b; + } + + public int getA() { + return a; + } + + public int getB() { + return b; + } + } + + static class TestObjectHashCodeExclude2 { + @HashCodeExclude + private int a; + @HashCodeExclude + private int b; + + public TestObjectHashCodeExclude2(int a, int b) { + this.a = a; + this.b = b; + } + + public int getA() { + return a; + } + + public int getB() { + return b; + } + } + + @Test + public void testToHashCodeExclude() { + TestObjectHashCodeExclude one = new TestObjectHashCodeExclude(1, 2); + TestObjectHashCodeExclude2 two = new TestObjectHashCodeExclude2(1, 2); + assertEquals(17 * 37 + 2, HashCodeBuilder.reflectionHashCode(one)); + assertEquals(17, HashCodeBuilder.reflectionHashCode(two)); + } + } diff --git a/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java b/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java new file mode 100755 index 000000000..c01d3b814 --- /dev/null +++ b/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java @@ -0,0 +1,63 @@ +/* + * 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.commons.lang3.builder; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test class for ToStringExclude annotation + * @author Felipe Adorno (felipeadsc@gmail.com) + * @version $Id$ + */ +public class ReflectionToStringBuilderExcludeWithAnnotationTest { + + class TestFixture { + @ToStringExclude + private final String secretField = SECRET_VALUE; + + @SuppressWarnings("unused") + private final String showField = NOT_SECRET_VALUE; + } + + private static final String NOT_SECRET_FIELD = "showField"; + + private static final String NOT_SECRET_VALUE = "Hello World!"; + + private static final String SECRET_FIELD = "secretField"; + + private static final String SECRET_VALUE = "secret value"; + + @Test + public void test_toStringExclude() { + final String toString = ReflectionToStringBuilder.toString(new TestFixture()); + this.validateSecretFieldAbsent(toString); + } + + private void validateNonSecretField(final String toString) { + Assert.assertTrue(toString.indexOf(NOT_SECRET_FIELD) > ArrayUtils.INDEX_NOT_FOUND); + Assert.assertTrue(toString.indexOf(NOT_SECRET_VALUE) > ArrayUtils.INDEX_NOT_FOUND); + } + + private void validateSecretFieldAbsent(final String toString) { + Assert.assertEquals(ArrayUtils.INDEX_NOT_FOUND, toString.indexOf(SECRET_FIELD)); + Assert.assertEquals(ArrayUtils.INDEX_NOT_FOUND, toString.indexOf(SECRET_VALUE)); + this.validateNonSecretField(toString); + } +} From 4daaeabaad5ea11d25c0079fea40b7f9d0fe83a3 Mon Sep 17 00:00:00 2001 From: Felipe Adorno Date: Sun, 3 May 2015 21:42:20 -0300 Subject: [PATCH 2/3] Remove author --- pom.xml | 3 +++ .../java/org/apache/commons/lang3/builder/EqualsExclude.java | 1 - .../java/org/apache/commons/lang3/builder/HashCodeExclude.java | 1 - .../java/org/apache/commons/lang3/builder/ToStringExclude.java | 1 - .../ReflectionToStringBuilderExcludeWithAnnotationTest.java | 1 - 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 3d8090993..4f8c2e474 100644 --- a/pom.xml +++ b/pom.xml @@ -478,6 +478,9 @@ MichaƂ Kordas + + Felipe Adorno + diff --git a/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java b/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java index bbe2bb01b..f71616fb1 100755 --- a/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java +++ b/src/main/java/org/apache/commons/lang3/builder/EqualsExclude.java @@ -24,7 +24,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Use this annotation to builds a equals excluding the annotated field. - * @author Felipe Adorno (felipeadsc@gmail.com) */ @Retention(RUNTIME) @Target(ElementType.FIELD) diff --git a/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java b/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java index 2984808bb..adc2eb49c 100755 --- a/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java +++ b/src/main/java/org/apache/commons/lang3/builder/HashCodeExclude.java @@ -24,7 +24,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Use this annotation to builds a hash code excluding the annotated field. - * @author Felipe Adorno (felipeadsc@gmail.com) */ @Retention(RUNTIME) @Target(ElementType.FIELD) diff --git a/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java b/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java index b0bf98a56..0e26c4927 100755 --- a/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java +++ b/src/main/java/org/apache/commons/lang3/builder/ToStringExclude.java @@ -24,7 +24,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Use this annotation to builds a String excluding the annotated field. - * @author Felipe Adorno (felipeadsc@gmail.com) */ @Retention(RUNTIME) @Target(ElementType.FIELD) diff --git a/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java b/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java index c01d3b814..f6b62bcfd 100755 --- a/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/ReflectionToStringBuilderExcludeWithAnnotationTest.java @@ -23,7 +23,6 @@ import org.junit.Test; /** * Test class for ToStringExclude annotation - * @author Felipe Adorno (felipeadsc@gmail.com) * @version $Id$ */ public class ReflectionToStringBuilderExcludeWithAnnotationTest { From ceca92e3f8e9f893081b3e8461508ffcae0ed076 Mon Sep 17 00:00:00 2001 From: Benedikt Ritter Date: Mon, 4 May 2015 20:51:43 +0200 Subject: [PATCH 3/3] Add LANG-1031 to changes.xml --- src/changes/changes.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 36fc671e5..0a8069be1 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,7 @@ + Add annotations to exclude fields from ReflectionEqualsBuilder, ReflectionToStringBuilder and ReflectionHashCodeBuilder Unit test helpers which set and reset default Locale and TimeZone JsonToStringStyle doesn't handle chars and objects correctly HashCodeBuilder throws StackOverflowError in bidirectional navigable association