View Javadoc
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 }