1 package be
.nikiroo
.jvcard
.resources
;
3 import java
.io
.BufferedWriter
;
5 import java
.io
.FileOutputStream
;
6 import java
.io
.IOException
;
7 import java
.io
.OutputStreamWriter
;
9 import java
.lang
.reflect
.Field
;
10 import java
.util
.Locale
;
11 import java
.util
.ResourceBundle
;
14 * This class help you get UTF-8 bundles for this application.
19 public class Bundles
{
20 static private String confDir
= getConfDir();
23 * The type of configuration information the associated {@link Bundle} will
30 colors
, display
, jvcard
, remote
, resources
34 * Return the configuration directory where to try to find the
35 * <tt>.properties</tt> files in priority.
37 * @return the configuration directory
39 static private String
getConfDir() {
40 // Do not override user-supplied config directory (see --help)
41 if (Bundles
.confDir
!= null)
42 return Bundles
.confDir
;
45 ResourceBundle bundle
= ResourceBundle
.getBundle(Bundles
.class
46 .getPackage().getName() + "." + "jvcard",
47 Locale
.getDefault(), new FixedResourceBundleControl(null));
49 String configDir
= bundle
.getString("CONFIG_DIR");
50 if (configDir
!= null && configDir
.trim().length() > 0)
52 } catch (Exception e
) {
59 * Set the primary configuration directory to look for <tt>.properties</tt>
62 * All {@link ResourceBundle}s returned by this class after that point will
63 * respect this new directory.
68 static public void setDirectory(String confDir
) {
69 Bundles
.confDir
= confDir
;
73 * This class encapsulate a {@link ResourceBundle} in UTF-8. It only allows
74 * to retrieve values associated to an enumeration, and allows some
80 * the enum to use to get values out of this class
82 public class Bundle
<E
extends Enum
<E
>> {
83 private Class
<E
> type
;
84 protected Target name
;
85 protected ResourceBundle map
;
88 * Create a new {@link Bundles} of the given name.
91 * a runtime instance of the class of E
94 * the name of the {@link Bundles}
96 protected Bundle(Class
<E
> type
, Target name
) {
99 this.map
= getBundle(name
);
103 * Return the value associated to the given id as a {@link String}.
106 * the id of the value to get
108 * @return the associated value
110 public String
getString(E id
) {
111 if (map
.containsKey(id
.name())) {
112 return map
.getString(id
.name()).trim();
119 * Return the value associated to the given id as a {@link Boolean}.
122 * the id of the value to get
124 * @return the associated value
126 public Boolean
getBoolean(E id
) {
127 String str
= getString(id
);
128 if (str
!= null && str
.length() > 0) {
129 if (str
.equalsIgnoreCase("true") || str
.equalsIgnoreCase("on")
130 || str
.equalsIgnoreCase("yes"))
132 if (str
.equalsIgnoreCase("false")
133 || str
.equalsIgnoreCase("off")
134 || str
.equalsIgnoreCase("no"))
143 * Return the value associated to the given id as a {@link boolean}.
146 * the id of the value to get
148 * the default value when it is not present in the config
149 * file or if it is not a boolean value
151 * @return the associated value
153 public boolean getBoolean(E id
, boolean def
) {
154 Boolean b
= getBoolean(id
);
162 * Return the value associated to the given id as an {@link Integer}.
165 * the id of the value to get
167 * @return the associated value
169 public Integer
getInteger(E id
) {
171 return Integer
.parseInt(getString(id
));
172 } catch (Exception e
) {
179 * Return the value associated to the given id as a {@link int}.
182 * the id of the value to get
184 * the default value when it is not present in the config
185 * file or if it is not a int value
187 * @return the associated value
189 public int getInteger(E id
, int def
) {
190 Integer i
= getInteger(id
);
198 * Create/update the .properties file. Will use the most likely
199 * candidate as base if the file does not already exists and this
200 * resource is translatable (for instance, "en_US" will use "en" as a
201 * base if the resource is a translation file).
204 * the path where the .properties files are
206 * @throws IOException
207 * in case of IO errors
209 public void updateFile(String path
) throws IOException
{
210 File file
= getUpdateFile(path
);
212 BufferedWriter writer
= new BufferedWriter(new OutputStreamWriter(
213 new FileOutputStream(file
), "UTF-8"));
219 for (Field field
: type
.getDeclaredFields()) {
220 Meta meta
= field
.getAnnotation(Meta
.class);
222 E id
= E
.valueOf(type
, field
.getName());
223 String info
= getMetaInfo(meta
);
230 writeValue(writer
, id
);
238 * Return formated, display-able information from the {@link Meta} field
239 * given. Each line will always starts with a "#" character.
242 * the {@link Meta} field
244 * @return the information to display or NULL if none
246 protected String
getMetaInfo(Meta meta
) {
247 String what
= meta
.what();
248 String where
= meta
.where();
249 String format
= meta
.format();
250 String info
= meta
.info();
252 int opt
= what
.length() + where
.length() + format
.length();
253 if (opt
+ info
.length() == 0)
256 StringBuilder builder
= new StringBuilder();
257 builder
.append("# ");
261 if (what
.length() > 0) {
262 builder
.append("WHAT: " + what
);
263 if (where
.length() + format
.length() > 0)
264 builder
.append(", ");
267 if (where
.length() > 0) {
268 builder
.append("WHERE: " + where
);
269 if (format
.length() > 0)
270 builder
.append(", ");
273 if (format
.length() > 0) {
274 builder
.append("FORMAT: " + format
);
278 if (info
.length() > 0) {
279 builder
.append("\n# ");
283 builder
.append(info
);
285 return builder
.toString();
289 * Write the header found in the configuration <tt>.properties</tt> file
290 * of this {@link Bundles}.
293 * the {@link Writer} to write the header in
295 * @throws IOException
296 * in case of IO error
298 protected void writeHeader(Writer writer
) throws IOException
{
299 writer
.write("# " + name
+ "\n");
304 * Write the given id to the config file, i.e.,
305 * "MY_ID = my_curent_value" followed by a new line
308 * the {@link Writer} to write into
312 * @throws IOException
313 * in case of IO error
315 protected void writeValue(Writer writer
, E id
) throws IOException
{
316 writeValue(writer
, id
.name(), getString(id
));
320 * Write the given data to the config file, i.e.,
321 * "MY_ID = my_curent_value" followed by a new line
324 * the {@link Writer} to write into
330 * @throws IOException
331 * in case of IO error
333 protected void writeValue(Writer writer
, String id
, String value
)
338 String
[] lines
= value
.replaceAll("\\\t", "\\\\\\t").split("\n");
339 for (int i
= 0; i
< lines
.length
; i
++) {
340 writer
.write(lines
[i
]);
341 if (i
< lines
.length
- 1) {
342 writer
.write("\\n\\");
349 * Return the non-localised bundle of the given name.
352 * the name of the bundle to load
356 protected ResourceBundle
getBundle(Target name
) {
357 return ResourceBundle
.getBundle(Bundles
.class.getPackage()
358 .getName() + "." + name
.name(),
359 new FixedResourceBundleControl(confDir
));
363 * Return the localised bundle of the given name and {@link Locale}.
366 * the name of the bundle to load
368 * the {@link Locale} to use
370 * @return the localised bundle
372 protected ResourceBundle
getBundle(Target name
, Locale locale
) {
373 return ResourceBundle
.getBundle(Bundles
.class.getPackage()
374 .getName() + "." + name
.name(), locale
,
375 new FixedResourceBundleControl(confDir
));
379 * Return the source file for this {@link Bundles} from the given path.
382 * the path where the .properties files are
384 * @return the source {@link File}
386 * @throws IOException
387 * in case of IO errors
389 protected File
getUpdateFile(String path
) {
390 return new File(path
, name
.name() + ".properties");