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.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
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
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 }