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 static software.amazon.awssdk.utils.StringUtils.isNotBlank; 19 20 import com.squareup.javapoet.AnnotationSpec; 21 import com.squareup.javapoet.ClassName; 22 import com.squareup.javapoet.JavaFile; 23 import com.squareup.javapoet.MethodSpec; 24 import com.squareup.javapoet.ParameterizedTypeName; 25 import com.squareup.javapoet.TypeName; 26 import com.squareup.javapoet.TypeSpec; 27 import com.squareup.javapoet.TypeVariableName; 28 import java.util.Arrays; 29 import java.util.function.Consumer; 30 import javax.lang.model.element.Modifier; 31 import software.amazon.awssdk.annotations.Generated; 32 import software.amazon.awssdk.codegen.model.intermediate.DocumentationModel; 33 import software.amazon.awssdk.codegen.model.intermediate.HasDeprecation; 34 35 public final class PoetUtils { 36 private static final AnnotationSpec GENERATED = AnnotationSpec.builder(Generated.class) 37 .addMember("value", "$S", "software.amazon.awssdk:codegen") 38 .build(); 39 PoetUtils()40 private PoetUtils() { 41 } 42 generatedAnnotation()43 public static AnnotationSpec generatedAnnotation() { 44 return GENERATED; 45 } 46 toStringBuilder()47 public static MethodSpec.Builder toStringBuilder() { 48 return MethodSpec.methodBuilder("toString") 49 .returns(String.class) 50 .addModifiers(Modifier.PUBLIC) 51 .addAnnotation(Override.class); 52 } 53 addDeprecated(Consumer<Class<?>> builder, HasDeprecation deprecation)54 public static void addDeprecated(Consumer<Class<?>> builder, HasDeprecation deprecation) { 55 if (deprecation.isDeprecated()) { 56 addDeprecated(builder); 57 } 58 } 59 addDeprecated(Consumer<Class<?>> builder)60 public static void addDeprecated(Consumer<Class<?>> builder) { 61 builder.accept(Deprecated.class); 62 } 63 addJavadoc(Consumer<String> builder, String javadoc)64 public static void addJavadoc(Consumer<String> builder, String javadoc) { 65 if (isNotBlank(javadoc)) { 66 builder.accept(javadoc.replace("$", "$$") + (javadoc.endsWith("\n") ? "" : "\n")); 67 } 68 } 69 addJavadoc(Consumer<String> builder, DocumentationModel docModel)70 public static void addJavadoc(Consumer<String> builder, DocumentationModel docModel) { 71 addJavadoc(builder, docModel.getDocumentation()); 72 } 73 createEnumBuilder(ClassName name)74 public static TypeSpec.Builder createEnumBuilder(ClassName name) { 75 return TypeSpec.enumBuilder(name).addAnnotation(PoetUtils.generatedAnnotation()).addModifiers(Modifier.PUBLIC); 76 } 77 createInterfaceBuilder(ClassName name)78 public static TypeSpec.Builder createInterfaceBuilder(ClassName name) { 79 return TypeSpec.interfaceBuilder(name).addAnnotation(PoetUtils.generatedAnnotation()).addModifiers(Modifier.PUBLIC); 80 } 81 createClassBuilder(ClassName name)82 public static TypeSpec.Builder createClassBuilder(ClassName name) { 83 return TypeSpec.classBuilder(name).addAnnotation(PoetUtils.generatedAnnotation()); 84 } 85 createParameterizedTypeName(ClassName className, String... typeVariables)86 public static ParameterizedTypeName createParameterizedTypeName(ClassName className, String... typeVariables) { 87 TypeName[] typeParameters = Arrays.stream(typeVariables).map(TypeVariableName::get).toArray(TypeName[]::new); 88 return ParameterizedTypeName.get(className, typeParameters); 89 } 90 createParameterizedTypeName(Class<?> clazz, String... typeVariables)91 public static ParameterizedTypeName createParameterizedTypeName(Class<?> clazz, String... typeVariables) { 92 return createParameterizedTypeName(ClassName.get(clazz), typeVariables); 93 } 94 createBoundedTypeVariableName(String parameterName, ClassName upperBound, String... typeVariables)95 public static TypeVariableName createBoundedTypeVariableName(String parameterName, ClassName upperBound, 96 String... typeVariables) { 97 return TypeVariableName.get(parameterName, createParameterizedTypeName(upperBound, typeVariables)); 98 } 99 classNameFromFqcn(String fqcn)100 public static ClassName classNameFromFqcn(String fqcn) { 101 String basePath = fqcn.substring(0, fqcn.lastIndexOf('.')); 102 String className = fqcn.substring(fqcn.lastIndexOf('.') + 1); 103 return ClassName.get(basePath, className); 104 } 105 buildJavaFile(ClassSpec spec)106 public static JavaFile buildJavaFile(ClassSpec spec) { 107 JavaFile.Builder builder = JavaFile.builder(spec.className().packageName(), spec.poetSpec()).skipJavaLangImports(true); 108 spec.staticImports().forEach(i -> i.memberNames().forEach(m -> builder.addStaticImport(i.className(), m))); 109 return builder.build(); 110 } 111 112 } 113