001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.collections4.properties; 019 020import java.io.File; 021import java.io.FileInputStream; 022import java.io.FileNotFoundException; 023import java.io.IOException; 024import java.io.InputStream; 025import java.io.Reader; 026import java.net.URI; 027import java.net.URL; 028import java.nio.file.Files; 029import java.nio.file.Path; 030import java.nio.file.Paths; 031import java.util.Objects; 032import java.util.Properties; 033 034/** 035 * Subclasses create and load {@link Properties} and subclasses of {@link Properties} like {@link SortedProperties}. 036 * 037 * @param <T> {@link Properties} or a subclass like {@link SortedProperties}. 038 * @see Properties 039 * @since 4.4 040 */ 041public abstract class AbstractPropertiesFactory<T extends Properties> { 042 043 /** 044 * Enumerates property formats. 045 * 046 * @since 4.5.0-M1 047 */ 048 public enum PropertyFormat { 049 050 /** Properties file format. */ 051 PROPERTIES, 052 053 /** XML file format. */ 054 XML; 055 056 static PropertyFormat toPropertyFormat(final String fileName) { 057 return Objects.requireNonNull(fileName, "fileName").endsWith(".xml") ? XML : PROPERTIES; 058 } 059 } 060 061 /** 062 * Constructs an instance. 063 */ 064 protected AbstractPropertiesFactory() { 065 // no init. 066 } 067 068 /** 069 * Subclasses override to provide customized properties instances. 070 * 071 * @return a new Properties instance. 072 */ 073 protected abstract T createProperties(); 074 075 /** 076 * Creates and loads properties from the given file. 077 * 078 * @param classLoader the class loader to use to get the named resource. 079 * @param name the location of the properties file. 080 * @return a new properties object. 081 * @throws IOException Thrown if an error occurred reading the input stream. 082 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 083 */ 084 public T load(final ClassLoader classLoader, final String name) throws IOException { 085 try (InputStream inputStream = classLoader.getResourceAsStream(name)) { 086 return load(inputStream, PropertyFormat.toPropertyFormat(name)); 087 } 088 } 089 090 /** 091 * Creates and loads properties from the given file. 092 * 093 * @param file the location of the properties file. 094 * @return a new properties object. 095 * @throws IOException Thrown if an error occurred reading the input stream. 096 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 097 * @throws FileNotFoundException Thrown if the file does not exist, is a directory, or cannot be opened for 098 * reading. 099 * @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}