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.FileInputStream; 22 import java.io.FileNotFoundException; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.Reader; 26 import java.net.URI; 27 import java.net.URL; 28 import java.nio.file.Files; 29 import java.nio.file.Path; 30 import java.nio.file.Paths; 31 import java.util.Objects; 32 import java.util.Properties; 33 34 /** 35 * Subclasses create and load {@link Properties} and subclasses of {@link Properties} like {@link SortedProperties}. 36 * 37 * @param <T> {@link Properties} or a subclass like {@link SortedProperties}. 38 * @see Properties 39 * @since 4.4 40 */ 41 public abstract class AbstractPropertiesFactory<T extends Properties> { 42 43 /** 44 * Enumerates property formats. 45 * 46 * @since 4.5.0-M1 47 */ 48 public enum PropertyFormat { 49 50 /** Properties file format. */ 51 PROPERTIES, 52 53 /** XML file format. */ 54 XML; 55 56 static PropertyFormat toPropertyFormat(final String fileName) { 57 return Objects.requireNonNull(fileName, "fileName").endsWith(".xml") ? XML : PROPERTIES; 58 } 59 } 60 61 /** 62 * Constructs an instance. 63 */ 64 protected AbstractPropertiesFactory() { 65 // no init. 66 } 67 68 /** 69 * Subclasses override to provide customized properties instances. 70 * 71 * @return a new Properties instance. 72 */ 73 protected abstract T createProperties(); 74 75 /** 76 * Creates and loads properties from the given file. 77 * 78 * @param classLoader the class loader to use to get the named resource. 79 * @param name the location of the properties file. 80 * @return a new properties object. 81 * @throws IOException Thrown if an error occurred reading the input stream. 82 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 83 */ 84 public T load(final ClassLoader classLoader, final String name) throws IOException { 85 try (InputStream inputStream = classLoader.getResourceAsStream(name)) { 86 return load(inputStream, PropertyFormat.toPropertyFormat(name)); 87 } 88 } 89 90 /** 91 * Creates and loads properties from the given file. 92 * 93 * @param file the location of the properties file. 94 * @return a new properties object. 95 * @throws IOException Thrown if an error occurred reading the input stream. 96 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 97 * @throws FileNotFoundException Thrown if the file does not exist, is a directory, or cannot be opened for 98 * reading. 99 * @throws SecurityException Thrown if a security manager's {@code checkRead} method denies read access to 100 * the file. 101 */ 102 public T load(final File file) throws FileNotFoundException, IOException { 103 try (FileInputStream inputStream = new FileInputStream(file)) { 104 return load(inputStream, PropertyFormat.toPropertyFormat(file.getName())); 105 } 106 } 107 108 /** 109 * Creates and loads properties from the given input stream. 110 * 111 * @param inputStream the location of the properties file. 112 * @return a new properties object. 113 * @throws IOException Thrown if an error occurred reading the input stream. 114 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 115 */ 116 public T load(final InputStream inputStream) throws IOException { 117 if (inputStream == null) { 118 return null; 119 } 120 final T properties = createProperties(); 121 properties.load(inputStream); 122 return properties; 123 } 124 125 /** 126 * Creates and loads properties from the given input stream. 127 * 128 * @param inputStream the location of the properties file. 129 * @param propertyFormat The format of the given file. 130 * @return a new properties object. 131 * @throws IOException Thrown if an error occurred reading the input stream. 132 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 133 * @since 4.5.0-M1 134 */ 135 public T load(final InputStream inputStream, final PropertyFormat propertyFormat) throws IOException { 136 if (inputStream == null) { 137 return null; 138 } 139 final T properties = createProperties(); 140 if (propertyFormat == PropertyFormat.XML) { 141 properties.loadFromXML(inputStream); 142 } else { 143 properties.load(inputStream); 144 } 145 return properties; 146 } 147 148 /** 149 * Creates and loads properties from the given path. 150 * 151 * @param path the location of the properties file. 152 * @return a new properties object. 153 * @throws IOException Thrown if an error occurred reading the input stream. 154 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 155 */ 156 public T load(final Path path) throws IOException { 157 try (InputStream inputStream = Files.newInputStream(path)) { 158 return load(inputStream, PropertyFormat.toPropertyFormat(Objects.toString(path.getFileName(), null))); 159 } 160 } 161 162 /** 163 * Creates and loads properties from the given reader. 164 * 165 * @param reader the location of the properties file. 166 * @return a new properties object. 167 * @throws IOException Thrown if an error occurred reading the input stream. 168 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 169 */ 170 public T load(final Reader reader) throws IOException { 171 final T properties = createProperties(); 172 properties.load(reader); 173 return properties; 174 } 175 176 /** 177 * Creates and loads properties from the given file name. 178 * 179 * @param name the location of the properties file. 180 * @return a new properties object. 181 * @throws IOException Thrown if an error occurred reading the input stream. 182 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 183 */ 184 public T load(final String name) throws IOException { 185 try (FileInputStream inputStream = new FileInputStream(name)) { 186 return load(inputStream, PropertyFormat.toPropertyFormat(name)); 187 } 188 } 189 190 /** 191 * Creates and loads properties from the given URI. 192 * 193 * @param uri the location of the properties file. 194 * @return a new properties object. 195 * @throws IOException Thrown if an error occurred reading the input stream. 196 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 197 */ 198 public T load(final URI uri) throws IOException { 199 return load(Paths.get(uri)); 200 } 201 202 /** 203 * Creates and loads properties from the given URL. 204 * 205 * @param url the location of the properties file. 206 * @return a new properties object. 207 * @throws IOException Thrown if an error occurred reading the input stream. 208 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 209 */ 210 public T load(final URL url) throws IOException { 211 try (InputStream inputStream = url.openStream()) { 212 return load(inputStream, PropertyFormat.toPropertyFormat(url.getFile())); 213 } 214 } 215 216 }