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 }