1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"). 5 * You may not use this file except in compliance with the License. 6 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.codegen.poet; 17 18 import com.squareup.javapoet.ClassName; 19 import software.amazon.awssdk.codegen.internal.Utils; 20 import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; 21 import software.amazon.awssdk.codegen.model.intermediate.OperationModel; 22 import software.amazon.awssdk.codegen.model.intermediate.ShapeModel; 23 import software.amazon.awssdk.codegen.model.intermediate.ShapeType; 24 25 /** 26 * Extension and convenience methods to Poet that use the intermediate model. 27 */ 28 public class PoetExtension { 29 30 private final IntermediateModel model; 31 PoetExtension(IntermediateModel model)32 public PoetExtension(IntermediateModel model) { 33 this.model = model; 34 } 35 36 /** 37 * @param className Simple name of class in model package. 38 * @return A Poet {@link ClassName} for the given class in the model package. 39 */ getModelClass(String className)40 public ClassName getModelClass(String className) { 41 return ClassName.get(model.getMetadata().getFullModelPackageName(), className); 42 } 43 44 /** 45 * @param className Simple name of class in transform package. 46 * @return A Poet {@link ClassName} for the given class in the transform package. 47 */ getTransformClass(String className)48 public ClassName getTransformClass(String className) { 49 return ClassName.get(model.getMetadata().getFullTransformPackageName(), className); 50 } 51 52 /** 53 * @param className Simple name of class in transform package. 54 * @return A Poet {@link ClassName} for the given class in the transform package. 55 */ getRequestTransformClass(String className)56 public ClassName getRequestTransformClass(String className) { 57 return ClassName.get(model.getMetadata().getFullRequestTransformPackageName(), className); 58 } 59 60 /** 61 * @param className Simple name of class in base service package (i.e. software.amazon.awssdk.services.dynamodb). 62 * @return A Poet {@link ClassName} for the given class in the base service package. 63 */ getClientClass(String className)64 public ClassName getClientClass(String className) { 65 return ClassName.get(model.getMetadata().getFullClientPackageName(), className); 66 } 67 68 /** 69 * @return A Poet {@link ClassName} for the generated service client configuration. 70 */ getServiceConfigClass()71 public ClassName getServiceConfigClass() { 72 return PoetUtils.classNameFromFqcn(model.getMetadata().getFullClientPackageName() + "." 73 + model.getMetadata().getServiceName() + "ServiceClientConfiguration"); 74 } 75 getUserAgentClass()76 public ClassName getUserAgentClass() { 77 return ClassName.get(model.getMetadata().getFullClientInternalPackageName(), "UserAgentUtils"); 78 } 79 80 /** 81 * @param operationName Name of the operation 82 * @return A Poet {@link ClassName} for the response type of a paginated operation in the base service package. 83 * 84 * Example: If operationName is "ListTables", then the response type of the paginated operation 85 * will be "ListTablesIterable" class. 86 */ getResponseClassForPaginatedSyncOperation(String operationName)87 public ClassName getResponseClassForPaginatedSyncOperation(String operationName) { 88 return ClassName.get(model.getMetadata().getFullPaginatorsPackageName(), operationName + "Iterable"); 89 } 90 getSyncWaiterInterface()91 public ClassName getSyncWaiterInterface() { 92 return ClassName.get(model.getMetadata().getFullWaitersPackageName(), model.getMetadata().getServiceName() + "Waiter"); 93 } 94 getSyncWaiterClass()95 public ClassName getSyncWaiterClass() { 96 return ClassName.get(model.getMetadata().getFullWaitersPackageName(), "Default" + model.getMetadata().getServiceName() + 97 "Waiter"); 98 } 99 getAsyncWaiterInterface()100 public ClassName getAsyncWaiterInterface() { 101 return ClassName.get(model.getMetadata().getFullWaitersPackageName(), model.getMetadata().getServiceName() + 102 "AsyncWaiter"); 103 } 104 getAsyncWaiterClass()105 public ClassName getAsyncWaiterClass() { 106 return ClassName.get(model.getMetadata().getFullWaitersPackageName(), "Default" + model.getMetadata().getServiceName() + 107 "AsyncWaiter"); 108 } 109 getEndpointProviderInterfaceName()110 public ClassName getEndpointProviderInterfaceName() { 111 return ClassName.get(model.getMetadata().getFullEndpointRulesPackageName(), model.getMetadata().getServiceName() + 112 "EndpointProvider"); 113 } 114 115 /** 116 * @param operationName Name of the operation 117 * @return A Poet {@link ClassName} for the response type of a async paginated operation in the base service package. 118 * 119 * Example: If operationName is "ListTables", then the async response type of the paginated operation 120 * will be "ListTablesPublisher" class. 121 */ getResponseClassForPaginatedAsyncOperation(String operationName)122 public ClassName getResponseClassForPaginatedAsyncOperation(String operationName) { 123 return ClassName.get(model.getMetadata().getFullPaginatorsPackageName(), operationName + "Publisher"); 124 } 125 126 /** 127 * @return ResponseMetadata className. eg: "S3ResponseMetadata" 128 */ getResponseMetadataClass()129 public ClassName getResponseMetadataClass() { 130 return ClassName.get(model.getMetadata().getFullModelPackageName(), 131 model.getSdkResponseBaseClassName() + "Metadata"); 132 } 133 134 /** 135 * @return The correctly cased name of the API. 136 */ getApiName(OperationModel operation)137 public String getApiName(OperationModel operation) { 138 return Utils.capitalize(operation.getOperationName()); 139 } 140 141 /** 142 * @return The {@link ClassName} for the response pojo. 143 */ responsePojoType(OperationModel operation)144 public ClassName responsePojoType(OperationModel operation) { 145 return getModelClass(operation.getOutputShape().getShapeName()); 146 } 147 148 // TODO Should we move the event stream specific methods to a new class 149 /** 150 * @return {@link ClassName} for generated event stream response handler interface. 151 */ eventStreamResponseHandlerType(OperationModel operation)152 public ClassName eventStreamResponseHandlerType(OperationModel operation) { 153 return getModelClass(getApiName(operation) + "ResponseHandler"); 154 } 155 156 /** 157 * @return {@link ClassName} for the builder interface for the response handler interface 158 */ eventStreamResponseHandlerBuilderType(OperationModel operation)159 public ClassName eventStreamResponseHandlerBuilderType(OperationModel operation) { 160 return eventStreamResponseHandlerType(operation).nestedClass("Builder"); 161 } 162 163 /** 164 * @return {@link ClassName} for the event stream visitor interface. 165 */ eventStreamResponseHandlerVisitorType(OperationModel operation)166 public ClassName eventStreamResponseHandlerVisitorType(OperationModel operation) { 167 return eventStreamResponseHandlerType(operation).nestedClass("Visitor"); 168 } 169 170 /** 171 * @return {@link ClassName} for the builder interface for the event stream visitor interface. 172 */ eventStreamResponseHandlerVisitorBuilderType(OperationModel operation)173 public ClassName eventStreamResponseHandlerVisitorBuilderType(OperationModel operation) { 174 return eventStreamResponseHandlerVisitorType(operation).nestedClass("Builder"); 175 } 176 177 /** 178 * @param shapeModel shape model for the class in model package 179 * @return {@link ClassName} for the shape represented by the given {@link ShapeModel}. 180 */ getModelClassFromShape(ShapeModel shapeModel)181 public ClassName getModelClassFromShape(ShapeModel shapeModel) { 182 return getModelClass(shapeModel.getShapeName()); 183 } 184 isResponse(ShapeModel shapeModel)185 public boolean isResponse(ShapeModel shapeModel) { 186 return shapeModel.getShapeType() == ShapeType.Response; 187 } 188 isRequest(ShapeModel shapeModel)189 public boolean isRequest(ShapeModel shapeModel) { 190 return shapeModel.getShapeType() == ShapeType.Request; 191 } 192 } 193