[COLLECTIONS-746] Add

org.apache.commons.collections4.properties.PropertiesFactory.EMPTY_PROPERTIES.

[build] Update Jacoco from 0.8.4 to 0.8.5.
This commit is contained in:
Gary Gregory 2020-02-09 11:40:43 -05:00
parent ee282c7c6b
commit 8f906c08fa
4 changed files with 662 additions and 6 deletions

18
pom.xml
View File

@ -463,10 +463,16 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
<optional>true</optional>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
<optional>true</optional>
</dependency>
</dependencies>
@ -534,10 +540,10 @@
<!-- Override clirr version to enable clirr on Java 8 -->
<commons.clirr.version>2.8</commons.clirr.version>
<commons.jacoco.version>0.8.4</commons.jacoco.version>
<commons.jacoco.version>0.8.5</commons.jacoco.version>
<!--Commons Release Plugin -->
<commons.bc.version>4.3</commons.bc.version>
<commons.bc.version>4.4</commons.bc.version>
<commons.release.isDistModule>true</commons.release.isDistModule>
<commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>
<commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey>

View File

@ -120,6 +120,12 @@
<action dev="ggregory" type="update" due-to="Gary Gregory">
[build] Update Apache commons-parent from 48 to 50.
</action>
<action issue="COLLECTIONS-746" dev="ggregory" type="add" due-to="Gary Gregory">
Add org.apache.commons.collections4.properties.PropertiesFactory.EMPTY_PROPERTIES.
</action>
<action dev="ggregory" type="update" due-to="Gary Gregory">
[build] Update Jacoco from 0.8.4 to 0.8.5.
</action>
</release>
<release version="4.4" date="2019-07-05" description="Maintenance release.">
<action issue="COLLECTIONS-710" dev="ggregory" type="fix" due-to="Yu Shi, Gary Gregory">

View File

