diff --git a/src/main/java/org/apache/commons/lang3/concurrent/ConstantInitializer.java b/src/main/java/org/apache/commons/lang3/concurrent/ConstantInitializer.java new file mode 100644 index 000000000..afd38ae1a --- /dev/null +++ b/src/main/java/org/apache/commons/lang3/concurrent/ConstantInitializer.java @@ -0,0 +1,128 @@ +/* + * 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.concurrent; + +import org.apache.commons.lang3.ObjectUtils; + +/** + *

+ * A very simple implementation of the {@link ConcurrentInitializer} interface + * which always returns the same object. + *

+ *

+ * An instance of this class is passed a reference to an object when it is + * constructed. The {@link #get()} method just returns this object. No + * synchronization is required. + *

+ *

+ * This class is useful for instance for unit testing or in cases where a + * specific object has to be passed to an object which expects a + * {@link ConcurrentInitializer}. + *

+ * + * @author Apache Software Foundation + * @version $Id$ + * @param the type of the object managed by this initializer + */ +public class ConstantInitializer implements ConcurrentInitializer { + /** Constant for the format of the string representation. */ + private static final String FMT_TO_STRING = "ConstantInitializer@%d [ object = %s ]"; + + /** Stores the managed object. */ + private final T object; + + /** + * Creates a new instance of {@code ConstantInitializer} and initializes it + * with the object to be managed. The {@code get()} method will always + * return the object passed here. This class does not place any restrictions + * on the object. It may be null, then {@code get()} will return + * null, too. + * + * @param obj the object to be managed by this initializer + */ + public ConstantInitializer(T obj) { + object = obj; + } + + /** + * Directly returns the object that was passed to the constructor. This is + * the same object as returned by {@code get()}. However, this method does + * not declare that it throws an exception. + * + * @return the object managed by this initializer + */ + public final T getObject() { + return object; + } + + /** + * Returns the object managed by this initializer. This implementation just + * returns the object passed to the constructor. + * + * @return the object managed by this initializer + * @throws ConcurrentException if an error occurs + */ + public T get() throws ConcurrentException { + return getObject(); + } + + /** + * Returns a hash code for this object. This implementation returns the hash + * code of the managed object. + * + * @return a hash code for this object + */ + @Override + public int hashCode() { + return (getObject() != null) ? getObject().hashCode() : 0; + } + + /** + * Compares this object with another one. This implementation returns + * true if and only if the passed in object is an instance of + * {@code ConstantInitializer} which refers to an object equals to the + * object managed by this instance. + * + * @param obj the object to compare to + * @return a flag whether the objects are equal + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ConstantInitializer)) { + return false; + } + + ConstantInitializer c = (ConstantInitializer) obj; + return ObjectUtils.equals(getObject(), c.getObject()); + } + + /** + * Returns a string representation for this object. This string also + * contains a string representation of the object managed by this + * initializer. + * + * @return a string for this object + */ + @Override + public String toString() { + return String.format(FMT_TO_STRING, System.identityHashCode(this), + String.valueOf(getObject())); + } +} diff --git a/src/test/java/org/apache/commons/lang3/concurrent/ConstantInitializerTest.java b/src/test/java/org/apache/commons/lang3/concurrent/ConstantInitializerTest.java new file mode 100644 index 000000000..83ea6a957 --- /dev/null +++ b/src/test/java/org/apache/commons/lang3/concurrent/ConstantInitializerTest.java @@ -0,0 +1,134 @@ +/* + * 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.concurrent; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.regex.Pattern; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test class for {@code ConstantInitializer}. + * + * @author Apache Software Foundation + * @version $Id$ + */ +public class ConstantInitializerTest { + /** Constant for the object managed by the initializer. */ + private static final Integer VALUE = 42; + + /** The initializer to be tested. */ + private ConstantInitializer init; + + @Before + public void setUp() throws Exception { + init = new ConstantInitializer(VALUE); + } + + /** + * Helper method for testing equals() and hashCode(). + * + * @param obj the object to compare with the test instance + * @param expected the expected result + */ + private void checkEquals(Object obj, boolean expected) { + assertEquals("Wrong result of equals", expected, init.equals(obj)); + if (obj != null) { + assertEquals("Not symmetric", expected, obj.equals(init)); + } + if (expected) { + assertEquals("Different hash codes", init.hashCode(), + obj.hashCode()); + } + } + + /** + * Tests whether the correct object is returned. + */ + @Test + public void testGetObject() { + assertEquals("Wrong object", VALUE, init.getObject()); + } + + /** + * Tests whether get() returns the correct object. + */ + @Test + public void testGet() throws ConcurrentException { + assertEquals("Wrong object", VALUE, init.get()); + } + + /** + * Tests equals() if the expected result is true. + */ + @Test + public void testEqualsTrue() { + checkEquals(init, true); + ConstantInitializer init2 = new ConstantInitializer( + new Integer(VALUE.intValue())); + checkEquals(init2, true); + init = new ConstantInitializer(null); + init2 = new ConstantInitializer(null); + checkEquals(init2, true); + } + + /** + * Tests equals() if the expected result is false. + */ + @Test + public void testEqualsFalse() { + ConstantInitializer init2 = new ConstantInitializer( + null); + checkEquals(init2, false); + init2 = new ConstantInitializer(VALUE + 1); + checkEquals(init2, false); + } + + /** + * Tests equals() with objects of other classes. + */ + @Test + public void testEqualsWithOtherObjects() { + checkEquals(null, false); + checkEquals(this, false); + checkEquals(new ConstantInitializer("Test"), false); + } + + /** + * Tests the string representation. + */ + @Test + public void testToString() { + String s = init.toString(); + Pattern pattern = Pattern + .compile("ConstantInitializer@\\d+ \\[ object = " + VALUE + + " \\]"); + assertTrue("Wrong string: " + s, pattern.matcher(s).matches()); + } + + /** + * Tests the string representation if the managed object is null. + */ + @Test + public void testToStringNull() { + String s = new ConstantInitializer(null).toString(); + assertTrue("Object not found: " + s, s.indexOf("object = null") > 0); + } +}