001package ca.uhn.fhir.parser.json;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import java.io.IOException;
024import java.io.Writer;
025import java.math.BigDecimal;
026import java.math.BigInteger;
027import java.util.Stack;
028
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032import com.google.gson.stream.JsonWriter;
033
034public class GsonWriter extends JsonLikeWriter {
035        private static final Logger log = LoggerFactory.getLogger(GsonWriter.class);
036
037        private JsonWriter eventWriter;
038        private enum BlockType {
039                NONE, OBJECT, ARRAY
040        }
041        private BlockType blockType = BlockType.NONE;
042        private Stack<BlockType> blockStack = new Stack<BlockType>(); 
043
044        public GsonWriter () {
045                super();
046        }
047        public GsonWriter (Writer writer) {
048                setWriter(writer);
049        }
050
051        @Override
052        public JsonLikeWriter init() throws IOException {
053                eventWriter = new JsonWriter(getWriter());
054                eventWriter.setSerializeNulls(true);
055                if (isPrettyPrint()) {
056                        eventWriter.setIndent("  ");
057                }
058                blockType = BlockType.NONE;
059                blockStack.clear();
060                return this;
061        }
062
063        @Override
064        public JsonLikeWriter flush() throws IOException {
065                if (blockType != BlockType.NONE) {
066                        log.error("JsonLikeStreamWriter.flush() called but JSON document is not finished");
067                }
068                eventWriter.flush();
069                getWriter().flush();
070                return this;
071        }
072
073        @Override
074        public void close() throws IOException {
075                eventWriter.close();
076                getWriter().close();
077        }
078
079        @Override
080        public JsonLikeWriter beginObject() throws IOException {
081                blockStack.push(blockType);
082                blockType = BlockType.OBJECT;
083                eventWriter.beginObject();
084                return this;
085        }
086
087        @Override
088        public JsonLikeWriter beginArray() throws IOException {
089                blockStack.push(blockType);
090                blockType = BlockType.ARRAY;
091                eventWriter.beginArray();
092                return this;
093        }
094
095        @Override
096        public JsonLikeWriter beginObject(String name) throws IOException {
097                blockStack.push(blockType);
098                blockType = BlockType.OBJECT;
099                eventWriter.name(name);
100                eventWriter.beginObject();
101                return this;
102        }
103
104        @Override
105        public JsonLikeWriter beginArray(String name) throws IOException {
106                blockStack.push(blockType);
107                blockType = BlockType.ARRAY;
108                eventWriter.name(name);
109                eventWriter.beginArray();
110                return this;
111        }
112
113        @Override
114        public JsonLikeWriter write(String value) throws IOException {
115                eventWriter.value(value);
116                return this;
117        }
118
119        @Override
120        public JsonLikeWriter write(BigInteger value) throws IOException {
121                eventWriter.value(value);
122                return this;
123        }
124        
125        @Override
126        public JsonLikeWriter write(BigDecimal value) throws IOException {
127                eventWriter.value(value);
128                return this;
129        }
130
131        @Override
132        public JsonLikeWriter write(long value) throws IOException {
133                eventWriter.value(value);
134                return this;
135        }
136
137        @Override
138        public JsonLikeWriter write(double value) throws IOException {
139                eventWriter.value(value);
140                return this;
141        }
142
143        @Override
144        public JsonLikeWriter write(Boolean value) throws IOException {
145                eventWriter.value(value);
146                return this;
147        }
148
149        @Override
150        public JsonLikeWriter write(boolean value) throws IOException {
151                eventWriter.value(value);
152                return this;
153        }
154
155        @Override
156        public JsonLikeWriter writeNull() throws IOException {
157                eventWriter.nullValue();
158                return this;
159        }
160
161        @Override
162        public JsonLikeWriter write(String name, String value) throws IOException {
163                eventWriter.name(name);
164                eventWriter.value(value);
165                return this;
166        }
167
168        @Override
169        public JsonLikeWriter write(String name, BigInteger value) throws IOException {
170                eventWriter.name(name);
171                eventWriter.value(value);
172                return this;
173        }
174        @Override
175        public JsonLikeWriter write(String name, BigDecimal value) throws IOException {
176                eventWriter.name(name);
177                eventWriter.value(value);
178                return this;
179        }
180
181        @Override
182        public JsonLikeWriter write(String name, long value) throws IOException {
183                eventWriter.name(name);
184                eventWriter.value(value);
185                return this;
186        }
187
188        @Override
189        public JsonLikeWriter write(String name, double value) throws IOException {
190                eventWriter.name(name);
191                eventWriter.value(value);
192                return this;
193        }
194
195        @Override
196        public JsonLikeWriter write(String name, Boolean value) throws IOException {
197                eventWriter.name(name);
198                eventWriter.value(value);
199                return this;
200        }
201
202        @Override
203        public JsonLikeWriter write(String name, boolean value) throws IOException {
204                eventWriter.name(name);
205                eventWriter.value(value);
206                return this;
207        }
208
209        @Override
210        public JsonLikeWriter writeNull(String name) throws IOException {
211                eventWriter.name(name);
212                eventWriter.nullValue();
213                return this;
214        }
215
216        @Override
217        public JsonLikeWriter endObject() throws IOException {
218                if (blockType == BlockType.NONE) {
219                        log.error("JsonLikeStreamWriter.endObject(); called with no active JSON document");
220                } else {
221                        if (blockType != BlockType.OBJECT) {
222                                log.error("JsonLikeStreamWriter.endObject(); called outside a JSON object. (Use endArray() instead?)");
223                                eventWriter.endArray();
224                        } else {
225                                eventWriter.endObject();
226                        }
227                        blockType = blockStack.pop();
228                }
229                return this;
230        }
231
232        @Override
233        public JsonLikeWriter endArray() throws IOException {
234                if (blockType == BlockType.NONE) {
235                        log.error("JsonLikeStreamWriter.endArray(); called with no active JSON document");
236                } else {
237                        if (blockType != BlockType.ARRAY) {
238                                log.error("JsonLikeStreamWriter.endArray(); called outside a JSON array. (Use endObject() instead?)");
239                                eventWriter.endObject();
240                        } else {
241                                eventWriter.endArray();
242                        }
243                        blockType = blockStack.pop();
244                }
245                return this;
246        }
247
248        @Override
249        public JsonLikeWriter endBlock() throws IOException {
250                if (blockType == BlockType.NONE) {
251                        log.error("JsonLikeStreamWriter.endBlock(); called with no active JSON document");
252                } else {
253                        if (blockType == BlockType.ARRAY) {
254                                eventWriter.endArray();
255                        } else {
256                                eventWriter.endObject();
257                        }
258                        blockType = blockStack.pop();
259                }
260                return this;
261        }
262
263}