) value).entrySet())
+ ((ObjectNode) node).set(entry.getKey(), nodeFor(entry.getValue()));
+ } else if (value instanceof Number) {
+ if (value instanceof Byte)
+ node = root.numberNode((Byte) value);
+ else if (value instanceof Short)
+ node = root.numberNode((Short) value);
+ else if (value instanceof Integer)
+ node = root.numberNode((Integer) value);
+ else if (value instanceof Long)
+ node = root.numberNode((Long) value);
+ else if (value instanceof Float)
+ node = root.numberNode((Float) value);
+ else if (value instanceof Double)
+ node = root.numberNode((Double) value);
+ else if (value instanceof BigInteger)
+ node = root.numberNode((BigInteger) value);
+ else if (value instanceof BigDecimal)
+ node = root.numberNode((BigDecimal) value);
+ else
+ throw new IllegalArgumentException("unsupported number type: " + value.getClass().getSimpleName());
+ } else if (value instanceof String) {
+ node = root.textNode((String) value);
+ } else if (value instanceof byte[]) {
+ node = root.binaryNode((byte[]) value);
+ } else {
+ node = root.pojoNode(value);
+ }
+ return node;
+ }
+
+ protected JsonNodeType nodeTypeFor(Object value) {
+ JsonNodeType type;
+ if (value == null) {
+ type = JsonNodeType.NULL;
+ } else if (value instanceof Boolean) {
+ type = JsonNodeType.BOOLEAN;
+ } else if (value instanceof Number) {
+ type = JsonNodeType.NUMBER;
+ } else if (value instanceof String) {
+ type = JsonNodeType.STRING;
+ } else if (value instanceof ArrayNode || value instanceof List) {
+ type = JsonNodeType.ARRAY;
+ } else if (value instanceof byte[]) {
+ type = JsonNodeType.BINARY;
+ } else if (value instanceof ObjectNode || value instanceof Map) {
+ type = JsonNodeType.OBJECT;
+ } else {
+ type = JsonNodeType.POJO;
+ }
+ return type;
+ }
+
+ @Override
+ public JsonCache parent() {
+ return null;
+ }
+
+ protected void putNumber(ObjectNode object, String property, Number value) {
+ if (value instanceof Short) {
+ object.put(property, (Short) value);
+ } else if (value instanceof Integer) {
+ object.put(property, (Integer) value);
+ } else if (value instanceof Long) {
+ object.put(property, (Long) value);
+ } else if (value instanceof Float) {
+ object.put(property, (Float) value);
+ } else if (value instanceof Double) {
+ object.put(property, (Double) value);
+ } else if (value instanceof BigInteger) {
+ object.put(property, (BigInteger) value);
+ } else if (value instanceof BigDecimal) {
+ object.put(property, (BigDecimal) value);
+ } else {
+ throw new IllegalArgumentException(
+ "unsupported numeric value: " + value + " (" + value.getClass().getSimpleName() + ')');
+ }
+ }
+
+ @Override
+ public Root root() {
+ return this;
+ }
+
+ @Override
+ public Root save(File file) throws CacheException {
+ Objects.requireNonNull(file, "file is required");
+ file.getParentFile().mkdirs();
+ try {
+ save(new FileOutputStream(file));
+ } catch (FileNotFoundException e) {
+ throw new CacheException(e);
+ }
+ return this;
+ }
+
+ @Override
+ public Root save(OutputStream out) throws CacheException {
+ if (root == null || root.isMissingNode())
+ throw new CacheException("null or missing root node");
+ Objects.requireNonNull(out, "out is required");
+ try (OutputStream o = out) {
+ mapper.writeValue(o, root);
+ } catch (IOException e) {
+ throw new CacheException(e);
+ }
+ isDirty = false;
+ return this;
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, BigDecimal value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, BigInteger value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, boolean value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, double value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, float value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, int value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, List> values) throws CacheException {
+ // Note: if the node identified by ptr is not an array, we must create one before populating it.
+ ArrayNode array;
+ ContainerNode> container = ensureContainerExists(ptr);
+ JsonNode target = container.at(ptr.last());
+ if (target.isArray()) {
+ array = (ArrayNode) target;
+ } else {
+ String property = ptr.last().getMatchingProperty();
+ array = container.arrayNode();
+ switch (container.getNodeType()) {
+ case ARRAY:
+ int index = Integer.parseInt(property);
+ ((ArrayNode) container).set(index, array);
+ break;
+ case OBJECT:
+ ((ObjectNode) container).set(property, array);
+ break;
+ default:
+ throw new CacheException(ptr + " does not identify an array");
+ }
+ }
+
+ // Now that the target array exists, we can populate it.
+ array.removeAll();
+ for (Object value : values) {
+ JsonNode node = nodeFor(value);
+ array.add(node);
+ }
+ setDirty();
+ return this;
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, long value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, Object value) {
+ String property = ptr.last().getMatchingProperty();
+ ContainerNode> container = ensureContainerExists(ptr);
+ JsonNode node = nodeFor(value);
+ switch (container.getNodeType()) {
+ case ARRAY:
+ ArrayNode array = (ArrayNode) container;
+ int index = Integer.parseInt(property);
+ if (index < array.size()) {
+ array.set(index, node);
+ } else {
+ // Fill any gap between current size and index with nulls (Jackson doesn't support sparse arrays).
+ for (int i = array.size(); i < index; i++)
+ array.add(array.nullNode());
+ array.add(node);
+ }
+ break;
+ case OBJECT:
+ ((ObjectNode) container).set(property, node);
+ break;
+ default:
+ throw new IllegalArgumentException(ptr + " does not identify a settable container");
+ }
+ setDirty();
+ return this;
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, short value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(JsonPointer ptr, String value) {
+ return set(ptr, (Object) value);
+ }
+
+ @Override
+ public JsonCache set(String path, BigDecimal value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, BigInteger value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, boolean value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, double value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, float value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, int value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, List> values) throws CacheException {
+ return set(JsonPointer.compile(path), values);
+ }
+
+ @Override
+ public JsonCache set(String path, long value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, Object value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, short value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ @Override
+ public JsonCache set(String path, String value) {
+ return set(JsonPointer.compile(path), value);
+ }
+
+ protected void setDirty() {
+ isDirty = true;
+ isLoaded = true;
+ }
+
+ @Override
+ public int size(JsonPointer ptr) {
+ return root == null ? 0 : root.at(ptr).size();
+ }
+
+ @Override
+ public int size(String path) {
+ return size(JsonPointer.compile(path));
+ }
+
+ @Override
+ public String toString() {
+ return "JsonCacheImpl [root=" + root + ']';
+ }
+
+ @Override
+ public Root unload() {
+ isLoaded = false;
+ isDirty = false;
+ root = null;
+ return this;
+ }
+}
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/CXF2InterfaceComparator.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/CXF2InterfaceComparator.mustache
new file mode 100644
index 00000000000..d1fd0bf82c8
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/CXF2InterfaceComparator.mustache
@@ -0,0 +1,120 @@
+package {{package}};
+
+
+import java.lang.reflect.Method;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.Path;
+
+import org.apache.cxf.jaxrs.ext.ResourceComparator;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.message.Message;
+
+/**
+ * This class only help CXF to decide which resource interface is more suitable. It used Java reflexion to iterate over Java methods but it *DO NOT* select the target method.
+ */
+public class CXFInterfaceComparator implements ResourceComparator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CXFInterfaceComparator.class);
+
+ @Override
+ public int compare(ClassResourceInfo cri1, ClassResourceInfo cri2, Message message) {
+ String requestVerb = (String) message.get(Message.HTTP_REQUEST_METHOD);
+ String requestURI = (String) message.get(Message.REQUEST_URI);
+ String requestPath = requestURI.replace((String) message.get(Message.BASE_PATH), "");
+
+ // remove "/"at the end of requestPath if present
+ if (requestPath.endsWith("/")){
+ requestPath = requestPath.substring(0, requestPath.length()-1);
+ }
+
+ if (analyseInterface(cri1, requestPath, requestVerb)) {
+ return -1; // Indicate that 'cri1' interface should be preferred
+ } else if (analyseInterface(cri2, requestPath, requestVerb)) {
+ return 1; // Indicate that 'cri2' interface should be preferred
+ } else {
+ return 0; // Nothing match, leave CXF decision
+ }
+ }
+
+ /**
+ * Analyse each methods provided to check if there is a match with the
+ * message request path and request HTTP verb.
+ *
+ * @param cri
+ * the interface to be analysed
+ * @param requestPath
+ * the path of the request. Do not contains the host and base
+ * path
+ * @return true if a method match the request, false otherwise
+ */
+ private static boolean analyseInterface(ClassResourceInfo cri, String requestPath, String requestVerb) {
+ assert cri.getServiceClass() != null;
+ assert cri.getServiceClass().getInterfaces() != null;
+ assert cri.getServiceClass().getInterfaces()[0] != null;
+ assert cri.getServiceClass().getInterfaces()[0].getMethods().length > 0;
+
+ Method[] methods = cri.getServiceClass().getInterfaces()[0].getMethods();
+ // Java reflexion. Check all the methods of an interface.
+ for (Method method : methods) {
+ Path pathAnnotation = method.getAnnotation(javax.ws.rs.Path.class);
+ if (pathAnnotation != null && pathAnnotation.value() != null) {
+ String pathValue = pathAnnotation.value();
+ String methodHttpVerb = getMethodHttpVerb(method);
+
+ // Always authorize OPTIONS request if the path is matching a method declaration
+ if (requestVerb.equals(HttpMethod.OPTIONS) && match(pathValue,requestPath)) {
+ return true;
+ }
+ // Also check the HTTP verb since a single path can be match do multiple request, depending of the HTTP request verb.
+ if (requestVerb.equals(methodHttpVerb) && match(pathValue, requestPath)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static String getMethodHttpVerb(Method method) {
+ if (method.getAnnotation(javax.ws.rs.POST.class) != null) {
+ return HttpMethod.POST;
+ } else if (method.getAnnotation(javax.ws.rs.GET.class) != null) {
+ return HttpMethod.GET;
+ } else if (method.getAnnotation(javax.ws.rs.PUT.class) != null) {
+ return HttpMethod.PUT;
+ } else if (method.getAnnotation(javax.ws.rs.OPTIONS.class) != null) {
+ return HttpMethod.OPTIONS;
+ } else if (method.getAnnotation(javax.ws.rs.DELETE.class) != null) {
+ return HttpMethod.DELETE;
+ } else if (method.getAnnotation(javax.ws.rs.HEAD.class) != null) {
+ return HttpMethod.HEAD;
+ }
+ assert false;
+ return null;
+ }
+
+ /**
+ * Check whether if the pathValue match with the requestPath parameter.
+ * Every path params are considered to be declared as '{param}'. The tokens to start and close path params declaration are '{' and '}'.
+ *
+ * @param valueFromAnnotation
+ * @param valueFromRequest
+ * @return true if there is a match, false otherwise
+ */
+ private static boolean match(String valueFromAnnotation, String valueFromRequest) {
+ String patternFinal = valueFromAnnotation.replaceAll("\\{(.*?)\\}", "([^/]*)").replace("/", "\\/");
+ Matcher matcher = Pattern.compile(patternFinal).matcher(valueFromRequest);
+ if (matcher.matches()) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int compare(OperationResourceInfo ori1, OperationResourceInfo ori2, Message message) {
+ return 0; // Leave CXF decision
+ }
+}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/allowableValues.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/allowableValues.mustache
new file mode 100644
index 00000000000..a48256d027a
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/allowableValues.mustache
@@ -0,0 +1 @@
+{{#allowableValues}}allowableValues="{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}{{^values}}range=[{{#min}}{{.}}{{/min}}{{^min}}-infinity{{/min}}, {{#max}}{{.}}{{/max}}{{^max}}infinity{{/max}}]{{/values}}"{{/allowableValues}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api.mustache
new file mode 100644
index 00000000000..514f9093715
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api.mustache
@@ -0,0 +1,70 @@
+package {{package}};
+
+{{#imports}}import {{import}};
+{{/imports}}
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.MediaType;
+import org.apache.cxf.jaxrs.ext.multipart.*;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.jaxrs.PATCH;
+{{#useBeanValidation}}
+import javax.validation.constraints.*;
+import javax.validation.Valid;
+{{/useBeanValidation}}
+
+{{#appName}}
+/**
+ * {{{appName}}}
+ *
+ {{#appDescription}}
+ * {{{appDescription}}}
+ *
+ {{/appDescription}}
+ */
+{{/appName}}
+@Path("{{^useAnnotatedBasePath}}/{{/useAnnotatedBasePath}}{{#useAnnotatedBasePath}}{{contextPath}}{{/useAnnotatedBasePath}}")
+@Api(value = "/", description = "{{description}}")
+{{#addConsumesProducesJson}}
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+{{/addConsumesProducesJson}}
+public interface {{classname}} {
+{{#operations}}
+{{#operation}}
+
+ {{#summary}}
+ /**
+ * {{summary}}
+ *
+ {{#notes}}
+ * {{notes}}
+ *
+ {{/notes}}
+ */
+ {{/summary}}
+ @{{httpMethod}}
+ {{#subresourceOperation}}@Path("{{{path}}}"){{/subresourceOperation}}
+{{#hasConsumes}}
+ @Consumes({ {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} })
+{{/hasConsumes}}
+{{#hasProduces}}
+ @Produces({ {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} })
+{{/hasProduces}}
+ @ApiOperation(value = "{{{summary}}}", tags={ {{#vendorExtensions.x-tags}}"{{tag}}"{{#hasMore}}, {{/hasMore}}{{/vendorExtensions.x-tags}} })
+ @ApiResponses(value = { {{#responses}}
+ @ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{^vendorExtensions.x-java-is-response-void}}, response = {{{baseType}}}.class{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}{{/vendorExtensions.x-java-is-response-void}}){{#hasMore}},{{/hasMore}}{{/responses}} })
+ public {{>returnTypes}} {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+{{/operation}}
+}
+{{/operations}}
+
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/apiServiceImpl.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/apiServiceImpl.mustache
new file mode 100644
index 00000000000..aa92850c125
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/apiServiceImpl.mustache
@@ -0,0 +1,93 @@
+package {{package}}.impl;
+
+import {{package}}.*;
+{{#imports}}import {{import}};
+{{/imports}}
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+{{#generateOperationBody}}
+import java.io.File;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+{{#loadTestDataFromFile}}
+import org.openapitools.codegen.utils.JsonCache;
+import org.openapitools.codegen.utils.JsonCache.CacheException;
+{{/loadTestDataFromFile}}
+{{/generateOperationBody}}
+import javax.ws.rs.*;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.model.wadl.Description;
+import org.apache.cxf.jaxrs.model.wadl.DocTarget;
+
+import org.apache.cxf.jaxrs.ext.multipart.*;
+
+import io.swagger.annotations.Api;
+{{#useSpringAnnotationConfig}}
+import org.springframework.stereotype.Service;
+{{/useSpringAnnotationConfig}}
+
+{{#useSpringAnnotationConfig}}
+@Service("{{classname}}")
+{{/useSpringAnnotationConfig}}
+{{#description}}
+{{/description}}
+{{#appName}}
+/**
+ * {{{appName}}}
+ *
+ {{#appDescription}}
+ *
{{{appDescription}}}
+ {{/appDescription}}
+ *
+ */
+{{/appName}}
+public class {{classname}}ServiceImpl implements {{classname}} {
+{{#generateOperationBody}}
+{{#loadTestDataFromFile}}
+ private JsonCache cache;
+
+ {
+ try {
+ File cacheFile = new File(System.getProperty("jaxrs.test.server.json",
+ "{{testDataFile}}"));
+ cache = JsonCache.Factory.instance.get("test-data").load(cacheFile).child("/{{invokerPackage}}/{{classname}}");
+ } catch (CacheException e) {
+ e.printStackTrace();
+ }
+ }
+
+{{/loadTestDataFromFile}}
+{{/generateOperationBody}}
+{{#operations}}
+{{#operation}}
+ {{#summary}}
+ /**
+ * {{summary}}
+ *
+ {{#notes}}
+ * {{notes}}
+ *
+ {{/notes}}
+ */
+ {{/summary}}
+ @Override
+ public {{>returnTypes}} {{operationId}}({{#allParams}}{{>queryParamsImpl}}{{>pathParamsImpl}}{{>headerParamsImpl}}{{>bodyParamsImpl}}{{>formParamsImpl}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
+ {{^loadTestDataFromFile}}
+ // TODO: Implement...
+ {{/loadTestDataFromFile}}
+{{! generic response:
+ }}{{#useGenericResponse}}return Response.ok().entity("magic!").build();{{/useGenericResponse}}{{!
+non-generic response: }}{{^useGenericResponse}}{{!
+non-void response: }}{{^vendorExtensions.x-java-is-response-void}}{{!
+pre-populated operation body: }}{{#generateOperationBody}}{{{vendorExtensions.x-java-operation-body}}}{{/generateOperationBody}}{{!
+null response: }}{{^generateOperationBody}} return null;{{/generateOperationBody}}{{!
+}}{{/vendorExtensions.x-java-is-response-void}}{{!
+}}{{/useGenericResponse}}
+ }
+
+{{/operation}}
+}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api_test.mustache b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api_test.mustache
new file mode 100644
index 00000000000..c268314c97e
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-ext/api_test.mustache
@@ -0,0 +1,197 @@
+{{>licenseInfo}}
+
+package {{package}};
+
+{{#imports}}import {{import}};
+{{/imports}}
+import org.junit.Test;
+import org.junit.Before;
+import static org.junit.Assert.*;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
+import org.apache.cxf.jaxrs.client.ClientConfiguration;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+{{#useGzipFeature}}
+import org.apache.cxf.transport.common.gzip.GZIPInInterceptor;
+import org.apache.cxf.transport.common.gzip.GZIPOutInterceptor;
+{{/useGzipFeature}}
+
+{{#useLoggingFeature}}
+import org.apache.cxf.interceptor.LoggingOutInterceptor;
+{{/useLoggingFeature}}
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import com.fasterxml.jackson.jaxrs.xml.JacksonXMLProvider;
+import org.apache.cxf.jaxrs.provider.MultipartProvider;
+
+{{^fullJavaUtil}}
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+{{/fullJavaUtil}}
+
+{{#generateSpringBootApplication}}
+import org.junit.runner.RunWith;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+{{/generateSpringBootApplication}}
+{{#generateOperationBody}}
+import java.io.File;
+{{^fullJavaUtil}}
+import java.util.Set;
+{{/fullJavaUtil}}
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.junit.BeforeClass;
+{{#loadTestDataFromFile}}
+import org.openapitools.codegen.utils.JsonCache;
+{{/loadTestDataFromFile}}
+{{/generateOperationBody}}
+
+/**
+ {{#appName}}
+ * {{{appName}}}
+ *
+ {{/appName}}
+ {{#appDescription}}
+ *
{{{appDescription}}}
+ *
+ {{/appDescription}}
+ * API tests for {{classname}}.
+ */
+{{#generateSpringBootApplication}}
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+{{/generateSpringBootApplication}}
+public class {{classname}}Test {
+{{#generateOperationBody}}
+ private static Validator validator;
+{{#loadTestDataFromFile}}
+ private static JsonCache cache;
+{{/loadTestDataFromFile}}
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+{{#loadTestDataFromFile}}
+ File cacheFile = new File(System.getProperty("jaxrs.test.client.json",
+ "{{testDataFile}}"));
+ cache = JsonCache.Factory.instance.get("test-data").load(cacheFile).child("/{{invokerPackage}}/{{classname}}");
+
+{{/loadTestDataFromFile}}
+ validator = Validation.buildDefaultValidatorFactory().getValidator();
+ }
+
+{{/generateOperationBody}}
+{{#generateSpringBootApplication}}
+ @LocalServerPort
+ private int serverPort;
+{{/generateSpringBootApplication}}
+
+ private {{classname}} api;
+
+ @Before
+ public void setup() {
+ List> providers = Arrays.asList(new JacksonJsonProvider(), new JacksonXMLProvider(), new MultipartProvider());
+
+{{#generateSpringBootApplication}}
+ api = JAXRSClientFactory.create("http://localhost:" + serverPort + "/services", {{classname}}.class, providers);
+{{/generateSpringBootApplication}}
+{{^generateSpringBootApplication}}
+ api = JAXRSClientFactory.create("{{{basePath}}}", {{classname}}.class, providers);
+{{/generateSpringBootApplication}}
+ org.apache.cxf.jaxrs.client.Client client = WebClient.client(api);
+
+ ClientConfiguration config = WebClient.getConfig(client);
+{{#useGzipFeatureForTests}}
+ // Example for using Gzipping
+ GZIPOutInterceptor gzipOutInterceptor = new GZIPOutInterceptor();
+ // use Gzipping for first request sent to server
+ //gzipOutInterceptor.setForce(true);
+ config.getOutInterceptors().add(gzipOutInterceptor);
+
+ config.getInInterceptors().add(new GZIPInInterceptor());
+{{/useGzipFeatureForTests}}
+{{#useLoggingFeatureForTests}}
+ LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
+ config.getOutInterceptors().add(loggingOutInterceptor);
+{{/useLoggingFeatureForTests}}
+ }
+
+{{#generateOperationBody}}
+ private void validate(Object o) {
+ assertNotNull(o);
+ Set> violations = validator.validate(o);
+ if (!violations.isEmpty()) {
+ StringBuilder message = new StringBuilder("Validation failed");
+ for (ConstraintViolation