This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch v3 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit e90610576fd9c2eea75c24b58100305bdf096037 Merge: 256988d313 01b4d6babf Author: Andi Huber <[email protected]> AuthorDate: Mon Apr 8 06:43:48 2024 +0200 Merge remote-tracking branch 'origin/master' into v3 antora/components/comguide/modules/ROOT/nav.adoc | 1 - .../modules/ROOT/pages/cutting-a-release.adoc | 4 +- .../modules/ROOT/pages/nightly-deploys.adoc | 641 --------------------- .../ROOT/pages/post-release-successful.adoc | 2 +- .../comguide/modules/ROOT/pages/starter-apps.adoc | 20 +- .../components/docs/modules/ROOT/pages/about.adoc | 1 - .../relnotes/modules/ROOT/pages/about.adoc | 4 +- antora/supplemental-ui/index.html | 2 +- .../facets/object/value/ValueFacetAbstract.java | 4 +- .../object/value/ValueSerializerFallback.java | 65 +++ .../images/enable-static-weaving-in-IntelliJ.png | Bin 0 -> 83860 bytes .../jpa/adoc/modules/ROOT/pages/weaving.adoc | 120 +++- .../adoc/modules/starters/pages/helloworld.adoc | 4 +- .../adoc/modules/starters/pages/simpleapp.adoc | 4 +- .../commons/model/decorators/IconDecorator.java | 2 +- .../client/ActionParameterListBuilder.java | 63 +- .../JsonValueEncoderServiceDefault.java | 65 ++- .../domainobjects/JsonValueEncoderTest.java | 4 +- .../restfulobjects/test/domain/dom/Department.java | 24 +- .../restfulobjects/test/domain/dom/Staff.java | 14 + ...IntegTest.can_create_staff_member.approved.json | 109 ++++ .../test/scenarios/staff/Staff_IntegTest.java | 102 ++++ 22 files changed, 507 insertions(+), 748 deletions(-) diff --cc viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java index eb2f2ea016,a2223b4d21..700b5a5820 --- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java +++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/ActionParameterListBuilder.java @@@ -22,11 -22,22 +22,22 @@@ import java.util.LinkedHashMap import java.util.Map; import java.util.stream.Collectors; -import javax.ws.rs.client.Entity; +import jakarta.ws.rs.client.Entity; + import org.springframework.lang.Nullable; + + import org.apache.causeway.applib.util.schema.CommonDtoUtils; + import org.apache.causeway.applib.value.Blob; + import org.apache.causeway.applib.value.Clob; import org.apache.causeway.applib.value.semantics.ValueDecomposition; + import org.apache.causeway.commons.io.JsonUtils; + import org.apache.causeway.schema.common.v2.BlobDto; + import org.apache.causeway.schema.common.v2.ClobDto; + import org.apache.causeway.schema.common.v2.ValueType; + import org.apache.causeway.schema.common.v2.ValueWithTypeDto; import lombok.Getter; + import lombok.NonNull; /** * @since 2.0 {@index} @@@ -88,9 -99,54 +99,54 @@@ public class ActionParameterListBuilde return this; } + public ActionParameterListBuilder addActionParameter(final String parameterName, final Blob blob) { + var blobDto = new BlobDto(); + blobDto.setName(blob.getName()); + blobDto.setMimeType(blob.getMimeType().getBaseType()); + blobDto.setBytes(blob.getBytes()); + var fundamentalTypeDto = new ValueWithTypeDto(); + fundamentalTypeDto.setType(ValueType.BLOB); + fundamentalTypeDto.setBlob(blobDto); + actionParameters.put(parameterName, value(CommonDtoUtils.getFundamentalValueAsJson(fundamentalTypeDto))); + actionParameterTypes.put(parameterName, Blob.class); + return this; + } + + public ActionParameterListBuilder addActionParameter(final String parameterName, final Clob clob) { + var clobDto = new ClobDto(); + clobDto.setName(clob.getName()); + clobDto.setMimeType(clob.getMimeType().getBaseType()); + clobDto.setChars(clob.asString()); + var fundamentalTypeDto = new ValueWithTypeDto(); + fundamentalTypeDto.setType(ValueType.CLOB); + fundamentalTypeDto.setClob(clobDto); + actionParameters.put(parameterName, value(CommonDtoUtils.getFundamentalValueAsJson(fundamentalTypeDto))); + actionParameterTypes.put(parameterName, Blob.class); + return this; + } + + public ActionParameterListBuilder addActionParameter(final String parameterName, + final @NonNull Map<String, Object> map) { + var nestedJson = JsonUtils.toStringUtf8(map); + actionParameters.put(parameterName, value(nestedJson)); + actionParameterTypes.put(parameterName, Map.class); + return this; + } + + public <T> ActionParameterListBuilder addActionParameter(final String parameterName, + final @NonNull Class<T> type, + final @Nullable T object) { + var nestedJson = object!=null + ? JsonUtils.toStringUtf8(object) + : "NULL"; // see ValueSerializerDefault.ENCODED_NULL + actionParameters.put(parameterName, value(nestedJson)); + actionParameterTypes.put(parameterName, type); + return this; + } + /** * For transport of {@link ValueDecomposition} over REST. - * @see RestfulClient#digestValue(javax.ws.rs.core.Response, org.apache.causeway.applib.value.semantics.ValueSemanticsProvider) + * @see RestfulClient#digestValue(jakarta.ws.rs.core.Response, org.apache.causeway.applib.value.semantics.ValueSemanticsProvider) */ public ActionParameterListBuilder addActionParameter(final String parameterName, final ValueDecomposition decomposition) { return addActionParameter(parameterName, decomposition.stringify()); diff --cc viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java index 0000000000,316fdb2e1e..489e4a0c1f mode 000000,100644..100644 --- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java +++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/staff/Staff_IntegTest.java @@@ -1,0 -1,102 +1,102 @@@ + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.causeway.viewer.restfulobjects.test.scenarios.staff; + -import javax.ws.rs.core.Response; ++import jakarta.ws.rs.core.Response; + + import org.approvaltests.Approvals; + import org.approvaltests.reporters.DiffReporter; + import org.approvaltests.reporters.UseReporter; + import org.junit.jupiter.api.Test; + + import static org.assertj.core.api.Assertions.assertThat; + + import org.springframework.transaction.annotation.Propagation; + + import org.apache.causeway.applib.value.Blob; + import org.apache.causeway.applib.value.NamedWithMimeType.CommonMimeType; + import org.apache.causeway.commons.io.DataSource; + import org.apache.causeway.viewer.restfulobjects.test.domain.dom.Department; + import org.apache.causeway.viewer.restfulobjects.test.scenarios.Abstract_IntegTest; + + import lombok.SneakyThrows; + import lombok.val; + + class Staff_IntegTest extends Abstract_IntegTest { + + @SneakyThrows + @Test + @UseReporter(DiffReporter.class) + public void can_create_staff_member() { + + // given + final var staffName = "Fred Smith"; + + final var bookmarkBeforeIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + + assertThat(bookmarkBeforeIfAny).isEmpty(); + + final Blob photo = readFileAsBlob("StaffMember-photo-Bar.pdf"); + final var requestBuilder = restfulClient.request("services/university.dept.Staff/actions/createStaffMemberWithPhoto/invoke"); + + /* + * String name, + * Department.SecondaryKey departmentSecondaryKey, + * Blob photo + */ + var args = restfulClient.arguments() + .addActionParameter("name", staffName) + //.addActionParameter("departmentSecondaryKey", Map.of("name", "Classics")) ... can be used alternatively + .addActionParameter("departmentSecondaryKey", Department.SecondaryKey.class, new Department.SecondaryKey("Classics")) + .addActionParameter("photo", photo) + .build(); + + // when + val response = requestBuilder.post(args); + + // then + assertThat(response.getStatusInfo().getFamily()).isEqualTo(Response.Status.Family.SUCCESSFUL); + assertThat(response.getStatus()).isEqualTo(Response.Status.OK.getStatusCode()); + + // and also json response + val entity = response.readEntity(String.class); + assertThat(response) + .extracting(Response::getStatus) + .isEqualTo(Response.Status.OK.getStatusCode()); + Approvals.verify(entity, jsonOptions()); + + // and also object is created in database + final var bookmarkAfterIfAny = transactionService.callTransactional(Propagation.REQUIRED, () -> { + final var staffMember = staffMemberRepository.findByName(staffName); + return bookmarkService.bookmarkFor(staffMember); + }).valueAsNonNullElseFail(); + assertThat(bookmarkAfterIfAny).isNotEmpty(); + } + + private Blob readFileAsBlob(final String fileName) { + var bytes = DataSource.ofResource(Abstract_IntegTest.class, fileName) + .bytes(); + return Blob.of(fileName, CommonMimeType.PDF, bytes); + } + + } +
