Skip to content

Commit 0df911b

Browse files
authored
Merge pull request #159 from RikkiGibson/ConcreteRestResponse
Use concrete RestResponse in generator
2 parents 7e62008 + 2696cec commit 0df911b

528 files changed

Lines changed: 18987 additions & 8329 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@
144144
<artifactId>maven-compiler-plugin</artifactId>
145145
<version>3.1</version>
146146
<configuration>
147-
<source>1.7</source>
148-
<target>1.7</target>
147+
<source>1.8</source>
148+
<target>1.8</target>
149149
<showWarnings>true</showWarnings>
150150
<showDeprecation>true</showDeprecation>
151151
<compilerArgument>-Xlint:unchecked</compilerArgument>

src/JavaCodeGenerator.cs

Lines changed: 114 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,11 @@ public override Task Generate(AutoRestCodeModel codeModel)
207207
javaFiles.Add(GetMethodGroupClientJavaFile(methodGroupClient, javaSettings));
208208
}
209209

210+
foreach (ResponseModel rm in service.ResponseModels)
211+
{
212+
javaFiles.Add(GetResponseJavaFile(rm, javaSettings));
213+
}
214+
210215
foreach (ServiceModel model in service.Models)
211216
{
212217
javaFiles.Add(GetModelJavaFile(model, javaSettings));
@@ -691,11 +696,27 @@ private static Service ParseService(AutoRestCodeModel codeModel, JavaSettings se
691696
IEnumerable<ServiceModel> models = autoRestModelTypes
692697
.Select((AutoRestCompositeType autoRestCompositeType) => ParseModel(autoRestCompositeType, settings, serviceModels))
693698
.ToArray();
699+
700+
IEnumerable<ResponseModel> responseModels = codeModel.Methods
701+
.Where(m => m.ReturnType.Headers != null)
702+
.Select(m => ParseResponse(m, settings))
703+
.ToList();
704+
694705
#endregion
695706

696707
ServiceManager manager = ParseManager(serviceClientName, codeModel, settings);
697708

698-
return new Service(serviceClientName, serviceClientDescription, enumTypes, exceptions, xmlSequenceWrappers, models, manager, serviceClient);
709+
return new Service(serviceClientName, serviceClientDescription, enumTypes, exceptions, xmlSequenceWrappers, responseModels, models, manager, serviceClient);
710+
}
711+
712+
private static ResponseModel ParseResponse(AutoRestMethod method, JavaSettings settings)
713+
{
714+
string name = method.MethodGroup.Name.ToPascalCase() + method.Name.ToPascalCase() + "Response";
715+
string package = settings.Package + "." + settings.ModelsSubpackage;
716+
string description = $"Contains all response data for the {method.Name} operation.";
717+
IType headersType = ParseType(method.ReturnType.Headers, method.Extensions, settings).AsNullable();
718+
IType bodyType = ParseType(method.ReturnType.Body, method.Extensions, settings).AsNullable();
719+
return new ResponseModel(name, package, description, headersType, bodyType);
699720
}
700721

701722
private static ServiceClient ParseServiceClient(AutoRestCodeModel codeModel, JavaSettings settings)
@@ -1061,19 +1082,25 @@ private static RestAPIMethod ParseRestAPIMethod(AutoRestMethod autoRestMethod, J
10611082
}
10621083
else
10631084
{
1064-
IType restResponseHeadersType = ConvertToClientType(ParseType(autoRestRestAPIMethodReturnType.Headers, settings));
1065-
1066-
IType restResponseBodyType;
1067-
if (settings.IsAzureOrFluent && responseBodyWireListType != null && (autorestRestAPIMethodReturnTypeIsPaged || restAPIMethodSimulateMethodAsPagingOperation))
1085+
IType singleValueType;
1086+
if (autoRestRestAPIMethodReturnType.Headers != null)
1087+
{
1088+
string className = autoRestMethod.MethodGroup.Name.ToPascalCase() + autoRestMethod.Name.ToPascalCase() + "Response";
1089+
singleValueType = new ClassType(settings.Package + "." + settings.ModelsSubpackage, className);
1090+
}
1091+
else if (responseBodyType.Equals(GenericType.FlowableByteBuffer))
1092+
{
1093+
singleValueType = ClassType.StreamResponse;
1094+
}
1095+
else if (responseBodyType.Equals(PrimitiveType.Void))
10681096
{
1069-
restResponseBodyType = responseBodyWireListType;
1097+
singleValueType = ClassType.VoidResponse;
10701098
}
10711099
else
10721100
{
1073-
restResponseBodyType = responseBodyType;
1101+
singleValueType = GenericType.BodyResponse(responseBodyType);
10741102
}
1075-
1076-
restAPIMethodReturnType = GenericType.Single(GenericType.RestResponse(restResponseHeadersType, responseBodyType));
1103+
restAPIMethodReturnType = GenericType.Single(singleValueType);
10771104
}
10781105

10791106
List<RestAPIParameter> restAPIMethodParameters = new List<RestAPIParameter>();
@@ -2401,6 +2428,79 @@ private static bool ShouldParseModelType(AutoRestCompositeType modelType, JavaSe
24012428
return shouldParseModelType;
24022429
}
24032430

2431+
public static JavaFile GetResponseJavaFile(ResponseModel response, JavaSettings settings)
2432+
{
2433+
JavaFile javaFile = GetJavaFileWithHeaderAndPackage(response.Package, settings, response.Name);
2434+
ISet<string> imports = new HashSet<string> { "java.util.Map" };
2435+
IType restResponseType = GenericType.RestResponse(response.HeadersType, response.BodyType);
2436+
restResponseType.AddImportsTo(imports, includeImplementationImports: true);
2437+
2438+
bool isStreamResponse = response.BodyType.Equals(GenericType.FlowableByteBuffer);
2439+
if (isStreamResponse)
2440+
{
2441+
imports.Add("java.io.Closeable");
2442+
imports.Add("io.reactivex.internal.functions.Functions");
2443+
}
2444+
2445+
javaFile.Import(imports);
2446+
2447+
string classSignature = isStreamResponse
2448+
? $"{response.Name} extends {restResponseType} implements Closeable"
2449+
: $"{response.Name} extends {restResponseType}";
2450+
2451+
javaFile.JavadocComment(javadoc =>
2452+
{
2453+
javadoc.Description(response.Description);
2454+
});
2455+
2456+
javaFile.PublicFinalClass(classSignature, classBlock =>
2457+
{
2458+
classBlock.JavadocComment(javadoc =>
2459+
{
2460+
javadoc.Description($"Creates an instance of {response.Name}.");
2461+
javadoc.Param("statusCode", "the status code of the HTTP response");
2462+
javadoc.Param("headers", "the deserialized headers of the HTTP response");
2463+
javadoc.Param("rawHeaders", "the raw headers of the HTTP response");
2464+
javadoc.Param("body", isStreamResponse ? "the body content stream" : "the deserialized body of the HTTP response");
2465+
});
2466+
classBlock.PublicConstructor(
2467+
$"{response.Name}(int statusCode, {response.HeadersType} headers, Map<String, String> rawHeaders, {response.BodyType} body)",
2468+
ctorBlock => ctorBlock.Line("super(statusCode, headers, rawHeaders, body);"));
2469+
2470+
if (!response.HeadersType.Equals(ClassType.Void))
2471+
{
2472+
classBlock.JavadocComment(javadoc => javadoc.Return("the deserialized response headers"));
2473+
classBlock.Annotation("Override");
2474+
classBlock.PublicMethod($"{response.HeadersType} headers()", methodBlock => methodBlock.Return("super.headers()"));
2475+
}
2476+
2477+
if (!response.BodyType.Equals(ClassType.Void))
2478+
{
2479+
if (response.BodyType.Equals(GenericType.FlowableByteBuffer))
2480+
{
2481+
classBlock.JavadocComment(javadoc => javadoc.Return("the response content stream"));
2482+
}
2483+
else
2484+
{
2485+
classBlock.JavadocComment(javadoc => javadoc.Return("the deserialized response body"));
2486+
}
2487+
2488+
2489+
classBlock.Annotation("Override");
2490+
classBlock.PublicMethod($"{response.BodyType} body()", methodBlock => methodBlock.Return("super.body()"));
2491+
}
2492+
2493+
if (isStreamResponse)
2494+
{
2495+
classBlock.JavadocComment(javadoc => javadoc.Description("Disposes of the connection associated with this stream response."));
2496+
classBlock.Annotation("Override");
2497+
classBlock.PublicMethod("void close()",
2498+
methodBlock => methodBlock.Line("body().subscribe(Functions.emptyConsumer(), Functions.<Throwable>emptyConsumer()).dispose();"));
2499+
}
2500+
});
2501+
return javaFile;
2502+
}
2503+
24042504
public static JavaFile GetModelJavaFile(ServiceModel model, JavaSettings settings)
24052505
{
24062506
JavaFile javaFile = GetJavaFileWithHeaderAndPackage(model.Package, settings, model.Name);
@@ -3497,10 +3597,6 @@ restAPIMethodReturnBodyClientType is ListType restAPIMethodReturnBodyClientListT
34973597
pageType = restAPIMethodReturnBodyClientType.AsNullable();
34983598
}
34993599

3500-
GenericType restResponseType = GenericType.RestResponse(
3501-
headersType: ConvertToClientType(ParseType(autoRestRestAPIMethodReturnType.Headers, settings)),
3502-
bodyType: deserializedResponseBodyType);
3503-
35043600
Parameter serviceCallbackParameter = new Parameter(
35053601
description: "the async ServiceCallback to handle successful and failed responses.",
35063602
isFinal: false,
@@ -4193,16 +4289,7 @@ restAPIMethodReturnBodyClientType is ListType restAPIMethodReturnBodyClientListT
41934289

41944290
string restAPIMethodArgumentList = GetRestAPIMethodArgumentList(autoRestMethodOrderedRetrofitParameters, settings);
41954291

4196-
function.Line($"return service.{restAPIMethod.Name}({restAPIMethodArgumentList}).map(new {GenericType.Function(restResponseType, pageType)}() {{");
4197-
function.Indent(() =>
4198-
{
4199-
function.Annotation("Override");
4200-
function.Block($"public {pageType} apply({restResponseType} response)", subFunction =>
4201-
{
4202-
subFunction.Return("response.body()");
4203-
});
4204-
});
4205-
function.Line("});");
4292+
function.Return($"service.{restAPIMethod.Name}({restAPIMethodArgumentList}).map(res -> res.body())");
42064293
});
42074294
break;
42084295

