001/*
002 * #%L
003 * HAPI FHIR - Core Library
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.parser.json;
021
022/**
023 * This is the generalization of anything that is a "value"
024 * element in a JSON structure. This could be a JSON object,
025 * a JSON array, a scalar value (number, string, boolean),
026 * or a null.
027 *
028 */
029public abstract class BaseJsonLikeValue {
030
031        public enum ValueType {
032                ARRAY,
033                OBJECT,
034                SCALAR,
035                NULL
036        };
037
038        public enum ScalarType {
039                NUMBER,
040                STRING,
041                BOOLEAN
042        }
043
044        public abstract ValueType getJsonType();
045
046        public abstract ScalarType getDataType();
047
048        public abstract Object getValue();
049
050        public boolean isArray() {
051                return this.getJsonType() == ValueType.ARRAY;
052        }
053
054        public boolean isObject() {
055                return this.getJsonType() == ValueType.OBJECT;
056        }
057
058        public boolean isScalar() {
059                return this.getJsonType() == ValueType.SCALAR;
060        }
061
062        public boolean isString() {
063                return this.getJsonType() == ValueType.SCALAR && this.getDataType() == ScalarType.STRING;
064        }
065
066        public boolean isNumber() {
067                return this.getJsonType() == ValueType.SCALAR && this.getDataType() == ScalarType.NUMBER;
068        }
069
070        public boolean isNull() {
071                return this.getJsonType() == ValueType.NULL;
072        }
073
074        public BaseJsonLikeArray getAsArray() {
075                return null;
076        }
077
078        public BaseJsonLikeObject getAsObject() {
079                return null;
080        }
081
082        public String getAsString() {
083                return this.toString();
084        }
085
086        public Number getAsNumber() {
087                return this.isNumber() ? (Number) this.getValue() : null;
088        }
089
090        public boolean getAsBoolean() {
091                return !isNull();
092        }
093
094        public static BaseJsonLikeArray asArray(BaseJsonLikeValue element) {
095                if (element != null) {
096                        return element.getAsArray();
097                }
098                return null;
099        }
100
101        public static BaseJsonLikeObject asObject(BaseJsonLikeValue element) {
102                if (element != null) {
103                        return element.getAsObject();
104                }
105                return null;
106        }
107
108        public static String asString(BaseJsonLikeValue element) {
109                if (element != null) {
110                        return element.getAsString();
111                }
112                return null;
113        }
114
115        public static boolean asBoolean(BaseJsonLikeValue element) {
116                if (element != null) {
117                        return element.getAsBoolean();
118                }
119                return false;
120        }
121
122        public static final BaseJsonLikeValue NULL = new BaseJsonLikeValue() {
123                @Override
124                public ValueType getJsonType() {
125                        return ValueType.NULL;
126                }
127
128                @Override
129                public ScalarType getDataType() {
130                        return null;
131                }
132
133                @Override
134                public Object getValue() {
135                        return null;
136                }
137
138                @Override
139                public boolean equals(Object obj) {
140                        if (this == obj) {
141                                return true;
142                        }
143                        if (obj instanceof BaseJsonLikeValue) {
144                                return getJsonType().equals(((BaseJsonLikeValue) obj).getJsonType());
145                        }
146                        return false;
147                }
148
149                @Override
150                public int hashCode() {
151                        return "null".hashCode();
152                }
153
154                @Override
155                public String toString() {
156                        return "null";
157                }
158        };
159
160        public static final BaseJsonLikeValue TRUE = new BaseJsonLikeValue() {
161                @Override
162                public ValueType getJsonType() {
163                        return ValueType.SCALAR;
164                }
165
166                @Override
167                public ScalarType getDataType() {
168                        return ScalarType.BOOLEAN;
169                }
170
171                @Override
172                public Object getValue() {
173                        return Boolean.TRUE;
174                }
175
176                @Override
177                public boolean equals(Object obj) {
178                        if (this == obj) {
179                                return true;
180                        }
181                        if (obj instanceof BaseJsonLikeValue) {
182                                return getJsonType().equals(((BaseJsonLikeValue) obj).getJsonType())
183                                                && getDataType().equals(((BaseJsonLikeValue) obj).getDataType())
184                                                && toString().equals(((BaseJsonLikeValue) obj).toString());
185                        }
186                        return false;
187                }
188
189                @Override
190                public int hashCode() {
191                        return "true".hashCode();
192                }
193
194                @Override
195                public String toString() {
196                        return "true";
197                }
198        };
199
200        public static final BaseJsonLikeValue FALSE = new BaseJsonLikeValue() {
201                @Override
202                public ValueType getJsonType() {
203                        return ValueType.SCALAR;
204                }
205
206                @Override
207                public ScalarType getDataType() {
208                        return ScalarType.BOOLEAN;
209                }
210
211                @Override
212                public Object getValue() {
213                        return Boolean.FALSE;
214                }
215
216                @Override
217                public boolean equals(Object obj) {
218                        if (this == obj) {
219                                return true;
220                        }
221                        if (obj instanceof BaseJsonLikeValue) {
222                                return getJsonType().equals(((BaseJsonLikeValue) obj).getJsonType())
223                                                && getDataType().equals(((BaseJsonLikeValue) obj).getDataType())
224                                                && toString().equals(((BaseJsonLikeValue) obj).toString());
225                        }
226                        return false;
227                }
228
229                @Override
230                public int hashCode() {
231                        return "false".hashCode();
232                }
233
234                @Override
235                public String toString() {
236                        return "false";
237                }
238        };
239}