[COLLECTIONS-748] Let

org.apache.commons.collections4.properties.[Sorted]PropertiesFactory
accept XML input.
This commit is contained in:
Gary Gregory 2020-02-16 20:42:27 -05:00
parent 87497d0fa1
commit d5bf76870f
6 changed files with 129 additions and 20 deletions

View File

@ -132,6 +132,9 @@
<action issue="COLLECTIONS-747" dev="ggregory" type="fix" due-to="Gary Gregory, Walter Laan">
MultiKey.getKeys class cast exception.
</action>
<action issue="COLLECTIONS-748" dev="ggregory" type="update" due-to="Gary Gregory">
Let org.apache.commons.collections4.properties.[Sorted]PropertiesFactory accept XML input.
</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

@ -28,6 +28,7 @@ import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.Properties;
/**
@ -39,6 +40,24 @@ import java.util.Properties;
*/
public abstract class AbstractPropertiesFactory<T extends Properties> {
/**
* Enumerat5es property formats.
*
* @since 4.5
*/
public enum PropertyFormat {
/** Properties file format. */
PROPERTIES,
/** XML file format. */
XML;
static PropertyFormat toPropertyFormat(String fileName) {
return Objects.requireNonNull(fileName, "fileName").endsWith(".xml") ? XML : PROPERTIES;
}
}
/**
* Constructs an instance.
*/
@ -64,7 +83,7 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
*/
public T load(final ClassLoader classLoader, final String name) throws IOException {
try (final InputStream inputStream = classLoader.getResourceAsStream(name)) {
return load(inputStream);
return load(inputStream, PropertyFormat.toPropertyFormat(name));
}
}
@ -82,7 +101,7 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
*/
public T load(final File file) throws FileNotFoundException, IOException {
try (final FileInputStream inputStream = new FileInputStream(file)) {
return load(inputStream);
return load(inputStream, PropertyFormat.toPropertyFormat(file.getName()));
}
}
@ -103,6 +122,29 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
return properties;
}
/**
* Creates and loads properties from the given input stream.
*
* @param inputStream the location of the properties file.
* @param propertyFormat The format of the given file.
* @return a new properties object.
* @throws IOException Thrown if an error occurred reading the input stream.
* @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence.
* @since 4.5
*/
public T load(final InputStream inputStream, final PropertyFormat propertyFormat) throws IOException {
if (inputStream == null) {
return null;
}
final T properties = createProperties();
if (propertyFormat == PropertyFormat.XML) {
properties.loadFromXML(inputStream);
} else {
properties.load(inputStream);
}
return properties;
}
/**
* Creates and loads properties from the given path.
*
@ -113,7 +155,7 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
*/
public T load(final Path path) throws IOException {
try (final InputStream inputStream = Files.newInputStream(path)) {
return load(inputStream);
return load(inputStream, PropertyFormat.toPropertyFormat(Objects.toString(path.getFileName(), null)));
}
}
@ -141,7 +183,7 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
*/
public T load(final String name) throws IOException {
try (final FileInputStream inputStream = new FileInputStream(name)) {
return load(inputStream);
return load(inputStream, PropertyFormat.toPropertyFormat(name));
}
}
@ -167,7 +209,7 @@ public abstract class AbstractPropertiesFactory<T extends Properties> {
*/
public T load(final URL url) throws IOException {
try (final InputStream inputStream = url.openStream()) {
return load(inputStream);
return load(inputStream, PropertyFormat.toPropertyFormat(url.getFile()));
}
}

View File

@ -24,22 +24,48 @@ import java.nio.file.Paths;
import java.util.Properties;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public abstract class AbstractPropertiesFactoryTest<T extends Properties> {
private static final String PATH_STRING = "src/test/resources/properties/test.properties";
@Parameters(name = "{0}")
public static Object[][] getParameters() {
return new Object[][] { { ".properties" }, { ".xml" } };
}
private final AbstractPropertiesFactory<T> factory;
private final String pathString;
private final String fileExtention;
protected AbstractPropertiesFactoryTest(final AbstractPropertiesFactory<T> factory) {
protected AbstractPropertiesFactoryTest(final AbstractPropertiesFactory<T> factory, final String fileExtension) {
super();
this.factory = factory;
this.fileExtention = fileExtension;
this.pathString = "src/test/resources/properties/test" + fileExtention;
}
private void assertContents(final T properties) {
Assert.assertEquals("value1", properties.getProperty("key1"));
Assert.assertEquals("value2", properties.getProperty("key2"));
Assert.assertEquals("value3", properties.getProperty("key3"));
Assert.assertEquals("value4", properties.getProperty("key4"));
Assert.assertEquals("value5", properties.getProperty("key5"));
Assert.assertEquals("value6", properties.getProperty("key6"));
Assert.assertEquals("value7", properties.getProperty("key7"));
Assert.assertEquals("value8", properties.getProperty("key8"));
Assert.assertEquals("value9", properties.getProperty("key9"));
Assert.assertEquals("value10", properties.getProperty("key10"));
Assert.assertEquals("value11", properties.getProperty("key11"));
}
private boolean isXmlTest() {
return ".xml".equals(fileExtention);
}
@Test
@ -49,50 +75,56 @@ public abstract class AbstractPropertiesFactoryTest<T extends Properties> {
@Test
public void testLoadClassLoaderMissingResource() throws Exception {
Assert.assertNull(factory.load(ClassLoader.getSystemClassLoader(), "missing/test.properties"));
Assert.assertNull(factory.load(ClassLoader.getSystemClassLoader(), "missing/test" + fileExtention));
}
@Test
public void testLoadClassLoaderResource() throws Exception {
assertContents(factory.load(ClassLoader.getSystemClassLoader(), "properties/test.properties"));
assertContents(factory.load(ClassLoader.getSystemClassLoader(), "properties/test" + fileExtention));
}
@Test
public void testLoadFile() throws Exception {
assertContents(factory.load(Paths.get(PATH_STRING).toFile()));
assertContents(factory.load(Paths.get(pathString).toFile()));
}
@Test
public void testLoadFileName() throws Exception {
assertContents(factory.load(PATH_STRING));
assertContents(factory.load(pathString));
}
@Test
public void testLoadInputStream() throws Exception {
try (final FileInputStream inputStream = new FileInputStream(PATH_STRING)) {
// Can't tell what we are reading
Assume.assumeFalse(isXmlTest());
//
try (final FileInputStream inputStream = new FileInputStream(pathString)) {
assertContents(factory.load(inputStream));
}
}
@Test
public void testLoadPath() throws Exception {
assertContents(factory.load(Paths.get(PATH_STRING)));
assertContents(factory.load(Paths.get(pathString)));
}
@Test
public void testLoadReader() throws Exception {
try (final BufferedReader inputStream = Files.newBufferedReader(Paths.get(PATH_STRING))) {
// Can't tell what we are reading
Assume.assumeFalse(isXmlTest());
//
try (final BufferedReader inputStream = Files.newBufferedReader(Paths.get(pathString))) {
assertContents(factory.load(inputStream));
}
}
@Test
public void testLoadUri() throws Exception {
assertContents(factory.load(Paths.get(PATH_STRING).toUri()));
assertContents(factory.load(Paths.get(pathString).toUri()));
}
@Test
public void testLoadUrl() throws Exception {
assertContents(factory.load(Paths.get(PATH_STRING).toUri().toURL()));
assertContents(factory.load(Paths.get(pathString).toUri().toURL()));
}
}

View File

@ -24,8 +24,8 @@ import org.junit.Test;
public class PropertiesFactoryTest extends AbstractPropertiesFactoryTest<Properties> {
public PropertiesFactoryTest() {
super(PropertiesFactory.INSTANCE);
public PropertiesFactoryTest(final String fileExtension) {
super(PropertiesFactory.INSTANCE, fileExtension);
}
@Override

View File

@ -22,8 +22,8 @@ import org.junit.Test;
public class SortedPropertiesFactoryTest extends AbstractPropertiesFactoryTest<SortedProperties> {
public SortedPropertiesFactoryTest() {
super(SortedPropertiesFactory.INSTANCE);
public SortedPropertiesFactoryTest(final String fileExtension) {
super(SortedPropertiesFactory.INSTANCE, fileExtension);
}
@Override

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
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.
-->
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Hello comment!</comment>
<entry key="key1">value1</entry>
<entry key="key2">value2</entry>
<entry key="key3">value3</entry>
<entry key="key4">value4</entry>
<entry key="key5">value5</entry>
<entry key="key6">value6</entry>
<entry key="key7">value7</entry>
<entry key="key8">value8</entry>
<entry key="key9">value9</entry>
<entry key="key10">value10</entry>
<entry key="key11">value11</entry>
</properties>