diff options
author | Henri Yandell <bayard@apache.org> | 2010-03-20 20:20:26 +0000 |
---|---|---|
committer | Henri Yandell <bayard@apache.org> | 2010-03-20 20:20:26 +0000 |
commit | bc22af91e7e8fd7a530de48cd164056ef05829e0 (patch) | |
tree | 1ea39c009c0c0fa40ee4b1d39c1498365f8109cf | |
parent | 1a60c21395fe7648188d1c91f62ac7baefa12742 (diff) | |
download | apache-commons-lang-bc22af91e7e8fd7a530de48cd164056ef05829e0.tar.gz |
Adding Builder interface, and refactoring the builder classes and BasicThreadFactory to implement this interface. Patch from Michael Wooten in LANG-601
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@925674 13f79535-47bb-0310-9956-ffa450edef68
10 files changed, 199 insertions, 5 deletions
diff --git a/src/main/java/org/apache/commons/lang3/builder/Builder.java b/src/main/java/org/apache/commons/lang3/builder/Builder.java new file mode 100644 index 000000000..10da0b35c --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/builder/Builder.java @@ -0,0 +1,89 @@ +/* + * 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; + +/** + * <p> + * The Builder interface is designed to designate a class as a <em>builder</em> + * object in the Builder design pattern. Builders are capable of creating and + * configuring objects or results that normally take multiple steps to construct + * or are very complex to derive. + * </p> + * + * <p> + * The builder interface defines a single method, {@link #build()}, that + * classes must implement. The result of this method should be the final + * configured object or result after all building operations are performed. + * </p> + * + * <p> + * It is a recommended practice that the methods supplied to configure the + * object or result being built return a reference to <code>this</code> so that + * method calls can be chained together. + * </p> + * + * <p> + * Example Builder: + * <code><pre> + * class FontBuilder implements Builder<Font> { + * private Font font; + * + * public FontBuilder(String fontName) { + * this.font = new Font(fontName, Font.PLAIN, 12); + * } + * + * public FontBuilder bold() { + * this.font = this.font.deriveFont(Font.BOLD); + * return this; // Reference returned so calls can be chained + * } + * + * public FontBuilder size(float pointSize) { + * this.font = this.font.deriveFont(pointSize); + * return this; // Reference returned so calls can be chained + * } + * + * // Other Font construction methods + * + * public Font build() { + * return this.font; + * } + * } + * </pre></code> + * + * Example Builder Usage: + * <code><pre> + * Font bold14ptSansSerifFont = new FontBuilder(Font.SANS_SERIF).bold() + * .size(14.0f) + * .build(); + * </pre></code> + * </p> + * + * @param <T> the type of object that the builder will construct or compute. + * + * @author <a href="mailto:mwooten.dev@gmail.com">Michael Wooten</a> + * @since 3.0 + */ +public interface Builder<T> { + + /** + * Returns a reference to the object being constructed or result being + * calculated by the builder. + * + * @return the object constructed or result calculated by the builder. + */ + public T build(); +} diff --git a/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java b/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java index 50d5407e1..70fac50a2 100644 --- a/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/CompareToBuilder.java @@ -89,7 +89,7 @@ import org.apache.commons.lang3.ArrayUtils; * @since 1.0 * @version $Id$ */ -public class CompareToBuilder { +public class CompareToBuilder implements Builder<Integer> { /** * Current state of the comparison as appended fields are checked. @@ -1043,5 +1043,18 @@ public class CompareToBuilder { return comparison; } + /** + * Returns a negative integer, a positive integer, or zero as + * the <code>builder</code> has judged the "left-hand" side + * as less than, greater than, or equal to the "right-hand" + * side. + * + * @return final comparison result + * + * @since 3.0 + */ + public Integer build() { + return toComparison(); + } } 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 c725cfffd..7db4a0708 100644 --- a/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/EqualsBuilder.java @@ -86,7 +86,7 @@ import org.apache.commons.lang3.Pair; * @since 1.0 * @version $Id$ */ -public class EqualsBuilder { +public class EqualsBuilder implements Builder<Boolean> { /** * <p> @@ -968,6 +968,19 @@ public class EqualsBuilder { public boolean isEquals() { return this.isEquals; } + + /** + * <p>Returns <code>true</code> if the fields that have been checked + * are all equal.</p> + * + * @return <code>true</code> if all of the fields that have been checked + * are equal, <code>false</code> otherwise. + * + * @since 3.0 + */ + public Boolean build() { + return isEquals(); + } /** * Sets the <code>isEquals</code> value. 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 c6fe82c27..290e70936 100644 --- a/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/HashCodeBuilder.java @@ -93,7 +93,7 @@ import org.apache.commons.lang3.ArrayUtils; * @since 1.0 * @version $Id$ */ -public class HashCodeBuilder { +public class HashCodeBuilder implements Builder<Integer> { /** * <p> * A registry of objects used by reflection methods to detect cyclical object references and avoid infinite loops. @@ -976,6 +976,17 @@ public class HashCodeBuilder { public int toHashCode() { return iTotal; } + + /** + * Returns the computed <code>hashCode</code>. + * + * @return <code>hashCode</code> based on the fields appended + * + * @since 3.0 + */ + public Integer build() { + return toHashCode(); + } /** * <p> diff --git a/src/main/java/org/apache/commons/lang3/builder/ToStringBuilder.java b/src/main/java/org/apache/commons/lang3/builder/ToStringBuilder.java index c368126b6..cc360c670 100644 --- a/src/main/java/org/apache/commons/lang3/builder/ToStringBuilder.java +++ b/src/main/java/org/apache/commons/lang3/builder/ToStringBuilder.java @@ -89,7 +89,7 @@ import org.apache.commons.lang3.ObjectUtils; * @since 1.0 * @version $Id$ */ -public class ToStringBuilder { +public class ToStringBuilder implements Builder<String> { /** * The default style of output to use, not null. @@ -1065,4 +1065,17 @@ public class ToStringBuilder { return this.getStringBuffer().toString(); } + /** + * Returns the String that was build as an object representation. The + * default implementation utilizes the {@link #toString()} implementation. + * + * @return the String <code>toString</code> + * + * @see #toString() + * + * @since 3.0 + */ + public String build() { + return toString(); + } } diff --git a/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java b/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java index 7ba8cf206..e2441334a 100644 --- a/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java +++ b/src/main/java/org/apache/commons/lang3/concurrent/BasicThreadFactory.java @@ -250,7 +250,9 @@ public class BasicThreadFactory implements ThreadFactory { * * @version $Id: $ */ - public static class Builder { + public static class Builder + implements org.apache.commons.lang3.builder.Builder<BasicThreadFactory> { + /** The wrapped factory. */ private ThreadFactory wrappedFactory; diff --git a/src/test/java/org/apache/commons/lang3/builder/CompareToBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/CompareToBuilderTest.java index 49ebd5ab6..9c053f4a6 100644 --- a/src/test/java/org/apache/commons/lang3/builder/CompareToBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/CompareToBuilderTest.java @@ -272,6 +272,20 @@ public class CompareToBuilderTest extends TestCase { assertTrue(new CompareToBuilder().append((Object) null, (Object) null).toComparison() == 0); assertTrue(new CompareToBuilder().append(null, o1).toComparison() < 0); } + + public void testObjectBuild() { + TestObject o1 = new TestObject(4); + TestObject o2 = new TestObject(4); + assertTrue(new CompareToBuilder().append(o1, o1).build() == 0); + assertTrue(new CompareToBuilder().append(o1, o2).build() == 0); + o2.setA(5); + assertTrue(new CompareToBuilder().append(o1, o2).build() < 0); + assertTrue(new CompareToBuilder().append(o2, o1).build() > 0); + + assertTrue(new CompareToBuilder().append(o1, null).build() > 0); + assertTrue(new CompareToBuilder().append((Object) null, (Object) null).build() == 0); + assertTrue(new CompareToBuilder().append(null, o1).build() < 0); + } public void testObjectEx2() { TestObject o1 = new TestObject(4); 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 382997080..f03d6b394 100644 --- a/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/EqualsBuilderTest.java @@ -305,6 +305,21 @@ public class EqualsBuilderTest extends TestCase { assertTrue(!new EqualsBuilder().append(null, o2).isEquals()); assertTrue(new EqualsBuilder().append((Object) null, (Object) null).isEquals()); } + + public void testObjectBuild() { + TestObject o1 = new TestObject(4); + TestObject o2 = new TestObject(5); + assertTrue(new EqualsBuilder().append(o1, o1).build()); + assertTrue(!new EqualsBuilder().append(o1, o2).build()); + o2.setA(4); + assertTrue(new EqualsBuilder().append(o1, o2).build()); + + assertTrue(!new EqualsBuilder().append(o1, this).build()); + + assertTrue(!new EqualsBuilder().append(o1, null).build()); + assertTrue(!new EqualsBuilder().append(null, o2).build()); + assertTrue(new EqualsBuilder().append((Object) null, (Object) null).build()); + } public void testLong() { long o1 = 1L; 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 64b34f907..3ce645fdd 100644 --- a/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java @@ -205,6 +205,13 @@ public class HashCodeBuilderTest extends TestCase { obj = new Object(); assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).toHashCode()); } + + public void testObjectBuild() { + Object obj = null; + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).build().intValue()); + obj = new Object(); + assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).build().intValue()); + } @SuppressWarnings("cast") // cast is not really needed, keep for consistency public void testLong() { diff --git a/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java index f2085b2ce..b15515e35 100644 --- a/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/ToStringBuilderTest.java @@ -619,6 +619,23 @@ public class ToStringBuilderTest extends TestCase { assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).toString()); assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).toString()); } + + public void testObjectBuild() { + Integer i3 = new Integer(3); + Integer i4 = new Integer(4); + assertEquals(baseStr + "[<null>]", new ToStringBuilder(base).append((Object) null).build()); + assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(i3).build()); + assertEquals(baseStr + "[a=<null>]", new ToStringBuilder(base).append("a", (Object) null).build()); + assertEquals(baseStr + "[a=3]", new ToStringBuilder(base).append("a", i3).build()); + assertEquals(baseStr + "[a=3,b=4]", new ToStringBuilder(base).append("a", i3).append("b", i4).build()); + assertEquals(baseStr + "[a=<Integer>]", new ToStringBuilder(base).append("a", i3, false).build()); + assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new ArrayList<Object>(), false).build()); + assertEquals(baseStr + "[a=[]]", new ToStringBuilder(base).append("a", new ArrayList<Object>(), true).build()); + assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", new HashMap<Object, Object>(), false).build()); + assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", new HashMap<Object, Object>(), true).build()); + assertEquals(baseStr + "[a=<size=0>]", new ToStringBuilder(base).append("a", (Object) new String[0], false).build()); + assertEquals(baseStr + "[a={}]", new ToStringBuilder(base).append("a", (Object) new String[0], true).build()); + } public void testLong() { assertEquals(baseStr + "[3]", new ToStringBuilder(base).append(3L).toString()); |