a0b76b1e415bf2b4c6e82ca7c16a0989f89ed81b
[packages/precise/mcollective.git] / lib / mcollective / vendor / json / java / src / json / ext / OptionsReader.java
1 /*
2  * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3  *
4  * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5  * for details.
6  */
7 package json.ext;
8
9 import org.jruby.Ruby;
10 import org.jruby.RubyClass;
11 import org.jruby.RubyHash;
12 import org.jruby.RubyNumeric;
13 import org.jruby.RubyString;
14 import org.jruby.runtime.ThreadContext;
15 import org.jruby.runtime.builtin.IRubyObject;
16 import org.jruby.util.ByteList;
17
18 final class OptionsReader {
19     private final ThreadContext context;
20     private final Ruby runtime;
21     private final RubyHash opts;
22     private RuntimeInfo info;
23
24     OptionsReader(ThreadContext context, IRubyObject vOpts) {
25         this.context = context;
26         this.runtime = context.getRuntime();
27
28         if (vOpts == null || vOpts.isNil()) {
29             opts = null;
30         } else if (vOpts.respondsTo("to_hash")) {
31             opts = vOpts.convertToHash();
32         } else {
33             opts = vOpts.callMethod(context, "to_h").convertToHash();
34         }
35     }
36
37     private RuntimeInfo getRuntimeInfo() {
38         if (info != null) return info;
39         info = RuntimeInfo.forRuntime(runtime);
40         return info;
41     }
42
43     /**
44      * Efficiently looks up items with a {@link RubySymbol Symbol} key
45      * @param key The Symbol name to look up for
46      * @return The item in the {@link RubyHash Hash}, or <code>null</code>
47      *         if not found
48      */
49     IRubyObject get(String key) {
50         return opts == null ? null : opts.fastARef(runtime.newSymbol(key));
51     }
52
53     boolean getBool(String key, boolean defaultValue) {
54         IRubyObject value = get(key);
55         return value == null ? defaultValue : value.isTrue();
56     }
57
58     int getInt(String key, int defaultValue) {
59         IRubyObject value = get(key);
60         if (value == null) return defaultValue;
61         if (!value.isTrue()) return 0;
62         return RubyNumeric.fix2int(value);
63     }
64
65     /**
66      * Reads the setting from the options hash. If no entry is set for this
67      * key or if it evaluates to <code>false</code>, returns null; attempts to
68      * coerce the value to {@link RubyString String} otherwise.
69      * @param key The Symbol name to look up for
70      * @return <code>null</code> if the key is not in the Hash or if
71      *         its value evaluates to <code>false</code>
72      * @throws RaiseException <code>TypeError</code> if the value does not
73      *                        evaluate to <code>false</code> and can't be
74      *                        converted to string
75      */
76     ByteList getString(String key) {
77         RubyString str = getString(key, null);
78         return str == null ? null : str.getByteList().dup();
79     }
80
81     RubyString getString(String key, RubyString defaultValue) {
82         IRubyObject value = get(key);
83         if (value == null || !value.isTrue()) return defaultValue;
84
85         RubyString str = value.convertToString();
86         RuntimeInfo info = getRuntimeInfo();
87         if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) {
88             str = (RubyString)str.encode(context, info.utf8.get());
89         }
90         return str;
91     }
92
93     /**
94      * Reads the setting from the options hash. If it is <code>nil</code> or
95      * undefined, returns the default value given.
96      * If not, ensures it is a RubyClass instance and shares the same
97      * allocator as the default value (i.e. for the basic types which have
98      * their specific allocators, this ensures the passed value is
99      * a subclass of them).
100      */
101     RubyClass getClass(String key, RubyClass defaultValue) {
102         IRubyObject value = get(key);
103
104         if (value == null || value.isNil()) return defaultValue;
105
106         if (value instanceof RubyClass &&
107                 ((RubyClass)value).getAllocator() == defaultValue.getAllocator()) {
108             return (RubyClass)value;
109         }
110         throw runtime.newTypeError(key + " option must be a subclass of "
111                                    + defaultValue);
112     }
113
114     public RubyHash getHash(String key) {
115         IRubyObject value = get(key);
116         if (value == null || value.isNil()) return new RubyHash(runtime);
117         return (RubyHash) value;
118     }
119 }