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}