diff --git a/javagen/src/main/java/com/azure/autorest/template/ConvenienceMethodTemplateBase.java b/javagen/src/main/java/com/azure/autorest/template/ConvenienceMethodTemplateBase.java index 5b8fb75966..76bb55696c 100644 --- a/javagen/src/main/java/com/azure/autorest/template/ConvenienceMethodTemplateBase.java +++ b/javagen/src/main/java/com/azure/autorest/template/ConvenienceMethodTemplateBase.java @@ -655,74 +655,76 @@ private static String expressionMultipartFormDataToBinaryData(String name, Clien StringBuilder builder = new StringBuilder().append("new MultipartFormDataHelper(requestOptions)"); for (ClientModelProperty property : model.getProperties()) { String propertyGetExpression = name + "." + property.getGetterName() + "()"; - if (isMultipartModel(property.getWireType())) { - // file, usually application/octet-stream - - String fileExpression = propertyGetExpression + ".getContent()"; - String contentTypeExpression = propertyGetExpression + ".getContentType()"; - String filenameExpression = propertyGetExpression + ".getFilename()"; - if (!property.isRequired()) { - fileExpression = nullableExpression.apply(propertyGetExpression, fileExpression); - contentTypeExpression = nullableExpression.apply(propertyGetExpression, contentTypeExpression); - filenameExpression = nullableExpression.apply(propertyGetExpression, filenameExpression); - } + if (!property.isReadOnly()) { + if (isMultipartModel(property.getWireType())) { + // file, usually application/octet-stream + + String fileExpression = propertyGetExpression + ".getContent()"; + String contentTypeExpression = propertyGetExpression + ".getContentType()"; + String filenameExpression = propertyGetExpression + ".getFilename()"; + if (!property.isRequired()) { + fileExpression = nullableExpression.apply(propertyGetExpression, fileExpression); + contentTypeExpression = nullableExpression.apply(propertyGetExpression, contentTypeExpression); + filenameExpression = nullableExpression.apply(propertyGetExpression, filenameExpression); + } - builder.append(String.format( - ".serializeFileField(%1$s, %2$s, %3$s, %4$s)", - ClassType.STRING.defaultValueExpression(property.getSerializedName()), - fileExpression, - contentTypeExpression, - filenameExpression - )); - } else if (property.getWireType() instanceof ListType && isMultipartModel(((ListType) property.getWireType()).getElementType())) { - // file array - - // For now, we use 3 List, as we do not wish the Helper class refer to different ##FileDetails model. - // Later, if we switch to a shared class in azure-core, we can change the implementation. - String className = ((ListType) property.getWireType()).getElementType().toString(); - String streamExpressionFormat = "%1$s.stream().map(%2$s::%3$s).collect(Collectors.toList())"; - String fileExpression = String.format(streamExpressionFormat, - propertyGetExpression, className, "getContent"); - String contentTypeExpression = String.format(streamExpressionFormat, - propertyGetExpression, className, "getContentType"); - String filenameExpression = String.format(streamExpressionFormat, - propertyGetExpression, className, "getFilename"); - if (!property.isRequired()) { - fileExpression = nullableExpression.apply(propertyGetExpression, fileExpression); - contentTypeExpression = nullableExpression.apply(propertyGetExpression, contentTypeExpression); - filenameExpression = nullableExpression.apply(propertyGetExpression, filenameExpression); - } + builder.append(String.format( + ".serializeFileField(%1$s, %2$s, %3$s, %4$s)", + ClassType.STRING.defaultValueExpression(property.getSerializedName()), + fileExpression, + contentTypeExpression, + filenameExpression + )); + } else if (property.getWireType() instanceof ListType && isMultipartModel(((ListType) property.getWireType()).getElementType())) { + // file array + + // For now, we use 3 List, as we do not wish the Helper class refer to different ##FileDetails model. + // Later, if we switch to a shared class in azure-core, we can change the implementation. + String className = ((ListType) property.getWireType()).getElementType().toString(); + String streamExpressionFormat = "%1$s.stream().map(%2$s::%3$s).collect(Collectors.toList())"; + String fileExpression = String.format(streamExpressionFormat, + propertyGetExpression, className, "getContent"); + String contentTypeExpression = String.format(streamExpressionFormat, + propertyGetExpression, className, "getContentType"); + String filenameExpression = String.format(streamExpressionFormat, + propertyGetExpression, className, "getFilename"); + if (!property.isRequired()) { + fileExpression = nullableExpression.apply(propertyGetExpression, fileExpression); + contentTypeExpression = nullableExpression.apply(propertyGetExpression, contentTypeExpression); + filenameExpression = nullableExpression.apply(propertyGetExpression, filenameExpression); + } - builder.append(String.format( - ".serializeFileFields(%1$s, %2$s, %3$s, %4$s)", - ClassType.STRING.defaultValueExpression(property.getSerializedName()), - fileExpression, - contentTypeExpression, - filenameExpression - )); - } else if (ClientModelUtil.isClientModel(property.getWireType()) - || property.getWireType() instanceof MapType - || property.getWireType() instanceof IterableType) { - // application/json - builder.append(String.format( - ".serializeJsonField(%1$s, %2$s)", - ClassType.STRING.defaultValueExpression(property.getSerializedName()), - propertyGetExpression - )); - } else { - // text/plain - String stringExpression = propertyGetExpression; - // convert to String - if (property.getWireType() instanceof PrimitiveType) { - stringExpression = String.format("String.valueOf(%s)", stringExpression); - } else if (property.getWireType() != ClassType.STRING) { - stringExpression = String.format("Objects.toString(%s)", stringExpression); + builder.append(String.format( + ".serializeFileFields(%1$s, %2$s, %3$s, %4$s)", + ClassType.STRING.defaultValueExpression(property.getSerializedName()), + fileExpression, + contentTypeExpression, + filenameExpression + )); + } else if (ClientModelUtil.isClientModel(property.getWireType()) + || property.getWireType() instanceof MapType + || property.getWireType() instanceof IterableType) { + // application/json + builder.append(String.format( + ".serializeJsonField(%1$s, %2$s)", + ClassType.STRING.defaultValueExpression(property.getSerializedName()), + propertyGetExpression + )); + } else { + // text/plain + String stringExpression = propertyGetExpression; + // convert to String + if (property.getWireType() instanceof PrimitiveType) { + stringExpression = String.format("String.valueOf(%s)", stringExpression); + } else if (property.getWireType() != ClassType.STRING) { + stringExpression = String.format("Objects.toString(%s)", stringExpression); + } + builder.append(String.format( + ".serializeTextField(%1$s, %2$s)", + ClassType.STRING.defaultValueExpression(property.getSerializedName()), + stringExpression + )); } - builder.append(String.format( - ".serializeTextField(%1$s, %2$s)", - ClassType.STRING.defaultValueExpression(property.getSerializedName()), - stringExpression - )); } } builder.append(".end().getRequestBody()"); diff --git a/typespec-extension/changelog.md b/typespec-extension/changelog.md index 6c49f154fd..8a893be68f 100644 --- a/typespec-extension/changelog.md +++ b/typespec-extension/changelog.md @@ -1,5 +1,9 @@ # Release History +## 0.15.2 (2024-03-08) + +Compatible with compiler 0.54. + ## 0.15.1 (2024-03-08) Compatible with compiler 0.54. diff --git a/typespec-extension/package-lock.json b/typespec-extension/package-lock.json index 3c876cceb2..09191665a7 100644 --- a/typespec-extension/package-lock.json +++ b/typespec-extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure-tools/typespec-java", - "version": "0.15.1", + "version": "0.15.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@azure-tools/typespec-java", - "version": "0.15.1", + "version": "0.15.2", "license": "MIT", "dependencies": { "@autorest/codemodel": "~4.20.0", diff --git a/typespec-extension/package.json b/typespec-extension/package.json index 94c1e84bf7..34c7f06f81 100644 --- a/typespec-extension/package.json +++ b/typespec-extension/package.json @@ -1,6 +1,6 @@ { "name": "@azure-tools/typespec-java", - "version": "0.15.1", + "version": "0.15.2", "description": "TypeSpec library for emitting Java client from the TypeSpec REST protocol binding", "keywords": [ "TypeSpec" diff --git a/typespec-tests/package.json b/typespec-tests/package.json index 08e444931e..13f54eabcc 100644 --- a/typespec-tests/package.json +++ b/typespec-tests/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@azure-tools/cadl-ranch-specs": "0.31.2", - "@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.15.1.tgz" + "@azure-tools/typespec-java": "file:/../typespec-extension/azure-tools-typespec-java-0.15.2.tgz" }, "devDependencies": { "@typespec/prettier-plugin-typespec": "~0.54.0", diff --git a/typespec-tests/src/main/java/com/cadl/multipart/MultipartAsyncClient.java b/typespec-tests/src/main/java/com/cadl/multipart/MultipartAsyncClient.java index b7bb7b8698..9f2464ab4b 100644 --- a/typespec-tests/src/main/java/com/cadl/multipart/MultipartAsyncClient.java +++ b/typespec-tests/src/main/java/com/cadl/multipart/MultipartAsyncClient.java @@ -195,6 +195,7 @@ public Mono uploadFile(String name, FileDataFileDetails fileData) { BinaryData request = new MultipartFormDataHelper(requestOptions) .serializeFileField("file_data", requestObj.getFileData().getContent(), requestObj.getFileData().getContentType(), requestObj.getFileData().getFilename()) + .serializeTextField("constant", requestObj.getConstant()) .end() .getRequestBody(); return uploadFileWithResponse(name, request, requestOptions).flatMap(FluxUtil::toMono); diff --git a/typespec-tests/src/main/java/com/cadl/multipart/MultipartClient.java b/typespec-tests/src/main/java/com/cadl/multipart/MultipartClient.java index 735b39391c..f4897e6a2f 100644 --- a/typespec-tests/src/main/java/com/cadl/multipart/MultipartClient.java +++ b/typespec-tests/src/main/java/com/cadl/multipart/MultipartClient.java @@ -190,6 +190,7 @@ public void uploadFile(String name, FileDataFileDetails fileData) { BinaryData request = new MultipartFormDataHelper(requestOptions) .serializeFileField("file_data", requestObj.getFileData().getContent(), requestObj.getFileData().getContentType(), requestObj.getFileData().getFilename()) + .serializeTextField("constant", requestObj.getConstant()) .end() .getRequestBody(); uploadFileWithResponse(name, request, requestOptions).getValue(); diff --git a/typespec-tests/src/main/java/com/cadl/multipart/implementation/models/UploadFileRequest.java b/typespec-tests/src/main/java/com/cadl/multipart/implementation/models/UploadFileRequest.java index 4ef7baf08e..2b6c504967 100644 --- a/typespec-tests/src/main/java/com/cadl/multipart/implementation/models/UploadFileRequest.java +++ b/typespec-tests/src/main/java/com/cadl/multipart/implementation/models/UploadFileRequest.java @@ -19,6 +19,18 @@ public final class UploadFileRequest { @Generated private final FileDataFileDetails fileData; + /* + * The readOnly property. + */ + @Generated + private String readOnly; + + /* + * The constant property. + */ + @Generated + private final String constant = "constant"; + /** * Creates an instance of UploadFileRequest class. * @@ -38,4 +50,24 @@ public UploadFileRequest(FileDataFileDetails fileData) { public FileDataFileDetails getFileData() { return this.fileData; } + + /** + * Get the readOnly property: The readOnly property. + * + * @return the readOnly value. + */ + @Generated + public String getReadOnly() { + return this.readOnly; + } + + /** + * Get the constant property: The constant property. + * + * @return the constant value. + */ + @Generated + public String getConstant() { + return this.constant; + } } diff --git a/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_Send.json b/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_Send.json index f0d620bc7e..5fa30090d6 100644 --- a/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_Send.json +++ b/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_Send.json @@ -7,7 +7,8 @@ "user": { "user": "myOptionalUser" }, - "input": "myRequiredInput" + "input": "myRequiredInput", + "constant": "constant" } }, "responses": { diff --git a/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_SendLong.json b/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_SendLong.json index 451936f202..9603aaf43e 100644 --- a/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_SendLong.json +++ b/typespec-tests/tsp/examples/2022-06-01-preview/FlattenOp_SendLong.json @@ -15,7 +15,8 @@ "data_float": 14.0, "title": "title", "description": "description", - "status": "NotStarted" + "status": "NotStarted", + "constant": "constant" } }, "responses": { diff --git a/typespec-tests/tsp/multipart.tsp b/typespec-tests/tsp/multipart.tsp index 137089d8c4..1a2740320a 100644 --- a/typespec-tests/tsp/multipart.tsp +++ b/typespec-tests/tsp/multipart.tsp @@ -42,4 +42,9 @@ op uploadFile( @path name: string, @header contentType: "multipart/form-data", file_data: bytes, + + // this field should not be serialized to form-data + @visibility("read") readOnly: string, + + constant: "constant", ): OkResponse;