diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d0e58401d..ed5c369e08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix issue with generating classes with Aliases(PHP)[microsoftgraph/msgraph-beta-sdk-php#197](https://github.com/microsoftgraph/msgraph-beta-sdk-php/pull/197) - Flattens the models namespaces in Ruby to avoid circular dependencies. - Adds ObjectId as a reserved keyword in Ruby to have memory management issues. -- Replace Javax annotations in favor of Jakarta annotations for Java code generation. [#2810](https://github.com/microsoft/kiota/issues/2810) +- Replace Javax annotations in favor of Jakarta annotations for Java code generation. [#2810](https://github.com/microsoft/kiota/issues/2810) +- Remove URISyntaxException from Java generated RequestExecutors and RequestGenerators. [#3149](https://github.com/microsoft/kiota/issues/3149) ## [1.5.1] - 2023-08-08 diff --git a/src/Kiota.Builder/Refiners/JavaRefiner.cs b/src/Kiota.Builder/Refiners/JavaRefiner.cs index 3b5bfb91b8..f31a883995 100644 --- a/src/Kiota.Builder/Refiners/JavaRefiner.cs +++ b/src/Kiota.Builder/Refiners/JavaRefiner.cs @@ -209,8 +209,6 @@ private static void AddEnumSetImport(CodeElement currentElement) "java.util", "HashMap"), new (static x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestGenerator), AbstractionsNamespaceName, "RequestInformation", "RequestOption", "HttpMethod"), - new (static x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestGenerator), - "java.net", "URISyntaxException"), new (static x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestGenerator), "java.util", "Collection", "Map"), new (static x => x is CodeClass @class && @class.IsOfKind(CodeClassKind.Model), diff --git a/src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs index 0a771da7ed..5af2bbf8ad 100644 --- a/src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Java/CodeMethodWriter.cs @@ -17,13 +17,12 @@ public override void WriteCodeElement(CodeMethod codeElement, LanguageWriter wri if (codeElement.Parent is not CodeClass parentClass) throw new InvalidOperationException("the parent of a method should be a class"); var returnType = conventions.GetTypeString(codeElement.ReturnType, codeElement); - WriteMethodDocumentation(codeElement, writer); if (codeElement.IsAsync && codeElement.IsOfKind(CodeMethodKind.RequestExecutor) && returnType.Equals("void", StringComparison.OrdinalIgnoreCase)) returnType = "Void"; //generic type for the future - writer.WriteLine(codeElement.ReturnType.IsNullable && !codeElement.IsAsync ? "@jakarta.annotation.Nullable" : "@jakarta.annotation.Nonnull"); - var signatureReturnType = WriteMethodPrototype(codeElement, writer, returnType); + WriteMethodDocumentation(codeElement, writer, returnType); + WriteMethodPrototype(codeElement, writer, returnType); writer.IncreaseIndent(); var inherits = parentClass.StartBlock.Inherits != null && !parentClass.IsErrorDefinition; var requestBodyParam = codeElement.Parameters.OfKind(CodeParameterKind.RequestBody); @@ -48,7 +47,7 @@ public override void WriteCodeElement(CodeMethod codeElement, LanguageWriter wri WriteRequestGeneratorBody(codeElement, requestParams, parentClass, writer); break; case CodeMethodKind.RequestExecutor: - WriteRequestExecutorBody(codeElement, requestParams, parentClass, writer, signatureReturnType); + WriteRequestExecutorBody(codeElement, requestParams, parentClass, writer); break; case CodeMethodKind.Getter: WriteGetterBody(codeElement, writer, parentClass); @@ -458,13 +457,10 @@ private void WriteDeserializerBodyForInheritedModel(CodeMethod method, CodeClass writer.WriteLine($"return {DeserializerVarName};"); } private const string FactoryMethodName = "createFromDiscriminatorValue"; - private const string ExecuterExceptionVar = "executionException"; - private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requestParams, CodeClass parentClass, LanguageWriter writer, string signatureReturnType) + private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requestParams, CodeClass parentClass, LanguageWriter writer) { if (codeElement.HttpMethod == null) throw new InvalidOperationException("http method cannot be null"); var returnType = conventions.GetTypeString(codeElement.ReturnType, codeElement, false); - writer.WriteLine("try {"); - writer.IncreaseIndent(); WriteGeneratorMethodCall(codeElement, requestParams, parentClass, writer, $"final RequestInformation {RequestInfoVarName} = "); var sendMethodName = GetSendRequestMethodName(codeElement.ReturnType.IsCollection, returnType, codeElement.ReturnType.AllTypes.First().TypeDefinition is CodeEnum); var errorMappingVarName = "null"; @@ -479,12 +475,6 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams requ } var factoryParameter = codeElement.ReturnType is CodeType returnCodeType && returnCodeType.TypeDefinition is CodeClass ? $"{returnType}::{FactoryMethodName}" : $"{returnType}.class"; writer.WriteLine($"return this.requestAdapter.{sendMethodName}({RequestInfoVarName}, {factoryParameter}, {errorMappingVarName});"); - writer.DecreaseIndent(); - writer.StartBlock("} catch (URISyntaxException ex) {"); - writer.WriteLine($"final java.util.concurrent.CompletableFuture<{signatureReturnType}> {ExecuterExceptionVar} = new java.util.concurrent.CompletableFuture<{signatureReturnType}>();"); - writer.WriteLine($"{ExecuterExceptionVar}.completeExceptionally(ex);"); - writer.WriteLine($"return {ExecuterExceptionVar};"); - writer.CloseBlock(); } private string GetSendRequestMethodName(bool isCollection, string returnType, bool isEnum) { @@ -658,7 +648,7 @@ private void WriteSerializationMethodCall(CodeProperty otherProp, CodeMethod met writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type, method)}({serializationKey}, {dataToSerialize});"); } private static readonly BaseCodeParameterOrderComparer parameterOrderComparer = new(); - private string WriteMethodPrototype(CodeMethod code, LanguageWriter writer, string returnType) + private void WriteMethodPrototype(CodeMethod code, LanguageWriter writer, string returnType) { var accessModifier = conventions.GetAccessModifier(code.Access); var returnTypeAsyncPrefix = code.IsAsync ? "java.util.concurrent.CompletableFuture<" : string.Empty; @@ -670,27 +660,23 @@ private string WriteMethodPrototype(CodeMethod code, LanguageWriter writer, stri _ => code.Name.ToFirstCharacterLowerCase() }; var parameters = string.Join(", ", code.Parameters.OrderBy(static x => x, parameterOrderComparer).Select(p => conventions.GetParameterSignature(p, code))); - var throwableDeclarations = code.Kind switch - { - CodeMethodKind.RequestGenerator => "throws URISyntaxException ", - _ => string.Empty - }; var collectionCorrectedReturnType = code.ReturnType.IsArray && code.IsOfKind(CodeMethodKind.RequestExecutor) ? $"Iterable<{returnType.StripArraySuffix()}>" : returnType; var finalReturnType = isConstructor ? string.Empty : $" {returnTypeAsyncPrefix}{collectionCorrectedReturnType}{returnTypeAsyncSuffix}"; var staticModifier = code.IsStatic ? " static" : string.Empty; conventions.WriteDeprecatedAnnotation(code, writer); - writer.WriteLine($"{accessModifier}{staticModifier}{finalReturnType} {methodName}({parameters}) {throwableDeclarations}{{"); - return collectionCorrectedReturnType; + writer.WriteLine($"{accessModifier}{staticModifier}{finalReturnType} {methodName}({parameters}) {{"); } - private void WriteMethodDocumentation(CodeMethod code, LanguageWriter writer) + private void WriteMethodDocumentation(CodeMethod code, LanguageWriter writer, string returnType) { - var returnRemark = code.IsAsync switch + var returnVoid = returnType.Equals("void", StringComparison.OrdinalIgnoreCase); + // Void returns, this includes constructors, should not have a return statement in the JavaDocs. + var returnRemark = returnVoid ? string.Empty : (code.IsAsync switch { true => $"@return a CompletableFuture of {code.ReturnType.Name}", false => $"@return a {code.ReturnType.Name}", - }; + }); conventions.WriteLongDescription(code, writer, code.Parameters @@ -698,7 +684,8 @@ private void WriteMethodDocumentation(CodeMethod code, LanguageWriter writer) .OrderBy(static x => x.Name, StringComparer.OrdinalIgnoreCase) .Select(x => $"@param {x.Name} {JavaConventionService.RemoveInvalidDescriptionCharacters(x.Documentation.Description)}") .Union(new[] { returnRemark })); - + if (!returnVoid) //Nullable/Nonnull annotations for returns are a part of Method Documentation + writer.WriteLine(code.ReturnType.IsNullable && !code.IsAsync ? "@jakarta.annotation.Nullable" : "@jakarta.annotation.Nonnull"); } private string GetDeserializationMethodName(CodeTypeBase propType, CodeMethod method) { diff --git a/tests/Kiota.Builder.Tests/Writers/Java/CodeMethodWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Java/CodeMethodWriterTests.cs index 2c3ce459cc..27b639e45b 100644 --- a/tests/Kiota.Builder.Tests/Writers/Java/CodeMethodWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/Java/CodeMethodWriterTests.cs @@ -653,8 +653,6 @@ public void WritesRequestExecutorBody() Assert.Contains("put(\"5XX\", Error5XX::createFromDiscriminatorValue);", result); Assert.Contains("put(\"401\", Error401::createFromDiscriminatorValue);", result); Assert.Contains("sendAsync", result); - Assert.Contains($"java.util.concurrent.CompletableFuture {ExecuterExceptionVar} = new java.util.concurrent.CompletableFuture();", result); - Assert.Contains($"{ExecuterExceptionVar}.completeExceptionally(ex);", result); AssertExtensions.CurlyBracesAreClosed(result); } [Fact] @@ -1157,7 +1155,6 @@ public void WritesRequestExecutorBodyForCollections() writer.Write(method); var result = tw.ToString(); Assert.Contains("sendCollectionAsync", result); - Assert.Contains("final java.util.concurrent.CompletableFuture> executionException = new java.util.concurrent.CompletableFuture>()", result); AssertExtensions.CurlyBracesAreClosed(result); } [Fact]