@@ -4254,16 +4341,7 @@ restAPIMethodReturnBodyClientType is ListType restAPIMethodReturnBodyClientListT
42544341
ApplyParameterTransformations(function, clientMethod, settings);
42554342
ConvertClientTypesToWireTypes(function, autoRestMethodRetrofitParameters, methodClientReference, settings);
42564343
string restAPIMethodArgumentList = GetRestAPIMethodArgumentList(autoRestMethodOrderedRetrofitParameters, settings);
4257-
function.Line($"return service.{clientMethod.RestAPIMethod.Name}({restAPIMethodArgumentList}).map(new {GenericType.Function(restResponseType, pageType)}() {{");
4258-
function.Indent(() =>
4259-
{
4260-
function.Annotation("Override");
4261-
function.Block($"public {pageType} apply({restResponseType} response)", subFunction =>
4262-
{
4263-
subFunction.Return("response.body()");
4264-
});
4265-
});
4266-
function.Line("}).toObservable();");
4344+
function.Return($"service.{clientMethod.RestAPIMethod.Name}({restAPIMethodArgumentList}).map(res -> res.body()).toObservable()");
42674345
});
42684346
break;
42694347

@@ -4464,34 +4542,11 @@ restAPIMethodReturnBodyClientType is ListType restAPIMethodReturnBodyClientListT
44644542
{
44654543
if (restAPIMethodReturnBodyClientType != PrimitiveType.Void)
44664544
{
4467-
function.Line($".flatMapMaybe(new {GenericType.Function(restResponseType, clientMethod.ReturnValue.Type)}() {{");
4468-
function.Indent(() =>
4469-
{
4470-
function.Block($"public {clientMethod.ReturnValue.Type} apply({restResponseType} restResponse)", subFunction =>
4471-
{
4472-
subFunction.If("restResponse.body() == null", ifBlock =>
4473-
{
4474-
ifBlock.Return("Maybe.empty()");
4475-
})
4476-
.Else(elseBlock =>
4477-
{
4478-
elseBlock.Return("Maybe.just(restResponse.body())");
4479-
});
4480-
});
4481-
});
4482-
function.Line("});");
4545+
function.Line($".flatMapMaybe(res -> res.body() == null ? Maybe.empty() : Maybe.just(res.body()));");
44834546
}
44844547
else if (isFluentDelete)
44854548
{
4486-
function.Line($".flatMapMaybe(new {GenericType.Function(restResponseType, clientMethod.ReturnValue.Type)}() {{");
4487-
function.Indent(() =>
4488-
{
4489-
function.Block($"public {clientMethod.ReturnValue.Type} apply({restResponseType} restResponse)", subFunction =>
4490-
{
4491-
subFunction.Return("Maybe.empty()");
4492-
});
4493-
});
4494-
function.Line("});");
4549+
function.Line($".flatMapMaybe(res -> Maybe.empty());");
44954550
}
44964551
else
44974552
{
@@ -4869,14 +4924,11 @@ restAPIMethodReturnBodyClientType is ListType restAPIMethodReturnBodyClientListT
48694924
restAPIMethod: restAPIMethod,
48704925
expressionsToValidate: expressionsToValidate));
48714926

