1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.collections4.properties; 19 20 import java.io.File; 21 import java.io.FileNotFoundException; 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.Reader; 25 import java.net.URI; 26 import java.net.URL; 27 import java.nio.file.Files; 28 import java.nio.file.Path; 29 import java.nio.file.Paths; 30 import java.util.Objects; 31 import java.util.Properties; 32 33 /** 34 * Subclasses create and load {@link Properties} and subclasses of {@link Properties} like {@link SortedProperties}. 35 * 36 * @param <T> {@link Properties} or a subclass like {@link SortedProperties}. 37 * @see Properties 38 * @since 4.4 39 */ 40 public abstract class AbstractPropertiesFactory<T extends Properties> { 41 42 /** 43 * Enumerates property formats. 44 * 45 * @since 4.5.0-M1 46 */ 47 public enum PropertyFormat { 48 49 /** Properties file format. */ 50 PROPERTIES, 51 52 /** XML file format. */ 53 XML; 54 55 static PropertyFormat toPropertyFormat(final String fileName) { 56 return Objects.requireNonNull(fileName, "fileName").endsWith(".xml") ? XML : PROPERTIES; 57 } 58 } 59 60 /** 61 * Constructs an instance. 62 */ 63 protected AbstractPropertiesFactory() { 64 // no init. 65 } 66 67 /** 68 * Subclasses override to provide customized properties instances. 69 * 70 * @return a new Properties instance. 71 */ 72 protected abstract T createProperties(); 73 74 /** 75 * Creates and loads properties from the given file. 76 * 77 * @param classLoader the class loader to use to get the named resource. 78 * @param name the location of the properties file. 79 * @return a new properties object. 80 * @throws IOException Thrown if an error occurred reading the input stream. 81 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 82 */ 83 public T load(final ClassLoader classLoader, final String name) throws IOException { 84 try (InputStream inputStream = classLoader.getResourceAsStream(name)) { 85 return load(inputStream, PropertyFormat.toPropertyFormat(name)); 86 } 87 } 88 89 /** 90 * Creates and loads properties from the given file. 91 * 92 * @param file the location of the properties file. 93 * @return a new properties object. 94 * @throws IOException Thrown if an error occurred reading the input stream. 95 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 96 * @throws FileNotFoundException Thrown if the file does not exist, is a directory, or cannot be opened for 97 * reading. 98 * @throws SecurityException Thrown if a security manager's {@code checkRead} method denies read access to 99 * the file. 100 */ 101 public T load(final File file) throws FileNotFoundException, IOException { 102 return load(file.toPath()); 103 } 104 105 /** 106 * Creates and loads properties from the given input stream. 107 * 108 * @param inputStream the location of the properties file. 109 * @return a new properties object. 110 * @throws IOException Thrown if an error occurred reading the input stream. 111 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 112 */ 113 public T load(final InputStream inputStream) throws IOException { 114 if (inputStream == null) { 115 return null; 116 } 117 final T properties = createProperties(); 118 properties.load(inputStream); 119 return properties; 120 } 121 122 /** 123 * Creates and loads properties from the given input stream. 124 * 125 * @param inputStream the location of the properties file. 126 * @param propertyFormat The format of the given file. 127 * @return a new properties object. 128 * @throws IOException Thrown if an error occurred reading the input stream. 129 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 130 * @since 4.5.0-M1 131 */ 132 public T load(final InputStream inputStream, final PropertyFormat propertyFormat) throws IOException { 133 if (inputStream == null) { 134 return null; 135 } 136 final T properties = createProperties(); 137 if (propertyFormat == PropertyFormat.XML) { 138 properties.loadFromXML(inputStream); 139 } else { 140 properties.load(inputStream); 141 } 142 return properties; 143 } 144 145 /** 146 * Creates and loads properties from the given path. 147 * 148 * @param path the location of the properties file. 149 * @return a new properties object. 150 * @throws IOException Thrown if an error occurred reading the input stream. 151 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 152 */ 153 public T load(final Path path) throws IOException { 154 try (InputStream inputStream = Files.newInputStream(path)) { 155 return load(inputStream, PropertyFormat.toPropertyFormat(Objects.toString(path.getFileName(), null))); 156 } 157 } 158 159 /** 160 * Creates and loads properties from the given reader. 161 * 162 * @param reader the location of the properties file. 163 * @return a new properties object. 164 * @throws IOException Thrown if an error occurred reading the input stream. 165 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 166 */ 167 public T load(final Reader reader) throws IOException { 168 final T properties = createProperties(); 169 properties.load(reader); 170 return properties; 171 } 172 173 /** 174 * Creates and loads properties from the given file name. 175 * 176 * @param name the location of the properties file. 177 * @return a new properties object. 178 * @throws IOException Thrown if an error occurred reading the input stream. 179 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 180 */ 181 public T load(final String name) throws IOException { 182 return load(Paths.get(name)); 183 } 184 185 /** 186 * Creates and loads properties from the given URI. 187 * 188 * @param uri the location of the properties file. 189 * @return a new properties object. 190 * @throws IOException Thrown if an error occurred reading the input stream. 191 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 192 */ 193 public T load(final URI uri) throws IOException { 194 return load(Paths.get(uri)); 195 } 196 197 /** 198 * Creates and loads properties from the given URL. 199 * 200 * @param url the location of the properties file. 201 * @return a new properties object. 202 * @throws IOException Thrown if an error occurred reading the input stream. 203 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 204 */ 205 public T load(final URL url) throws IOException { 206 try (InputStream inputStream = url.openStream()) { 207 return load(inputStream, PropertyFormat.toPropertyFormat(url.getFile())); 208 } 209 } 210 211 }