001package org.hl7.fhir.r4.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
032import java.io.ByteArrayInputStream;
033import java.io.ByteArrayOutputStream;
034import java.io.IOException;
035import java.math.BigDecimal;
036import java.nio.charset.StandardCharsets;
037import java.text.ParseException;
038import java.util.HashMap;
039import java.util.Map;
040
041import org.apache.commons.codec.binary.Base64;
042import org.hl7.fhir.exceptions.FHIRFormatError;
043import org.hl7.fhir.r4.model.Resource;
044import org.hl7.fhir.r4.model.Type;
045import org.hl7.fhir.utilities.Utilities;
046
047public abstract class ParserBase extends FormatUtilities implements IParser {
048
049  // -- implementation of variant type methods from the interface
050  // --------------------------------
051
052  public Resource parse(String input) throws FHIRFormatError, IOException {
053    return parse(input.getBytes(StandardCharsets.UTF_8));
054  }
055
056  public Resource parse(byte[] bytes) throws FHIRFormatError, IOException {
057    ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
058    return parse(bi);
059  }
060
061  public Type parseType(String input, String typeName) throws FHIRFormatError, IOException {
062    return parseType(input.getBytes(StandardCharsets.UTF_8), typeName);
063  }
064
065  public Type parseAnyType(String input, String typeName) throws FHIRFormatError, IOException {
066    return parseAnyType(input.getBytes(StandardCharsets.UTF_8), typeName);
067  }
068
069  public Type parseType(byte[] bytes, String typeName) throws FHIRFormatError, IOException {
070    ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
071    return parseType(bi, typeName);
072  }
073
074  public Type parseAnyType(byte[] bytes, String typeName) throws FHIRFormatError, IOException {
075    ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
076    return parseAnyType(bi, typeName);
077  }
078
079  public String composeString(Resource resource) throws IOException {
080    return new String(composeBytes(resource), StandardCharsets.UTF_8);
081  }
082
083  public byte[] composeBytes(Resource resource) throws IOException {
084    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
085    compose(bytes, resource);
086    bytes.close();
087    return bytes.toByteArray();
088  }
089
090  public String composeString(Type type, String typeName) throws IOException {
091    return new String(composeBytes(type, typeName), StandardCharsets.UTF_8);
092  }
093
094  public byte[] composeBytes(Type type, String typeName) throws IOException {
095    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
096    compose(bytes, type, typeName);
097    bytes.close();
098    return bytes.toByteArray();
099  }
100
101  // -- Parser Configuration --------------------------------
102
103  protected String xhtmlMessage;
104
105  @Override
106  public IParser setSuppressXhtml(String message) {
107    xhtmlMessage = message;
108    return this;
109  }
110
111  protected boolean handleComments = false;
112
113  public boolean getHandleComments() {
114    return handleComments;
115  }
116
117  public IParser setHandleComments(boolean value) {
118    this.handleComments = value;
119    return this;
120  }
121
122  /**
123   * Whether to throw an exception if unknown content is found (or just skip it)
124   */
125  protected boolean allowUnknownContent;
126
127  /**
128   * whether to allow comments in the json (special case for IG publisher source)
129   */
130  protected boolean allowComments;
131
132  /**
133   * @return Whether to throw an exception if unknown content is found (or just
134   *         skip it)
135   */
136  public boolean isAllowUnknownContent() {
137    return allowUnknownContent;
138  }
139
140  /**
141   * @param allowUnknownContent Whether to throw an exception if unknown content
142   *                            is found (or just skip it)
143   */
144  public IParser setAllowUnknownContent(boolean allowUnknownContent) {
145    this.allowUnknownContent = allowUnknownContent;
146    return this;
147  }
148
149  public boolean isAllowComments() {
150    return allowComments;
151  }
152
153  public void setAllowComments(boolean allowComments) {
154    this.allowComments = allowComments;
155  }
156
157  protected OutputStyle style = OutputStyle.NORMAL;
158
159  public OutputStyle getOutputStyle() {
160    return style;
161  }
162
163  public IParser setOutputStyle(OutputStyle style) {
164    this.style = style;
165    return this;
166  }
167
168  // -- Parser Utilities --------------------------------
169
170  protected Map<String, Object> idMap = new HashMap<String, Object>();
171
172  protected int parseIntegerPrimitive(String value) {
173    if (value.startsWith("+") && Utilities.isInteger(value.substring(1)))
174      value = value.substring(1);
175    return java.lang.Integer.parseInt(value);
176  }
177
178  protected int parseIntegerPrimitive(java.lang.Long value) {
179    if (value < java.lang.Integer.MIN_VALUE || value > java.lang.Integer.MAX_VALUE) {
180      throw new IllegalArgumentException(value + " cannot be cast to int without changing its value.");
181    }
182    return value.intValue();
183  }
184
185  protected String parseCodePrimitive(String value) {
186    return value;
187  }
188
189  protected String parseTimePrimitive(String value) throws ParseException {
190    return value;
191  }
192
193  protected BigDecimal parseDecimalPrimitive(BigDecimal value) {
194    return value;
195  }
196
197  protected BigDecimal parseDecimalPrimitive(String value) {
198    return new BigDecimal(value);
199  }
200
201  protected String parseUriPrimitive(String value) {
202    return value;
203  }
204
205  protected byte[] parseBase64BinaryPrimitive(String value) {
206    return Base64.decodeBase64(value.getBytes());
207  }
208
209  protected String parseOidPrimitive(String value) {
210    return value;
211  }
212
213  protected Boolean parseBooleanPrimitive(String value) {
214    return java.lang.Boolean.valueOf(value);
215  }
216
217  protected Boolean parseBooleanPrimitive(Boolean value) {
218    return java.lang.Boolean.valueOf(value);
219  }
220
221  protected String parseIdPrimitive(String value) {
222    return value;
223  }
224
225  protected String parseStringPrimitive(String value) {
226    return value;
227  }
228
229  protected String parseUuidPrimitive(String value) {
230    return value;
231  }
232
233}