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  package org.apache.commons.vfs2.util;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.net.URL;
22  import java.util.Enumeration;
23  import java.util.Locale;
24  import java.util.Properties;
25  import java.util.ResourceBundle;
26  
27  /**
28   * A specialization of a resource bundle.
29   *
30   * @since 2.0
31   */
32  public class CombinedResources extends ResourceBundle {
33  
34      // locale.getLanguage()
35      // locale.getCountry()
36      // locale.getVariant()
37  
38      private final String resourceName;
39      private volatile boolean inited;
40      private final Properties properties = new Properties();
41  
42      /**
43       * Constructs a new instance.
44       *
45       * @param resourceName A resource name.
46       */
47      public CombinedResources(final String resourceName) {
48          this.resourceName = resourceName;
49          init();
50      }
51  
52      @Override
53      public Enumeration<String> getKeys() {
54          return new Enumeration<String>() {
55              @Override
56              public boolean hasMoreElements() {
57                  return properties.keys().hasMoreElements();
58              }
59  
60              @Override
61              public String nextElement() {
62                  // We know that our properties will only ever contain Strings
63                  return (String) properties.keys().nextElement();
64              }
65  
66          };
67      }
68  
69      /**
70       * Gets the resource name.
71       *
72       * @return the resource name.
73       */
74      public String getResourceName() {
75          return resourceName;
76      }
77  
78      @Override
79      protected Object handleGetObject(final String key) {
80          return properties.get(key);
81      }
82  
83      /**
84       * Initializes this instance.
85       */
86      protected void init() {
87          if (inited) {
88              return;
89          }
90          loadResources(getResourceName());
91          loadResources(Locale.getDefault());
92          loadResources(getLocale());
93          inited = true;
94      }
95  
96      /**
97       * Loads resources.
98       *
99       * @param locale a Locale.
100      */
101     protected void loadResources(final Locale locale) {
102         if (locale == null) {
103             return;
104         }
105         final String[] parts = {locale.getLanguage(), locale.getCountry(), locale.getVariant()};
106         final StringBuilder sb = new StringBuilder();
107         for (int i = 0; i < 3; i++) {
108             sb.append(getResourceName());
109             for (int j = 0; j < i; j++) {
110                 sb.append('_').append(parts[j]);
111             }
112             if (!parts[i].isEmpty()) {
113                 sb.append('_').append(parts[i]);
114                 loadResources(sb.toString());
115             }
116             sb.setLength(0);
117         }
118     }
119 
120     /**
121      * Loads a resource.
122      *
123      * @param resourceName the resource to load.
124      */
125     protected void loadResources(String resourceName) {
126         ClassLoader loader = getClass().getClassLoader();
127         if (loader == null) {
128             loader = ClassLoader.getSystemClassLoader();
129         }
130         if (loader != null) {
131             resourceName = resourceName.replace('.', '/') + ".properties";
132             try {
133                 final Enumeration<URL> resources = loader.getResources(resourceName);
134                 while (resources.hasMoreElements()) {
135                     final URL resource = resources.nextElement();
136                     try (InputStream inputStream = resource.openConnection().getInputStream()) {
137                         properties.load(inputStream);
138                     } catch (final IOException ignored) {
139                         // Ignore
140                     }
141                 }
142             } catch (final IOException ignored) {
143                 // Ignore
144             }
145         }
146     }
147 }