@ -17,7 +17,26 @@
package org.apache.commons.collections4.properties;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* Creates and loads {@link Properties}.
@ -27,6 +46,282 @@ import java.util.Properties;
*/
public class PropertiesFactory extends AbstractPropertiesFactory<Properties> {
private static class EmptyProperties extends Properties {
private static final long serialVersionUID = 1L;
@Override
public synchronized void clear() {
// Noop
}
@Override
public synchronized Object compute(final Object key,
final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
Objects.requireNonNull(key);
throw new UnsupportedOperationException();
}
@Override
public synchronized Object computeIfAbsent(final Object key,
final Function<? super Object, ? extends Object> mappingFunction) {
Objects.requireNonNull(key);
throw new UnsupportedOperationException();
}
@Override
public synchronized Object computeIfPresent(final Object key,
final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
Objects.requireNonNull(key);
throw new UnsupportedOperationException();
}
@Override
public synchronized boolean contains(final Object value) {
return false;
}
@Override
public synchronized boolean containsKey(final Object key) {
return false;
}
@Override
public boolean containsValue(final Object value) {
return false;
}
@Override
public synchronized Enumeration<Object> elements() {
return Collections.emptyEnumeration();
}
@Override
public Set<Entry<Object, Object>> entrySet() {
return Collections.emptySet();
}
@Override
public synchronized boolean equals(final Object o) {
return (o instanceof Properties) && ((Properties) o).isEmpty();
}
@Override
public synchronized void forEach(final BiConsumer<? super Object, ? super Object> action) {
Objects.requireNonNull(action);
}
@Override
public synchronized Object get(final Object key) {
return null;
}
@Override
public synchronized Object getOrDefault(final Object key, final Object defaultValue) {
return defaultValue;
}
@Override
public String getProperty(final String key) {
return null;
}
@Override
public String getProperty(final String key, final String defaultValue) {
return defaultValue;
}
@Override
public synchronized int hashCode() {
return 0;
}
@Override
public synchronized boolean isEmpty() {
return true;
}
@Override
public synchronized Enumeration<Object> keys() {
return Collections.emptyEnumeration();
}
@Override
public Set<Object> keySet() {
return Collections.emptySet();
}
@Override
public void list(final PrintStream out) {
// Implement as super
super.list(out);
}
@Override
public void list(final PrintWriter out) {
// Implement as super
super.list(out);
}
@Override
public synchronized void load(final InputStream inStream) throws IOException {
Objects.requireNonNull(inStream);
throw new UnsupportedOperationException();
}
@Override
public synchronized void load(final Reader reader) throws IOException {
Objects.requireNonNull(reader);
throw new UnsupportedOperationException();
}
@Override
public synchronized void loadFromXML(final InputStream in)
throws IOException, InvalidPropertiesFormatException {
Objects.requireNonNull(in);
throw new UnsupportedOperationException();
}
@Override
public synchronized Object merge(final Object key, final Object value,
final BiFunction<? super Object, ? super Object, ? extends Object> remappingFunction) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
public Enumeration<?> propertyNames() {
return Collections.emptyEnumeration();
}
@Override
public synchronized Object put(final Object key, final Object value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
public synchronized void putAll(final Map<? extends Object, ? extends Object> t) {
Objects.requireNonNull(t);
throw new UnsupportedOperationException();
}
@Override
public synchronized Object putIfAbsent(final Object key, final Object value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
protected void rehash() {
// Noop
}
@Override
public synchronized Object remove(final Object key) {
Objects.requireNonNull(key);
throw new UnsupportedOperationException();
}
@Override
public synchronized boolean remove(final Object key, final Object value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
public synchronized Object replace(final Object key, final Object value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
public synchronized boolean replace(final Object key, final Object oldValue, final Object newValue) {
Objects.requireNonNull(key);
Objects.requireNonNull(oldValue);
Objects.requireNonNull(newValue);
throw new UnsupportedOperationException();
}
@Override
public synchronized void replaceAll(
final BiFunction<? super Object, ? super Object, ? extends Object> function) {
Objects.requireNonNull(function);
throw new UnsupportedOperationException();
}
@Override
public void save(final OutputStream out, final String comments) {
// Implement as super
super.save(out, comments);
}
@Override
public synchronized Object setProperty(final String key, final String value) {
Objects.requireNonNull(key);
Objects.requireNonNull(value);
throw new UnsupportedOperationException();
}
@Override
public synchronized int size() {
return 0;
}
@Override
public void store(final OutputStream out, final String comments) throws IOException {
// Implement as super
super.store(out, comments);
}
@Override
public void store(final Writer writer, final String comments) throws IOException {
// Implement as super
super.store(writer, comments);
}
@Override
public void storeToXML(final OutputStream os, final String comment) throws IOException {
// Implement as super
super.storeToXML(os, comment);
}
@Override
public void storeToXML(final OutputStream os, final String comment, final String encoding) throws IOException {
// Implement as super
super.storeToXML(os, comment, encoding);
}
@Override
public Set<String> stringPropertyNames() {
return Collections.emptySet();
}
@Override
public synchronized String toString() {
// Implement as super
return super.toString();
}
@Override
public Collection<Object> values() {
return Collections.emptyList();
}
}
/**
* The empty map (immutable). This map is serializable.
*
* @since 4.5
*/
public static final Properties EMPTY_PROPERTIES = new EmptyProperties();
/**
* The singleton instance.
*/

View File

@ -0,0 +1,349 @@
/*
* 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.collections4.properties;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Properties;
import org.apache.commons.io.input.NullReader;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Assert;
import org.junit.Test;
public class EmptyPropertiesTest {
@Test
public void testClear() {
PropertiesFactory.EMPTY_PROPERTIES.clear();
Assert.assertEquals(0, PropertiesFactory.EMPTY_PROPERTIES.size());
}
@Test
public void testClone() {
// TODO Better test?
PropertiesFactory.EMPTY_PROPERTIES.clone();
Assert.assertEquals(0, PropertiesFactory.EMPTY_PROPERTIES.size());
}
@Test(expected = UnsupportedOperationException.class)
public void testCompute() {
PropertiesFactory.EMPTY_PROPERTIES.compute("key", (k, v) -> "foo");
}
@Test(expected = UnsupportedOperationException.class)
public void testComputeIfAbsent() {
PropertiesFactory.EMPTY_PROPERTIES.computeIfAbsent("key", k -> "foo");
}
@Test(expected = UnsupportedOperationException.class)
public void testComputeIfPresent() {
PropertiesFactory.EMPTY_PROPERTIES.computeIfPresent("key", (k, v) -> "foo");
}
@Test
public void testContains() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.contains("foo"));
}
@Test
public void testContainsKey() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.containsKey("foo"));
}
@Test
public void testContainsValue() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.containsValue("foo"));
}
@Test
public void testElements() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.elements().hasMoreElements());
}
@Test
public void testEntrySet() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.entrySet().isEmpty());
}
@Test
public void testEquals() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.equals(PropertiesFactory.EMPTY_PROPERTIES));
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.equals(new Properties()));
Assert.assertTrue(new Properties().equals(PropertiesFactory.EMPTY_PROPERTIES));
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.equals(null));
final Properties p = new Properties();
p.put("Key", "Value");
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.equals(p));
Assert.assertFalse(p.equals(PropertiesFactory.EMPTY_PROPERTIES));
}
public void testForEach() {
PropertiesFactory.EMPTY_PROPERTIES.forEach((k, v) -> Assert.fail());
}
@Test
public void testGet() {
Assert.assertNull(PropertiesFactory.EMPTY_PROPERTIES.get("foo"));
}
@Test
public void testGetOrDefault() {
Assert.assertEquals("bar", PropertiesFactory.EMPTY_PROPERTIES.getOrDefault("foo", "bar"));
}
@Test
public void testGetProperty() {
Assert.assertNull(PropertiesFactory.EMPTY_PROPERTIES.getProperty("foo"));
}
@Test
public void testGetPropertyDefault() {
Assert.assertEquals("bar", PropertiesFactory.EMPTY_PROPERTIES.getProperty("foo", "bar"));
}
@Test
public void testHashCode() {
Assert.assertEquals(PropertiesFactory.EMPTY_PROPERTIES.hashCode(),
PropertiesFactory.EMPTY_PROPERTIES.hashCode());
// Should be equals?
// Assert.assertEquals(PropertiesFactory.EMPTY_PROPERTIES.hashCode(), new Properties().hashCode());
}
@Test
public void testIsEmpty() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.isEmpty());
}
@Test
public void testKeys() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.keys().hasMoreElements());
}
@Test
public void testKeySet() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.keySet().isEmpty());
}
@Test
public void testListToPrintStream() {
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.list(new PrintStream(actual));
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().list(new PrintStream(expected));
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().list(new PrintStream(expected));
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test
public void testListToPrintWriter() {
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.list(new PrintWriter(actual));
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().list(new PrintWriter(expected));
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().list(new PrintWriter(expected));
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test(expected = UnsupportedOperationException.class)
public void testLoadFromXML() throws IOException {
PropertiesFactory.EMPTY_PROPERTIES.loadFromXML(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY));
}
@Test(expected = UnsupportedOperationException.class)
public void testLoadInputStream() throws IOException {
PropertiesFactory.EMPTY_PROPERTIES.load(new ByteArrayInputStream(ArrayUtils.EMPTY_BYTE_ARRAY));
}
@Test(expected = UnsupportedOperationException.class)
public void testLoadReader() throws IOException {
try (final NullReader reader = new NullReader(0)) {
PropertiesFactory.EMPTY_PROPERTIES.load(reader);
}
}
@Test(expected = UnsupportedOperationException.class)
public void testMerge() {
PropertiesFactory.EMPTY_PROPERTIES.merge("key", "value", (k, v) -> "foo");
}
@Test
public void testPropertyName() {
Assert.assertFalse(PropertiesFactory.EMPTY_PROPERTIES.propertyNames().hasMoreElements());
}
@Test(expected = UnsupportedOperationException.class)
public void testPut() {
PropertiesFactory.EMPTY_PROPERTIES.put("Key", "Value");
}
@Test(expected = UnsupportedOperationException.class)
public void testPutAll() {
PropertiesFactory.EMPTY_PROPERTIES.putAll(new HashMap<>());
}
@Test(expected = UnsupportedOperationException.class)
public void testPutIfAbsent() {
PropertiesFactory.EMPTY_PROPERTIES.putIfAbsent("Key", "Value");
}
@Test
public void testRehash() {
// Can't really test without extending and casting to a currently private class
// PropertiesFactory.EMPTY_PROPERTIES.rehash();
}
@Test(expected = UnsupportedOperationException.class)
public void testRemove() {
PropertiesFactory.EMPTY_PROPERTIES.remove("key", "value");
}
@Test(expected = UnsupportedOperationException.class)
public void testRemoveKey() {
PropertiesFactory.EMPTY_PROPERTIES.remove("key");
}
@Test(expected = UnsupportedOperationException.class)
public void testReplace() {
PropertiesFactory.EMPTY_PROPERTIES.replace("key", "value1");
}
@Test(expected = UnsupportedOperationException.class)
public void testReplaceAll() {
PropertiesFactory.EMPTY_PROPERTIES.replaceAll((k, v) -> "value1");
}
@Test(expected = UnsupportedOperationException.class)
public void testReplaceOldValue() {
PropertiesFactory.EMPTY_PROPERTIES.replace("key", "value1", "value2");
}
@Test
public void testSave() {
final String comments = "Hello world!";
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.save(new PrintStream(actual), comments);
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().save(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().save(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test(expected = UnsupportedOperationException.class)
public void testSetProperty() {
PropertiesFactory.EMPTY_PROPERTIES.setProperty("Key", "Value");
}
@Test
public void testSize() {
Assert.assertEquals(0, PropertiesFactory.EMPTY_PROPERTIES.size());
}
@Test
public void testStoreToOutputStream() throws IOException {
final String comments = "Hello world!";
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.store(new PrintStream(actual), comments);
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().store(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().store(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test
public void testStoreToPrintWriter() throws IOException {
final String comments = "Hello world!";
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.store(new PrintWriter(actual), comments);
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().store(new PrintWriter(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().store(new PrintWriter(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test
public void testStoreToXMLOutputStream() throws IOException {
final String comments = "Hello world!";
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.storeToXML(new PrintStream(actual), comments);
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().storeToXML(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().storeToXML(new PrintStream(expected), comments);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test
public void testStoreToXMLOutputStreamWithEncoding() throws IOException {
final String comments = "Hello world!";
final String encoding = StandardCharsets.UTF_8.name();
// actual
final ByteArrayOutputStream actual = new ByteArrayOutputStream();
PropertiesFactory.EMPTY_PROPERTIES.storeToXML(new PrintStream(actual), comments, encoding);
// expected
final ByteArrayOutputStream expected = new ByteArrayOutputStream();
PropertiesFactory.INSTANCE.createProperties().storeToXML(new PrintStream(expected), comments, encoding);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
expected.reset();
new Properties().storeToXML(new PrintStream(expected), comments, encoding);
Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
}
@Test
public void testStringPropertyName() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.stringPropertyNames().isEmpty());
}
@Test
public void testToString() {
Assert.assertEquals(new Properties().toString(), PropertiesFactory.EMPTY_PROPERTIES.toString());
}
@Test
public void testValues() {
Assert.assertTrue(PropertiesFactory.EMPTY_PROPERTIES.values().isEmpty());
}
}