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.FileNotFoundException; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.Reader; 025import java.net.URI; 026import java.net.URL; 027import java.nio.file.Files; 028import java.nio.file.Path; 029import java.nio.file.Paths; 030import java.util.Objects; 031import java.util.Properties; 032 033/** 034 * Subclasses create and load {@link Properties} and subclasses of {@link Properties} like {@link SortedProperties}. 035 * 036 * @param <T> {@link Properties} or a subclass like {@link SortedProperties}. 037 * @see Properties 038 * @since 4.4 039 */ 040public abstract class AbstractPropertiesFactory<T extends Properties> { 041 042 /** 043 * Enumerates property formats. 044 * 045 * @since 4.5.0-M1 046 */ 047 public enum PropertyFormat { 048 049 /** Properties file format. */ 050 PROPERTIES, 051 052 /** XML file format. */ 053 XML; 054 055 static PropertyFormat toPropertyFormat(final String fileName) { 056 return Objects.requireNonNull(fileName, "fileName").endsWith(".xml") ? XML : PROPERTIES; 057 } 058 } 059 060 /** 061 * Constructs an instance. 062 */ 063 protected AbstractPropertiesFactory() { 064 // no init. 065 } 066 067 /** 068 * Subclasses override to provide customized properties instances. 069 * 070 * @return a new Properties instance. 071 */ 072 protected abstract T createProperties(); 073 074 /** 075 * Creates and loads properties from the given file. 076 * 077 * @param classLoader the class loader to use to get the named resource. 078 * @param name the location of the properties file. 079 * @return a new properties object. 080 * @throws IOException Thrown if an error occurred reading the input stream. 081 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 082 */ 083 public T load(final ClassLoader classLoader, final String name) throws IOException { 084 try (InputStream inputStream = classLoader.getResourceAsStream(name)) { 085 return load(inputStream, PropertyFormat.toPropertyFormat(name)); 086 } 087 } 088 089 /** 090 * Creates and loads properties from the given file. 091 * 092 * @param file the location of the properties file. 093 * @return a new properties object. 094 * @throws IOException Thrown if an error occurred reading the input stream. 095 * @throws IllegalArgumentException Thrown if the input contains a malformed Unicode escape sequence. 096 * @throws FileNotFoundException Thrown if the file does not exist, is a directory, or cannot be opened for 097 * reading. 098 * @throws SecurityException Thrown if a security manager's {@code checkRead} method denies read access to 099 * 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}