OSDN Git Service

76f6fa3d3f5bcdce716a448525bf5eecb8ca6700
[stew/Stew4.git] / src / net / argius / stew / ResourceManager.java
1 package net.argius.stew;
2
3 import java.io.*;
4 import java.text.*;
5 import java.util.*;
6 import java.util.concurrent.*;
7
8 /**
9  * ResourceManager provides a function like a ResourceBundle used UTF-8 instead Unicode escapes.
10  */
11 public final class ResourceManager {
12
13     public static final ResourceManager Default = ResourceManager.getInstance(ResourceManager0.class);
14
15     private List<Map<String, String>> list;
16
17     private ResourceManager(List<Map<String, String>> list) {
18         this.list = list;
19     }
20
21     /**
22      * Creates an instance.
23      * @param o
24      * It used as a bundle name.
25      * If String, it will use as a bundle name directly.
26      * Else if Package, it will use its package name + "messages".
27      * Otherwise, it will use as its FQCN.
28      * @return
29      */
30     public static ResourceManager getInstance(Object o) {
31         Locale loc = Locale.getDefault();
32         String[] suffixes = {"_" + loc, "_" + loc.getLanguage(), ""};
33         List<Map<String, String>> a = new ArrayList<Map<String, String>>();
34         for (final String name : getResourceNames(o)) {
35             for (final String suffix : suffixes) {
36                 final String key = name + suffix;
37                 Map<String, String> m = ResourceManager0.map.get(key);
38                 if (m == null) {
39                     m = loadResource(key, "u8p", "utf-8");
40                     if (m == null) {
41                         continue;
42                     }
43                     ResourceManager0.map.putIfAbsent(key, m);
44                 }
45                 a.add(m);
46             }
47         }
48         return new ResourceManager(a);
49     }
50
51     private static Set<String> getResourceNames(Object o) {
52         Set<String> set = new LinkedHashSet<String>();
53         String cn = null;
54         String pn = null;
55         if (o instanceof String) {
56             cn = (String)o;
57         } else if (o instanceof Package) {
58             pn = ((Package)o).getName();
59         } else if (o != null) {
60             final Class<?> c = (o instanceof Class) ? (Class<?>)o : o.getClass();
61             cn = c.getName();
62             pn = c.getPackage().getName();
63         }
64         if (cn != null) {
65             set.add(cn);
66         }
67         if (pn != null) {
68             set.add(pn + ".messages");
69         }
70         set.add(ResourceManager0.getPackageName() + ".messages");
71         return set;
72     }
73
74     private static Map<String, String> loadResource(String name, String extension, String encname) {
75         final String path = "/" + name.replace('.', '/') + '.' + extension;
76         InputStream is = ResourceManager0.getResourceAsStream(path);
77         if (is == null) {
78             return null;
79         }
80         List<String> lines = new ArrayList<String>();
81         Scanner r = new Scanner(is, encname);
82         try {
83             StringBuilder buffer = new StringBuilder();
84             while (r.hasNextLine()) {
85                 final String s = r.nextLine();
86                 if (s.matches("^\\s*#.*")) {
87                     continue;
88                 }
89                 buffer.append(s.replace("\\t", "\t").replace("\\n", "\n").replace("\\=", "="));
90                 if (s.endsWith("\\")) {
91                     buffer.setLength(buffer.length() - 1);
92                     continue;
93                 }
94                 lines.add(buffer.toString());
95                 buffer.setLength(0);
96             }
97             if (buffer.length() > 0) {
98                 lines.add(buffer.toString());
99             }
100         } finally {
101             r.close();
102         }
103         Map<String, String> m = new HashMap<String, String>();
104         for (final String s : lines) {
105             if (s.contains("=")) {
106                 String[] a = s.split("=", 2);
107                 m.put(a[0].trim(), a[1].trim().replaceFirst("\\\\$", " ").replace("\\ ", " "));
108             } else {
109                 m.put(s.trim(), "");
110             }
111         }
112         return m;
113     }
114
115     /**
116      * @param path resource's path
117      * @param defaultValue defalut value if a resource not found
118      * @return
119      */
120     public String read(String path, String defaultValue) {
121         InputStream in = ResourceManager0.getResourceAsStream(path);
122         if (in == null) {
123             return defaultValue;
124         }
125         StringBuilder buffer = new StringBuilder();
126         Scanner r = new Scanner(in);
127         try {
128             if (r.hasNextLine()) {
129                 buffer.append(r.nextLine());
130             }
131             while (r.hasNextLine()) {
132                 buffer.append(String.format("%n"));
133                 buffer.append(r.nextLine());
134             }
135         } finally {
136             r.close();
137         }
138         return buffer.toString();
139     }
140
141     private String s(String key) {
142         for (final Map<String, String> m : this.list) {
143             final String s = m.get(key);
144             if (s != null) {
145                 return s;
146             }
147         }
148         return "";
149     }
150
151     /**
152      * Returns true if this resource contains a value specified by key.
153      * @param key
154      * @return
155      */
156     public boolean containsKey(String key) {
157         for (final Map<String, String> m : this.list) {
158             if (m.containsKey(key)) {
159                 return true;
160             }
161         }
162         return false;
163     }
164
165     /**
166      * Returns the value specified by key as a String.
167      * @param key
168      * @param args
169      * @return
170      */
171     public String get(String key, Object... args) {
172         final String s = s(key);
173         return (s.length() == 0) ? key : MessageFormat.format(s, args);
174     }
175
176     /**
177      * Returns the value specified by key as a boolean.
178      * @param key
179      * @return
180      */
181     public boolean isTrue(String key) {
182         return s(key).matches("(?i)true|on|yes");
183     }
184
185     /**
186      * Returns the (initial char) value specified by key as a char.
187      * @param key
188      * @return
189      */
190     public char getChar(String key) {
191         final String s = s(key);
192         return (s.length() == 0) ? ' ' : s.charAt(0);
193     }
194
195     /**
196      * Returns the value specified by key as a int.
197      * @param key
198      * @return
199      */
200     public int getInt(String key) {
201         return getInt(key, 0);
202     }
203
204     /**
205      * Returns the value specified by key as a int.
206      * @param key
207      * @param defaultValue
208      * @return
209      */
210     public int getInt(String key, int defaultValue) {
211         final String s = s(key);
212         try {
213             return Integer.parseInt(s);
214         } catch (NumberFormatException ex) {
215             // ignore
216         }
217         return defaultValue;
218     }
219
220 }
221
222 class ResourceManager0 {
223
224     static final ConcurrentHashMap<String, Map<String, String>> map = new ConcurrentHashMap<String, Map<String, String>>();
225
226     static String getPackageName() {
227         return ResourceManager0.class.getPackage().getName();
228     }
229
230     static InputStream getResourceAsStream(String path) {
231         return ResourceManager0.class.getResourceAsStream(path);
232     }
233
234 }