001/*
002 * This file is part of the JDrupes JSON utilities project.
003 * Copyright (C) 2017, 2018  Michael N. Lipp
004 *
005 * This program is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published
007 * by the Free Software Foundation; either version 3 of the License, or 
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful, but 
011 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
012 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
013 * License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License along 
016 * with this program; if not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.json;
020
021import java.util.HashMap;
022import java.util.Map;
023import java.util.Set;
024
025/**
026 * A view on `Map<String,Object>` that provides some utility methods
027 * for accessing the data.
028 */
029public interface JsonObject {
030
031        /**
032         * Creates a new instabnce of the {@link DefaultJsonObject}.
033         *
034         * @return the json object
035         */
036        public static JsonObject create() {
037                return new DefaultJsonObject();
038        }
039        
040        /**
041         * Creates a wrapper around an existing `Map<String,Object>`.
042         *
043         * @param backing the backing map
044         * @return the json object
045         */
046        public static JsonObject from(Map<String, Object> backing) {
047                return new JsonObjectWrapper(backing);
048        }
049        
050        /**
051         * Overloaded to ensure that an existing {@link DefaultJsonObject}
052         * is not wrapped again.
053         * 
054         * @param backing the backing object
055         * @return the argument
056         */
057        public static JsonObject from(JsonObject backing) {
058                return backing;
059        }
060
061        Map<String,Object> backing();
062
063        Set<String> fields();
064        
065        Object get(String field);
066        
067        JsonObject setField(String field, Object value);
068        
069        String asString(String field);
070        
071        int asInt(String field);
072        
073        long asLong(String field);
074        
075        boolean asBoolean(String field);
076        
077        float asFloat(String field);
078        
079        double asDouble(String field);
080
081        /**
082         * Instances of this class are used as default representations for JSON
083         * objects.
084         */
085        public static class DefaultJsonObject extends HashMap<String, Object>
086                implements JsonObject {
087                private static final long serialVersionUID = -9115687652764559620L;
088
089                public DefaultJsonObject() {
090                }
091
092                @Override
093                public Map<String,Object> backing() {
094                        return this;
095                }
096
097                /* (non-Javadoc)
098                 * @see org.jdrupes.json.JsonObject#fields()
099                 */
100                @Override
101                public Set<String> fields() {
102                        return keySet();
103                }
104
105                @Override
106                public Object get(String field) {
107                        return super.get(field);
108                }
109
110                /* (non-Javadoc)
111                 * @see org.jdrupes.json.JsonObject#setField(java.lang.String, java.lang.Object)
112                 */
113                @Override
114                public JsonObject setField(String field, Object value) {
115                        put(field, value);
116                        return this;
117                }
118
119                @Override
120                public String asString(String field) {
121                        return (String) get(field);
122                }
123
124                @Override
125                public int asInt(String field) {
126                        return (Integer) get(field);
127                }
128
129                @Override
130                public long asLong(String field) {
131                        return (Long) get(field);
132                }
133
134                @Override
135                public boolean asBoolean(String field) {
136                        return (Boolean) get(field);
137                }
138
139                @Override
140                public float asFloat(String field) {
141                        return (Float) get(field);
142                }
143
144                @Override
145                public double asDouble(String field) {
146                        return (Double) get(field);
147                }
148        }
149        
150        public static class JsonObjectWrapper implements JsonObject {
151
152                private Map<String, Object> backing;
153
154                private JsonObjectWrapper(Map<String, Object> backing) {
155                        this.backing = backing;
156                }
157
158                @Override
159                public Map<String, Object> backing() {
160                        return backing;
161                }
162
163                /* (non-Javadoc)
164                 * @see org.jdrupes.json.JsonObject#fields()
165                 */
166                @Override
167                public Set<String> fields() {
168                        return backing.keySet();
169                }
170
171                @Override
172                public Object get(String field) {
173                        return backing.get(field);
174                }
175
176                /* (non-Javadoc)
177                 * @see org.jdrupes.json.JsonObject#setField(java.lang.String, java.lang.Object)
178                 */
179                @Override
180                public JsonObject setField(String field, Object value) {
181                        backing.put(field, value);
182                        return this;
183                }
184
185                @Override
186                public String asString(String field) {
187                        return (String)backing.get(field);
188                }
189
190                @Override
191                public int asInt(String field) {
192                        return (Integer)backing.get(field);
193                }
194
195                @Override
196                public long asLong(String field) {
197                        return (Long)backing.get(field);
198                }
199
200                @Override
201                public boolean asBoolean(String field) {
202                        return (Boolean)backing.get(field);
203                }
204
205                @Override
206                public float asFloat(String field) {
207                        return (Float)backing.get(field);
208                }
209
210                @Override
211                public double asDouble(String field) {
212                        return (Double)backing.get(field);
213                }
214        }
215}