diff --git a/.gitignore b/.gitignore
index 5c9e69536..704d0b089 100644
--- a/.gitignore
+++ b/.gitignore
@@ -155,3 +155,4 @@ local.properties
/org.hl7.fhir.r4/src/test/resources/graphql/*.out
/org.hl7.fhir.r4/src/main/resources/graphql/*.out
/org.hl7.fhir.r4/src/main/resources/gen
+/release_batch_template.txt
diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml
index f08c1dbdd..b5861d2a1 100644
--- a/org.hl7.fhir.convertors/pom.xml
+++ b/org.hl7.fhir.convertors/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml
index b0800bf4f..dcaa7d5f9 100644
--- a/org.hl7.fhir.dstu2/pom.xml
+++ b/org.hl7.fhir.dstu2/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml
index ddc430ad2..c82724f48 100644
--- a/org.hl7.fhir.dstu2016may/pom.xml
+++ b/org.hl7.fhir.dstu2016may/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml
index 91da3171c..de06b8cc9 100644
--- a/org.hl7.fhir.dstu3/pom.xml
+++ b/org.hl7.fhir.dstu3/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml
index 5d0855fc6..208638e73 100644
--- a/org.hl7.fhir.r4/pom.xml
+++ b/org.hl7.fhir.r4/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml
index 5e855e067..fa790a077 100644
--- a/org.hl7.fhir.r5/pom.xml
+++ b/org.hl7.fhir.r5/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/BaseWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/BaseWriter.java
new file mode 100644
index 000000000..b4277cbb4
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/BaseWriter.java
@@ -0,0 +1,70 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+public class BaseWriter {
+
+ protected JsonObject object;
+
+ public BaseWriter(JsonObject object) {
+ super();
+ this.object = object;
+ }
+
+ protected JsonObject ensureObject(String name) {
+ JsonObject child = object.getAsJsonObject(name);
+ if (child == null) {
+ child = new JsonObject();
+ object.add(name, child);
+ }
+ return child;
+ }
+
+ protected JsonObject ensureArrayObject(String arrayName, String propertyName, String value) {
+ JsonArray arr = forceArray(arrayName);
+ for (JsonElement e : arr) {
+ String s = e.getAsJsonObject().get(propertyName).getAsString();
+ if (value.equals(s))
+ return e.getAsJsonObject();
+ }
+ JsonObject e = new JsonObject();
+ arr.add(e);
+ e.addProperty(propertyName, value);
+ return e;
+ }
+
+ protected JsonArray forceArray(String arrayName) {
+ JsonArray arr = object.get(arrayName).getAsJsonArray();
+ if (arr == null) {
+ arr = new JsonArray();
+ object.add(arrayName, arr);
+ }
+ return arr;
+ }
+
+
+ protected JsonObject ensureMapObject(String mapName, String value) {
+ JsonObject map = object.getAsJsonObject(mapName);
+ if (map == null) {
+ map = new JsonObject();
+ object.add(mapName, map);
+ }
+ if (map.has(value))
+ return map.getAsJsonObject(value);
+ JsonObject e = new JsonObject();
+ map.add(value, e);
+ return e;
+ }
+
+
+ protected JsonObject ensureMapObject(String value) {
+ if (object.has(value))
+ return object.getAsJsonObject(value);
+ JsonObject e = new JsonObject();
+ object.add(value, e);
+ return e;
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ComponentsWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ComponentsWriter.java
new file mode 100644
index 000000000..b5ade6ffb
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ComponentsWriter.java
@@ -0,0 +1,20 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class ComponentsWriter extends BaseWriter {
+
+ public ComponentsWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ComponentsWriter schema(String name, JsonObject jsonSchema) {
+ ensureMapObject("schemas", name).add("$ref", jsonSchema);
+ return this;
+ }
+
+ public ComponentsWriter schemaRef(String name, String uri) {
+ ensureMapObject("schemas", name).addProperty("$ref", uri);
+ return this;
+ }
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ExternalDocsWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ExternalDocsWriter.java
new file mode 100644
index 000000000..93705e574
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ExternalDocsWriter.java
@@ -0,0 +1,21 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class ExternalDocsWriter extends BaseWriter {
+
+ public ExternalDocsWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ExternalDocsWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public ExternalDocsWriter url(String value) {
+ object.addProperty("url", value);
+ return this;
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/HeaderWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/HeaderWriter.java
new file mode 100644
index 000000000..837d00939
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/HeaderWriter.java
@@ -0,0 +1,17 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class HeaderWriter extends ParameterWriter {
+
+ public HeaderWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ParameterWriter in(ParameterLocation value) {
+ if (value != ParameterLocation.header)
+ throw new Error("Invalid value for header");
+ super.in(value);
+ return this;
+ }
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/InfoWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/InfoWriter.java
new file mode 100644
index 000000000..cfeff87a3
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/InfoWriter.java
@@ -0,0 +1,60 @@
+package org.hl7.fhir.r5.openapi;
+
+
+import org.hl7.fhir.utilities.Utilities;
+
+import com.google.gson.JsonObject;
+
+public class InfoWriter extends BaseWriter {
+
+
+ public InfoWriter(JsonObject object) {
+ super(object);
+ }
+
+ public InfoWriter title(String value) {
+ if (!Utilities.noString(value))
+ object.addProperty("title", value);
+ return this;
+ }
+
+ public InfoWriter description(String value) {
+ if (!Utilities.noString(value))
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public InfoWriter termsOfService(String value) {
+ if (!Utilities.noString(value))
+ object.addProperty("termsOfService", value);
+ return this;
+ }
+
+ public InfoWriter version(String value) {
+ if (!Utilities.noString(value))
+ object.addProperty("version", value);
+ return this;
+ }
+
+ public InfoWriter contact(String name, String email, String url) {
+ JsonObject person = new JsonObject();
+ person.addProperty("name", name);
+ if (!Utilities.noString(email))
+ person.addProperty("email", email);
+ if (!Utilities.noString(url))
+ person.addProperty("url", url);
+ object.add("contact", person);
+ return this;
+ }
+
+ public InfoWriter license(String name, String url) {
+ JsonObject license = new JsonObject();
+ license.addProperty("name", name);
+ if (!Utilities.noString(url))
+ license.addProperty("url", url);
+ object.add("license", license);
+ return this;
+ }
+
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/MediaTypeObjectWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/MediaTypeObjectWriter.java
new file mode 100644
index 000000000..04a0ad843
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/MediaTypeObjectWriter.java
@@ -0,0 +1,28 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class MediaTypeObjectWriter extends BaseWriter {
+
+ public MediaTypeObjectWriter(JsonObject object) {
+ super(object);
+ }
+
+ public MediaTypeObjectWriter schema(JsonObject jsonSchema) {
+ object.add("schema", jsonSchema);
+ return this;
+ }
+
+ public MediaTypeObjectWriter schemaRef(String uri) {
+ JsonObject schema = new JsonObject();
+ schema.addProperty("$ref", uri);
+ object.add("schema", schema);
+ return this;
+ }
+
+ public MediaTypeObjectWriter example(JsonObject example) {
+ object.add("example", example);
+ return this;
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OpenApiGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OpenApiGenerator.java
new file mode 100644
index 000000000..79a40092b
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OpenApiGenerator.java
@@ -0,0 +1,215 @@
+package org.hl7.fhir.r5.openapi;
+
+import java.util.List;
+
+import org.hl7.fhir.r5.model.CapabilityStatement;
+import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
+import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
+import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent;
+import org.hl7.fhir.r5.model.CapabilityStatement.ResourceVersionPolicy;
+import org.hl7.fhir.r5.model.CapabilityStatement.RestfulCapabilityMode;
+import org.hl7.fhir.r5.model.CapabilityStatement.TypeRestfulInteraction;
+import org.hl7.fhir.r5.model.CodeType;
+import org.hl7.fhir.r5.model.ContactDetail;
+import org.hl7.fhir.r5.model.ContactPoint;
+import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem;
+
+public class OpenApiGenerator {
+
+ private CapabilityStatement source;
+ private Writer dest;
+
+ public OpenApiGenerator(CapabilityStatement cs, Writer oa) {
+ this.source = cs;
+ this.dest = oa;
+ }
+
+ public void generate(String license) {
+ dest.info().title(source.getTitle()).description(source.getDescription()).license(license, null).version(source.getVersion());
+ if (source.hasPublisher())
+ dest.info().contact(source.getPublisher(), null, null);
+ for (ContactDetail cd : source.getContact()) {
+ dest.info().contact(cd.getName(), email(cd.getTelecom()), url(cd.getTelecom()));
+ }
+
+ if (source.hasImplementation()) {
+ dest.server(source.getImplementation().getUrl()).description(source.getImplementation().getDescription());
+ }
+ dest.externalDocs().url(source.getUrl()).description("FHIR CapabilityStatement");
+
+ for (CapabilityStatementRestComponent csr : source.getRest()) {
+ if (csr.getMode() == RestfulCapabilityMode.SERVER) {
+ generatePaths(csr);
+ }
+ }
+ }
+
+ private void generatePaths(CapabilityStatementRestComponent csr) {
+ for (CapabilityStatementRestResourceComponent r : csr.getResource())
+ generateResource(r);
+ }
+
+ private void generateResource(CapabilityStatementRestResourceComponent r) {
+ if (hasOp(r, TypeRestfulInteraction.SEARCHTYPE))
+ generateSearch(r);
+ if (hasOp(r, TypeRestfulInteraction.READ))
+ generateRead(r);
+ if (hasOp(r, TypeRestfulInteraction.VREAD))
+ generateVRead(r);
+ if (hasOp(r, TypeRestfulInteraction.UPDATE))
+ generateUpdate(r);
+ }
+
+ private void generateRead(CapabilityStatementRestResourceComponent r) {
+ OperationWriter op = makePathResId(r).operation("get");
+ op.summary("Read the current state of the resource");
+ op.operationId("read"+r.getType());
+ opOutcome(op.responses().defaultResponse());
+ ResponseObjectWriter resp = op.responses().httpResponse("200");
+ resp.description("the resource being returned");
+ if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
+ resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
+ if (isJson())
+ resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
+ if (isXml())
+ resp.content("application/fhir+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
+ }
+
+ private void generateSearch(CapabilityStatementRestResourceComponent r) {
+ OperationWriter op = makePathResType(r).operation("get");
+ op.summary("Search all resources based on a set of criteria");
+ op.operationId("search"+r.getType());
+ opOutcome(op.responses().defaultResponse());
+ ResponseObjectWriter resp = op.responses().httpResponse("200");
+ resp.description("the resource being returned");
+ if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
+ resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
+ if (isJson())
+ resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
+ if (isXml())
+ resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
+ }
+
+ private void generateVRead(CapabilityStatementRestResourceComponent r) {
+ OperationWriter op = makePathResHistId(r).operation("get");
+ op.summary("Read a past state of the resource");
+ op.operationId("vread"+r.getType());
+ opOutcome(op.responses().defaultResponse());
+ ResponseObjectWriter resp = op.responses().httpResponse("200");
+ resp.description("the resource being returned");
+ if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
+ resp.header("ETag").description("Version from Resource.meta.version as a weak ETag for that version");
+ if (isJson())
+ resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
+ if (isXml())
+ resp.content("application/fhir+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
+ }
+
+ // todo: how does prefer header affect return type?
+ private void generateUpdate(CapabilityStatementRestResourceComponent r) {
+ OperationWriter op = makePathResId(r).operation("put");
+ op.summary("Update the current state of the resource");
+ op.operationId("update"+r.getType());
+ RequestBodyWriter req = op.request();
+ req.description("The new state of the resource").required(true);
+ if (isJson())
+ req.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
+ if (isXml())
+ req.content("application/fhir+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
+
+ opOutcome(op.responses().defaultResponse());
+ ResponseObjectWriter resp = op.responses().httpResponse("200");
+ resp.description("the resource being returned after being updated");
+ if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
+ resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
+ if (isJson())
+ resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
+ if (isXml())
+ resp.content("application/fhir+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
+ }
+
+ private void opOutcome(ResponseObjectWriter resp) {
+ resp.description("Error, with details");
+ if (isJson())
+ resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/OperationOutcome");
+ if (isXml())
+ resp.content("application/fhir+xml").schemaRef(specRef()+"/OperationOutcome.xsd");
+ }
+
+ private String specRef() {
+ // todo: figure out which version we are running against
+ return "http://hl7.org/fhir/STU3";
+ }
+
+ private boolean isJson() {
+ for (CodeType f : source.getFormat()) {
+ if (f.getCode().contains("json"))
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isXml() {
+ for (CodeType f : source.getFormat()) {
+ if (f.getCode().contains("xml"))
+ return true;
+ }
+ return false;
+ }
+
+ public PathItemWriter makePathRes(CapabilityStatementRestResourceComponent r) {
+ PathItemWriter p = dest.path("/"+r.getType());
+ p.summary("Manager for resources of type "+r.getType());
+ p.description("The Manager for resources of type "+r.getType()+": provides services to manage the collection of all the "+r.getType()+" instances");
+ return p;
+ }
+
+ public PathItemWriter makePathResId(CapabilityStatementRestResourceComponent r) {
+ PathItemWriter p = dest.path("/"+r.getType()+"/{rid}");
+ p.summary("Read/Write/etc resource instance of type "+r.getType());
+ p.description("Access to services to manage the state of a single resource of type "+r.getType());
+ return p;
+ }
+
+ public PathItemWriter makePathResType(CapabilityStatementRestResourceComponent r) {
+ PathItemWriter p = dest.path("/"+r.getType());
+ p.summary("manage the collection of resources of type "+r.getType());
+ p.description("Access to services to manage the collection of all resources of type "+r.getType());
+ return p;
+ }
+
+ public PathItemWriter makePathResHistId(CapabilityStatementRestResourceComponent r) {
+ PathItemWriter p = dest.path("/"+r.getType()+"/{rid}/_history/{hid}");
+ p.summary("Read past versions of resource instance of type "+r.getType());
+ p.description("Access to previous versions of a single resource of type "+r.getType());
+ return p;
+ }
+
+ private boolean hasOp(CapabilityStatementRestResourceComponent r, TypeRestfulInteraction opCode) {
+ for (ResourceInteractionComponent op : r.getInteraction()) {
+ if (op.getCode() == opCode)
+ return true;
+ }
+ return false;
+ }
+
+ private String url(List telecom) {
+ for (ContactPoint cp : telecom) {
+ if (cp.getSystem() == ContactPointSystem.URL)
+ return cp.getValue();
+ }
+ return null;
+ }
+
+
+ private String email(List telecom) {
+ for (ContactPoint cp : telecom) {
+ if (cp.getSystem() == ContactPointSystem.EMAIL)
+ return cp.getValue();
+ }
+ return null;
+ }
+
+
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OperationWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OperationWriter.java
new file mode 100644
index 000000000..0b54fd214
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/OperationWriter.java
@@ -0,0 +1,59 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class OperationWriter extends BaseWriter {
+
+ public OperationWriter(JsonObject object) {
+ super(object);
+ }
+
+ public OperationWriter summary(String value) {
+ object.addProperty("summary", value);
+ return this;
+ }
+
+ public OperationWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+
+ public ExternalDocsWriter variable(String name) {
+ return new ExternalDocsWriter(ensureObject("externalDocs"));
+ }
+
+ public OperationWriter operationId(String value) {
+ object.addProperty("operationId", value);
+ return this;
+ }
+
+ public OperationWriter deprecated(boolean value) {
+ object.addProperty("deprecated", value);
+ return this;
+ }
+
+
+ public ServerWriter server(String url) {
+ return new ServerWriter(ensureArrayObject("servers", "url", url));
+ }
+
+ public ParameterWriter parameter(String name) {
+ return new ParameterWriter(ensureMapObject("parameters", name));
+ }
+
+ public OperationWriter pathRef(String name, String url) {
+ ensureMapObject("parameters", name).addProperty("$ref", url);
+ return this;
+ }
+
+
+ public RequestBodyWriter request() {
+ return new RequestBodyWriter(ensureObject("requestBody"));
+ }
+
+ public ResponsesWriter responses() {
+ return new ResponsesWriter(ensureObject("responses"));
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ParameterWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ParameterWriter.java
new file mode 100644
index 000000000..903c1baa8
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ParameterWriter.java
@@ -0,0 +1,80 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class ParameterWriter extends BaseWriter {
+
+ public enum ParameterLocation {
+ query, header, path, cookie;
+ }
+ public enum ParameterStyle {
+ matrix, label, form, simple, spaceDelimited, pipeDelimited, deepObject;
+ }
+
+ public ParameterWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ParameterWriter in(ParameterLocation value) {
+ object.addProperty("in", value.toString());
+ return this;
+ }
+
+
+ public ParameterWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public ParameterWriter required(boolean value) {
+ object.addProperty("required", value);
+ return this;
+ }
+
+ public ParameterWriter deprecated(boolean value) {
+ object.addProperty("deprecated", value);
+ return this;
+ }
+
+ public ParameterWriter allowEmptyValue(boolean value) {
+ object.addProperty("allowEmptyValue", value);
+ return this;
+ }
+
+
+ public ParameterWriter style(ParameterStyle value) {
+ object.addProperty("style", value.toString());
+ return this;
+ }
+
+
+ public ParameterWriter explode(boolean value) {
+ object.addProperty("explode", value);
+ return this;
+ }
+
+ public ParameterWriter allowReserved(boolean value) {
+ object.addProperty("allowReserved", value);
+ return this;
+ }
+
+
+ public ParameterWriter schema(JsonObject jsonSchema) {
+ object.add("schema", jsonSchema);
+ return this;
+ }
+
+ public ParameterWriter schemaRef(String name, String uri) {
+ JsonObject schema = new JsonObject();
+ schema.addProperty("$ref", uri);
+ object.add("schema", schema);
+ return this;
+ }
+
+
+ public ParameterWriter example(JsonObject example) {
+ object.add("example", example);
+ return this;
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/PathItemWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/PathItemWriter.java
new file mode 100644
index 000000000..f6436152e
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/PathItemWriter.java
@@ -0,0 +1,29 @@
+package org.hl7.fhir.r5.openapi;
+
+
+import com.google.gson.JsonObject;
+
+public class PathItemWriter extends BaseWriter {
+
+
+ public PathItemWriter(JsonObject object) {
+ super(object);
+ }
+
+ public PathItemWriter summary(String value) {
+ object.addProperty("summary", value);
+ return this;
+ }
+
+ public PathItemWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public OperationWriter operation(String op) {
+ return new OperationWriter(ensureMapObject(op));
+ }
+
+
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/RequestBodyWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/RequestBodyWriter.java
new file mode 100644
index 000000000..7376a2fc6
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/RequestBodyWriter.java
@@ -0,0 +1,25 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class RequestBodyWriter extends BaseWriter {
+
+ public RequestBodyWriter(JsonObject object) {
+ super(object);
+ }
+
+ public RequestBodyWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public RequestBodyWriter required(boolean value) {
+ object.addProperty("required", value);
+ return this;
+ }
+
+ public MediaTypeObjectWriter content(String type) {
+ return new MediaTypeObjectWriter(ensureMapObject("content", type));
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponseObjectWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponseObjectWriter.java
new file mode 100644
index 000000000..500d2e817
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponseObjectWriter.java
@@ -0,0 +1,25 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class ResponseObjectWriter extends BaseWriter {
+
+ public ResponseObjectWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ResponseObjectWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+
+ public HeaderWriter header(String name) {
+ return new HeaderWriter(ensureMapObject("headers", name));
+ }
+
+ public MediaTypeObjectWriter content(String type) {
+ return new MediaTypeObjectWriter(ensureMapObject("content", type));
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponsesWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponsesWriter.java
new file mode 100644
index 000000000..4ea29ca62
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ResponsesWriter.java
@@ -0,0 +1,19 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class ResponsesWriter extends BaseWriter {
+
+ public ResponsesWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ResponseObjectWriter defaultResponse() {
+ return new ResponseObjectWriter(ensureObject("default"));
+ }
+
+ public ResponseObjectWriter httpResponse(String code) {
+ return new ResponseObjectWriter(ensureMapObject(code));
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerVariableWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerVariableWriter.java
new file mode 100644
index 000000000..5ffdd5655
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerVariableWriter.java
@@ -0,0 +1,33 @@
+package org.hl7.fhir.r5.openapi;
+
+import java.util.List;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+public class ServerVariableWriter extends BaseWriter {
+
+ public ServerVariableWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ServerVariableWriter enumValue(List values) {
+ JsonArray enums = forceArray("enum");
+ for (String s : values)
+ enums.add(new JsonPrimitive(s));
+ return this;
+ }
+
+
+ public ServerVariableWriter defaultValue(String value) {
+ object.addProperty("default", value);
+ return this;
+ }
+
+ public ServerVariableWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerWriter.java
new file mode 100644
index 000000000..56dec3520
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/ServerWriter.java
@@ -0,0 +1,23 @@
+package org.hl7.fhir.r5.openapi;
+
+import org.hl7.fhir.utilities.Utilities;
+
+import com.google.gson.JsonObject;
+
+public class ServerWriter extends BaseWriter {
+
+
+ public ServerWriter(JsonObject object) {
+ super(object);
+ }
+
+ public ServerWriter description(String value) {
+ if (!Utilities.noString(value))
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public ServerVariableWriter variable(String name) {
+ return new ServerVariableWriter(ensureMapObject("variables", name));
+ }
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/TagWriter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/TagWriter.java
new file mode 100644
index 000000000..c81f02be7
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/TagWriter.java
@@ -0,0 +1,21 @@
+package org.hl7.fhir.r5.openapi;
+
+import com.google.gson.JsonObject;
+
+public class TagWriter extends BaseWriter {
+
+
+ public TagWriter(JsonObject object) {
+ super(object);
+ }
+
+ public TagWriter description(String value) {
+ object.addProperty("description", value);
+ return this;
+ }
+
+ public ExternalDocsWriter variable(String name) {
+ return new ExternalDocsWriter(ensureObject("externalDocs"));
+ }
+
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/Writer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/Writer.java
new file mode 100644
index 000000000..7e2758cad
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/openapi/Writer.java
@@ -0,0 +1,79 @@
+package org.hl7.fhir.r5.openapi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import org.hl7.fhir.utilities.TextFile;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+
+public class Writer extends BaseWriter {
+
+ private OutputStream stream;
+
+ public Writer(OutputStream stream) {
+ super( new JsonObject());
+ this.stream = stream;
+ object.addProperty("openapi", "3.0.1");
+ }
+
+ public Writer(OutputStream stream, InputStream template) throws JsonSyntaxException, IOException {
+ super(parse(template));
+ this.stream = stream;
+ object.addProperty("openapi", "3.0.1");
+ }
+
+ private static JsonObject parse(InputStream template) throws JsonSyntaxException, IOException {
+ JsonParser parser = new com.google.gson.JsonParser();
+ return parser.parse(TextFile.streamToString(template)).getAsJsonObject();
+ }
+
+ public void commit() throws IOException {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ String json = gson.toJson(object);
+ OutputStreamWriter sw = new OutputStreamWriter(stream, "UTF-8");
+ sw.write('\ufeff'); // Unicode BOM, translates to UTF-8 with the configured outputstreamwriter
+ sw.write(json);
+ sw.flush();
+ sw.close();
+ }
+
+ public InfoWriter info() {
+ return new InfoWriter(ensureObject("info"));
+ }
+
+ public PathItemWriter path(String path) {
+ return new PathItemWriter(ensureMapObject("paths", path));
+ }
+
+ public Writer pathRef(String path, String url) {
+ ensureMapObject("paths", path).addProperty("$ref", url);
+ return this;
+ }
+
+
+ public ServerWriter server(String url) {
+ return new ServerWriter(ensureArrayObject("servers", "url", url));
+ }
+
+
+ public TagWriter tag(String name) {
+ return new TagWriter(ensureArrayObject("tags", "name", name));
+ }
+
+ public ExternalDocsWriter externalDocs() {
+ return new ExternalDocsWriter(ensureObject("externalDocs"));
+ }
+
+
+ public ComponentsWriter components() {
+ return new ComponentsWriter(ensureObject("components"));
+ }
+
+}
diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml
index ea6a1cef3..850638686 100644
--- a/org.hl7.fhir.utilities/pom.xml
+++ b/org.hl7.fhir.utilities/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml
index 031aa7266..dff390266 100644
--- a/org.hl7.fhir.validation.cli/pom.xml
+++ b/org.hl7.fhir.validation.cli/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml
index 6d4606b2f..387613429 100644
--- a/org.hl7.fhir.validation/pom.xml
+++ b/org.hl7.fhir.validation/pom.xml
@@ -5,7 +5,7 @@
ca.uhn.hapi.fhir
org.hl7.fhir.core
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index d5d1c71df..9dbf15c41 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
each other. It is fine to bump the point version of this POM without affecting
HAPI FHIR.
-->
- 3.7.5-SNAPSHOT
+ 3.7.6-SNAPSHOT
3.7.0-SNAPSHOT