4872-
GenericType singleRestResponseReturnType = GenericType.Single(GenericType.RestResponse(
4873-
headersType: ConvertToClientType(ParseType(autoRestRestAPIMethodReturnType.Headers, settings)),
4874-
bodyType: deserializedResponseBodyType));
48754927
clientMethods.Add(new ClientMethod(
48764928
description: restAPIMethod.Description,
48774929
returnValue: new ReturnValue(
48784930
description: $"a Single which performs the network request upon subscription.",
4879-
type: singleRestResponseReturnType),
4931+
type: ConvertToClientType(restAPIMethod.ReturnType)),
48804932
name: GetSimpleAsyncRestResponseMethodName(restAPIMethod),
48814933
parameters: parameters,
48824934
onlyRequiredParameters: onlyRequiredParameters,

src/Model/ClassType.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public class ClassType : IType
4444
public static readonly ClassType URL = new ClassType("java.net", "URL");
4545
public static readonly ClassType NonNull = new ClassType("io.reactivex.annotations", "NonNull");
4646
public static readonly ClassType OperationDescription = new ClassType("com.microsoft.rest.v2", "OperationDescription");
47+
public static readonly ClassType VoidResponse = new ClassType("com.microsoft.rest.v2", "VoidResponse");
48+
public static readonly ClassType StreamResponse = new ClassType("com.microsoft.rest.v2", "StreamResponse");
4749

4850
public ClassType(string package, string name, IEnumerable<string> implementationImports = null, IDictionary<string,string> extensions = null, bool isInnerModelType = false, Func<string,string> defaultValueExpressionConverter = null)
4951
{

src/Model/GenericType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class GenericType : IType
2020
public static GenericType Page(IType elementType) => new GenericType("com.microsoft.azure.v2", "Page", elementType);
2121
public static GenericType PagedList(IType elementType) => new GenericType("com.microsoft.azure.v2", "PagedList", elementType);
2222
public static GenericType RestResponse(IType headersType, IType bodyType) => new GenericType("com.microsoft.rest.v2", "RestResponse", headersType, bodyType);
23+
public static GenericType BodyResponse(IType bodyType) => new GenericType("com.microsoft.rest.v2", "BodyResponse", bodyType);
2324
public static GenericType Single(IType typeArgument) => new GenericType("io.reactivex", "Single", typeArgument);
2425
public static GenericType Function(IType inputType, IType outputType) => new GenericType("io.reactivex.functions", "Function", inputType, outputType);
2526

src/Model/ResponseModel.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
namespace AutoRest.Java.Model
5+
{
6+
public sealed class ResponseModel
7+
{
8+
public string Name { get; }
9+
public string Package { get; }
10+
public string Description { get; }
11+
public IType HeadersType { get; }
12+
public IType BodyType { get; }
13+
14+
public ResponseModel(string name, string package, string description, IType headersType, IType bodyType)
15+
{
16+
Name = name;
17+
Package = package;
18+
Description = description;
19+
HeadersType = headersType;
20+
BodyType = bodyType;
21+
}
22+
}
23+
}

src/Model/Service.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,23 @@ public class Service
2121
/// <param name="models"></param>
2222
/// <param name="manager"></param>
2323
/// <param name="serviceClient"></param>
24-
public Service(string clientName, string clientDescription, IEnumerable<EnumType> enums, IEnumerable<ServiceException> exceptions, IEnumerable<XmlSequenceWrapper> xmlSequenceWrappers, IEnumerable<ServiceModel> models, ServiceManager manager, ServiceClient serviceClient)
24+
public Service(
25+
string clientName,
26+
string clientDescription,
27+
IEnumerable<EnumType> enums,
28+
IEnumerable<ServiceException> exceptions,
29+
IEnumerable<XmlSequenceWrapper> xmlSequenceWrappers,
30+
IEnumerable<ResponseModel> responseModels,
31+
IEnumerable<ServiceModel> models,
32+
ServiceManager manager,
33+
ServiceClient serviceClient)
2534
{
2635
ClientName = clientName;
2736
ClientDescription = clientDescription;
2837
Enums = enums;
2938
Exceptions = exceptions;
3039
XmlSequenceWrappers = xmlSequenceWrappers;
40+
ResponseModels = responseModels;
3141
Models = models;
3242
Manager = manager;
3343
ServiceClient = serviceClient;
@@ -58,6 +68,11 @@ public Service(string clientName, string clientDescription, IEnumerable<EnumType
5868
/// </summary>
5969
public IEnumerable<XmlSequenceWrapper> XmlSequenceWrappers { get; }
6070

71+
/// <summary>
72+
/// Get the response models which contain the response status code, headers and body for each service method.
73+
/// </summary>
74+
public IEnumerable<ResponseModel> ResponseModels { get; }
75+
6176
/// <summary>
6277
/// Get the model types that are used by this service.
6378
/// </summary>

0 commit comments

Comments
 (0)