001package org.hl7.fhir.r5.formats;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032
033
034import java.io.IOException;
035import java.io.Writer;
036import java.math.BigDecimal;
037import java.util.ArrayList;
038import java.util.List;
039
040import org.hl7.fhir.utilities.Utilities;
041
042/**
043 * A little implementation of a json write to replace Gson .... because Gson screws up decimal values, and *we care*
044 * 
045 * @author Grahame Grieve
046 *
047 */
048public class JsonCreatorDirect implements JsonCreator {
049
050  private Writer writer;
051  private boolean pretty;
052  private boolean named;
053  private List<Boolean> valued = new ArrayList<Boolean>();
054  private int indent;
055  
056  public JsonCreatorDirect(Writer writer) {
057    super();
058    this.writer = writer;
059  }
060
061  @Override
062  public void setIndent(String indent) {
063    this.pretty = !Utilities.noString(indent);
064  }
065
066  @Override
067  public void beginObject() throws IOException {
068    checkState();
069    writer.write("{");
070    stepIn();
071    if (!valued.isEmpty()) {
072      valued.set(0, true);      
073    }
074    valued.add(0, false);
075  }
076
077  public void stepIn() throws IOException {
078    if (pretty) {
079      indent++;
080      writer.write("\r\n");
081      for (int i = 0; i < indent; i++) {
082        writer.write("  ");
083      }
084    }
085  }
086
087  public void stepOut() throws IOException {
088    if (pretty) {
089      indent--;
090      writer.write("\r\n");
091      for (int i = 0; i < indent; i++) {
092        writer.write("  ");
093      }
094    }
095  }
096
097  private void checkState() throws IOException {
098    if (named) {
099      if (pretty)
100        writer.write(" : ");
101      else
102        writer.write(":");
103      named = false;
104    }
105    if (!valued.isEmpty() && valued.get(0)) {
106      writer.write(",");
107      if (pretty) {
108        writer.write("\r\n");
109        for (int i = 0; i < indent; i++) {
110          writer.write("  ");
111        }        
112      }
113      valued.set(0, false);
114    }
115  }
116
117  @Override
118  public void endObject() throws IOException {
119    stepOut();
120    writer.write("}");    
121    valued.remove(0);
122  }
123
124  @Override
125  public void nullValue() throws IOException {
126    checkState();
127    writer.write("null");
128    valued.set(0, true);
129  }
130
131  @Override
132  public void name(String name) throws IOException {
133    checkState();
134    writer.write("\""+name+"\"");
135    named = true;
136  }
137
138  @Override
139  public void value(String value) throws IOException {
140    checkState();
141    writer.write("\""+Utilities.escapeJson(value)+"\"");    
142    valued.set(0, true);
143  }
144
145  @Override
146  public void value(Boolean value) throws IOException {
147    checkState();
148    if (value == null)
149      writer.write("null");
150    else if (value.booleanValue())
151      writer.write("true");
152    else
153      writer.write("false");
154    valued.set(0, true);
155  }
156
157  @Override
158  public void value(BigDecimal value) throws IOException {
159    checkState();
160    if (value == null)
161      writer.write("null");
162    else 
163      writer.write(value.toString());    
164    valued.set(0, true);
165  }
166
167  @Override
168  public void valueNum(String value) throws IOException {
169    checkState();
170    if (value == null)
171      writer.write("null");
172    else 
173      writer.write(value);    
174    valued.set(0, true);
175  }
176
177  @Override
178  public void value(Integer value) throws IOException {
179    checkState();
180    if (value == null)
181      writer.write("null");
182    else 
183      writer.write(value.toString());    
184    valued.set(0, true);
185  }
186
187  @Override
188  public void beginArray() throws IOException {
189    checkState();
190    writer.write("[");    
191    if (!valued.isEmpty()) {
192      valued.set(0, true);      
193    }
194    valued.add(0, false);
195  }
196
197  @Override
198  public void endArray() throws IOException {
199    writer.write("]");        
200    valued.remove(0);
201  }
202
203  @Override
204  public void finish() throws IOException {
205    writer.flush();
206  }
207
208  @Override
209  public void link(String href) {
210    // not used
211    
212  }
213
214  @Override
215  public void anchor(String name) {
216    // not used
217  }
218       
219
220}