diff --git a/domino-rest-client/pom.xml b/domino-rest-client/pom.xml index 77de6e7..eb287f9 100644 --- a/domino-rest-client/pom.xml +++ b/domino-rest-client/pom.xml @@ -84,7 +84,6 @@ jakarta.ws.rs-api ${jax.rs.version} - org.dominokit domino-rest-jaxrs diff --git a/domino-rest-processor/src/main/java/org/dominokit/rest/processor/RequestFactorySourceWriter.java b/domino-rest-processor/src/main/java/org/dominokit/rest/processor/RequestFactorySourceWriter.java index b1c86c7..11bc147 100644 --- a/domino-rest-processor/src/main/java/org/dominokit/rest/processor/RequestFactorySourceWriter.java +++ b/domino-rest-processor/src/main/java/org/dominokit/rest/processor/RequestFactorySourceWriter.java @@ -48,6 +48,7 @@ import org.dominokit.jackson.processor.deserialization.FieldDeserializersChainBuilder; import org.dominokit.jackson.processor.serialization.FieldSerializerChainBuilder; import org.dominokit.rest.shared.MultipartForm; +import org.dominokit.rest.shared.Response; import org.dominokit.rest.shared.request.*; import org.dominokit.rest.shared.request.service.annotations.*; import org.dominokit.rest.shared.request.service.annotations.Request; @@ -668,6 +669,10 @@ private TypeMirror getMappingType(TypeMirror returnType) { return elements.getTypeElement(Void.class.getCanonicalName()).asType(); } + if (processorUtil.isAssignableFrom(returnType, jakarta.ws.rs.core.Response.class)) { + return elements.getTypeElement(Response.class.getCanonicalName()).asType(); + } + if (Type.isArray(returnType)) { return returnType; } @@ -959,6 +964,12 @@ private Optional getResponseReader(ServiceMethod serviceMethod) { "setResponseReader(response -> new $T().read(response))", TypeName.get(readerType))); return Optional.of(builder.build()); + } else if (isGenericResponse(serviceMethod)) { + + builder.addStatement( + "setResponseReader(response -> new $T().read(response))", + TypeName.get(GeneralResponseReader.class)); + return Optional.of(builder.build()); } else if (producesJson(serviceMethod)) { TypeMirror responseBeanType = getResponseBeanType(serviceMethod); @@ -997,6 +1008,10 @@ private Optional getResponseReader(ServiceMethod serviceMethod) { return Optional.empty(); } + private boolean isGenericResponse(ServiceMethod serviceMethod) { + return processorUtil.isAssignableFrom(getResponseBeanType(serviceMethod), Response.class); + } + private boolean producesJson(ServiceMethod serviceMethod) { String acceptResponse = getAcceptResponse(serviceMethod); return acceptResponse.contains(MediaType.APPLICATION_JSON) diff --git a/domino-rest-shared/pom.xml b/domino-rest-shared/pom.xml index 9950f64..c442e28 100644 --- a/domino-rest-shared/pom.xml +++ b/domino-rest-shared/pom.xml @@ -33,6 +33,7 @@ org.dominokit domino-rest-jaxrs ${project.version} + provided diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/GeneralResponseReader.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/GeneralResponseReader.java new file mode 100644 index 0000000..d99d8ab --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/GeneralResponseReader.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request; + +import org.dominokit.rest.shared.Response; + +/** Reads the response body as a {@link String} */ +public class GeneralResponseReader implements ResponseReader { + @Override + public Response read(Response response) { + return response; + } +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Consumes.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Consumes.java new file mode 100644 index 0000000..34a0634 --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Consumes.java @@ -0,0 +1,20 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +public interface Consumes { + Produces accepts(String consumes); +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/GenericRequest.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/GenericRequest.java new file mode 100644 index 0000000..6043de9 --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/GenericRequest.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +import org.dominokit.rest.shared.request.RequestMeta; +import org.dominokit.rest.shared.request.ServerRequest; + +class GenericRequest extends ServerRequest { + + public GenericRequest(RequestMeta requestMeta, R requestBean) { + super(requestMeta, requestBean); + } +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasMethod.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasMethod.java new file mode 100644 index 0000000..e674be7 --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasMethod.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +public interface HasMethod { + + HasPath withMethod(String method); +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasPath.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasPath.java new file mode 100644 index 0000000..2721c13 --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/HasPath.java @@ -0,0 +1,20 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +public interface HasPath { + Consumes withPath(String consumes); +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Produces.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Produces.java new file mode 100644 index 0000000..7cdbe61 --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/Produces.java @@ -0,0 +1,20 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +public interface Produces { + RestRequestBuilder produces(String produces); +} diff --git a/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/RestRequestBuilder.java b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/RestRequestBuilder.java new file mode 100644 index 0000000..66d907d --- /dev/null +++ b/domino-rest-shared/src/main/java/org/dominokit/rest/shared/request/builder/RestRequestBuilder.java @@ -0,0 +1,107 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.shared.request.builder; + +import static java.util.Objects.isNull; + +import java.util.Optional; +import org.dominokit.rest.shared.request.RequestMeta; +import org.dominokit.rest.shared.request.RequestWriter; +import org.dominokit.rest.shared.request.ResponseReader; +import org.dominokit.rest.shared.request.ServerRequest; + +public class RestRequestBuilder + implements HasMethod, HasPath, Consumes, Produces { + + private String key; + private Class requestClass; + private Class responseClass; + private String method; + private String consumes; + private String produce; + private String path; + private String serviceRoot = ""; + private ResponseReader responseReader = response -> null; + private RequestWriter requestWriter = request -> null; + + public static HasMethod of( + Class requestClass, Class responseClass, String key) { + RestRequestBuilder builder = new RestRequestBuilder<>(); + builder.key = key; + builder.requestClass = requestClass; + builder.responseClass = responseClass; + return builder; + } + + @Override + public HasPath withMethod(String method) { + this.method = method; + return this; + } + + @Override + public Consumes withPath(String path) { + this.path = path; + return this; + } + + @Override + public Produces accepts(String consumes) { + this.consumes = consumes; + return this; + } + + @Override + public RestRequestBuilder produces(String produces) { + this.produce = produces; + return this; + } + + public RestRequestBuilder withServiceRoot(String serviceRoot) { + this.serviceRoot = serviceRoot; + return this; + } + + public RestRequestBuilder withResponseReader(ResponseReader responseReader) { + this.responseReader = responseReader; + return this; + } + + public RestRequestBuilder withRequestWriter(RequestWriter requestWriter) { + this.requestWriter = requestWriter; + return this; + } + + public ServerRequest build() { + return build(null); + } + + public ServerRequest build(R requestBean) { + ServerRequest request = + new GenericRequest<>( + new RequestMeta(RestRequestBuilder.class, key, requestClass, responseClass), + requestBean); + request.setHttpMethod(this.method); + request.setAccept(new String[] {this.consumes}); + request.setContentType(new String[] {this.produce}); + request.setPath(this.path); + request.setServiceRoot(isNull(this.serviceRoot) ? "" : this.serviceRoot); + Optional.ofNullable(this.responseReader).ifPresent(request::setResponseReader); + Optional.ofNullable(this.requestWriter).ifPresent(request::setRequestWriter); + + return request; + } +} diff --git a/domino-rest-test/src/test/java/org/dominokit/rest/model/JakartaResponseService.java b/domino-rest-test/src/test/java/org/dominokit/rest/model/JakartaResponseService.java new file mode 100644 index 0000000..a6f747c --- /dev/null +++ b/domino-rest-test/src/test/java/org/dominokit/rest/model/JakartaResponseService.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.model; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.dominokit.rest.shared.request.service.annotations.RequestFactory; + +@RequestFactory +@Path("test") +public interface JakartaResponseService { + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + Response getResponse(); +} diff --git a/domino-rest-test/src/test/java/org/dominokit/rest/test/ResponseReturnTypeTest.java b/domino-rest-test/src/test/java/org/dominokit/rest/test/ResponseReturnTypeTest.java new file mode 100644 index 0000000..209a523 --- /dev/null +++ b/domino-rest-test/src/test/java/org/dominokit/rest/test/ResponseReturnTypeTest.java @@ -0,0 +1,44 @@ +/* + * Copyright © 2019 Dominokit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dominokit.rest.test; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.vertx.core.Vertx; +import io.vertx.junit5.VertxExtension; +import io.vertx.junit5.VertxTestContext; +import org.dominokit.rest.model.JakartaResponseServiceFactory; +import org.dominokit.rest.shared.Response; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(VertxExtension.class) +public class ResponseReturnTypeTest extends BaseRestTest { + + @Test + @DisplayName("Test using jakarta.ws.rs.core.Response as a return type") + void nullQueryParamAsEmpty(Vertx vertx, VertxTestContext testContext) { + JakartaResponseServiceFactory.INSTANCE + .getResponse() + .onSuccess( + response -> { + assertThat(Response.class.isAssignableFrom(response.getClass())); + testContext.completeNow(); + }) + .send(); + } +}