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.internal; 17 18 import static software.amazon.awssdk.codegen.model.service.ShapeType.List; 19 import static software.amazon.awssdk.codegen.model.service.ShapeType.Map; 20 import static software.amazon.awssdk.codegen.model.service.ShapeType.Structure; 21 22 import java.io.InputStream; 23 import java.math.BigDecimal; 24 import java.math.BigInteger; 25 import java.time.Instant; 26 import java.util.ArrayList; 27 import java.util.HashMap; 28 import java.util.List; 29 import java.util.Map; 30 import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig; 31 import software.amazon.awssdk.codegen.model.service.Shape; 32 import software.amazon.awssdk.codegen.naming.NamingStrategy; 33 import software.amazon.awssdk.core.SdkBytes; 34 import software.amazon.awssdk.core.document.Document; 35 36 /** 37 * Used to determine the Java types for the service model. 38 */ 39 public class TypeUtils { 40 public static final class TypeKey { 41 public static final String LIST_INTERFACE = "listInterface"; 42 43 public static final String LIST_DEFAULT_IMPL = "listDefaultImpl"; 44 45 public static final String MAP_INTERFACE = "mapInterface"; 46 47 public static final String MAP_DEFAULT_IMPL = "mapDefaultImpl"; 48 } 49 50 private static final Map<String, String> DATA_TYPE_MAPPINGS = new HashMap<>(); 51 52 private static final Map<String, String> MARSHALLING_TYPE_MAPPINGS = new HashMap<>(); 53 54 static { 55 DATA_TYPE_MAPPINGS.put("string", String.class.getSimpleName()); 56 DATA_TYPE_MAPPINGS.put("boolean", Boolean.class.getSimpleName()); 57 DATA_TYPE_MAPPINGS.put("int", Integer.class.getSimpleName()); 58 DATA_TYPE_MAPPINGS.put("any", Object.class.getSimpleName()); 59 DATA_TYPE_MAPPINGS.put("integer", Integer.class.getSimpleName()); 60 DATA_TYPE_MAPPINGS.put("double", Double.class.getSimpleName()); 61 DATA_TYPE_MAPPINGS.put("short", Short.class.getSimpleName()); 62 DATA_TYPE_MAPPINGS.put("long", Long.class.getSimpleName()); 63 DATA_TYPE_MAPPINGS.put("float", Float.class.getSimpleName()); 64 DATA_TYPE_MAPPINGS.put("byte", Byte.class.getSimpleName()); 65 DATA_TYPE_MAPPINGS.put("timestamp", Instant.class.getName()); 66 DATA_TYPE_MAPPINGS.put("blob", SdkBytes.class.getName()); 67 DATA_TYPE_MAPPINGS.put("stream", InputStream.class.getName()); 68 DATA_TYPE_MAPPINGS.put("bigdecimal", BigDecimal.class.getName()); 69 DATA_TYPE_MAPPINGS.put("biginteger", BigInteger.class.getName()); 70 DATA_TYPE_MAPPINGS.put("list", List.class.getSimpleName()); 71 DATA_TYPE_MAPPINGS.put("map", Map.class.getSimpleName()); 72 DATA_TYPE_MAPPINGS.put("document", Document.class.getName()); DATA_TYPE_MAPPINGS.put(TypeKey.LIST_INTERFACE, List.class.getName())73 DATA_TYPE_MAPPINGS.put(TypeKey.LIST_INTERFACE, List.class.getName()); DATA_TYPE_MAPPINGS.put(TypeKey.LIST_DEFAULT_IMPL, ArrayList.class.getName())74 DATA_TYPE_MAPPINGS.put(TypeKey.LIST_DEFAULT_IMPL, ArrayList.class.getName()); DATA_TYPE_MAPPINGS.put(TypeKey.MAP_INTERFACE, Map.class.getName())75 DATA_TYPE_MAPPINGS.put(TypeKey.MAP_INTERFACE, Map.class.getName()); DATA_TYPE_MAPPINGS.put(TypeKey.MAP_DEFAULT_IMPL, HashMap.class.getName())76 DATA_TYPE_MAPPINGS.put(TypeKey.MAP_DEFAULT_IMPL, HashMap.class.getName()); 77 78 MARSHALLING_TYPE_MAPPINGS.put("String", "STRING"); 79 MARSHALLING_TYPE_MAPPINGS.put("Integer", "INTEGER"); 80 MARSHALLING_TYPE_MAPPINGS.put("Long", "LONG"); 81 MARSHALLING_TYPE_MAPPINGS.put("Float", "FLOAT"); 82 MARSHALLING_TYPE_MAPPINGS.put("Double", "DOUBLE"); 83 MARSHALLING_TYPE_MAPPINGS.put("Instant", "INSTANT"); 84 MARSHALLING_TYPE_MAPPINGS.put("SdkBytes", "SDK_BYTES"); 85 MARSHALLING_TYPE_MAPPINGS.put("Boolean", "BOOLEAN"); 86 MARSHALLING_TYPE_MAPPINGS.put("BigDecimal", "BIG_DECIMAL"); 87 MARSHALLING_TYPE_MAPPINGS.put("InputStream", "STREAM"); 88 MARSHALLING_TYPE_MAPPINGS.put("Short", "SHORT"); MARSHALLING_TYPE_MAPPINGS.put(null, "NULL")89 MARSHALLING_TYPE_MAPPINGS.put(null, "NULL"); 90 MARSHALLING_TYPE_MAPPINGS.put("Document", "DOCUMENT"); 91 } 92 93 private final NamingStrategy namingStrategy; 94 TypeUtils(NamingStrategy namingStrategy)95 public TypeUtils(NamingStrategy namingStrategy) { 96 this.namingStrategy = namingStrategy; 97 } 98 getMarshallingType(String simpleType)99 public static String getMarshallingType(String simpleType) { 100 return MARSHALLING_TYPE_MAPPINGS.get(simpleType); 101 } 102 isSimple(String type)103 public static boolean isSimple(String type) { 104 return DATA_TYPE_MAPPINGS.containsKey(type) || DATA_TYPE_MAPPINGS.containsValue(type); 105 } 106 getDataTypeMapping(String type)107 public static String getDataTypeMapping(String type) { 108 return DATA_TYPE_MAPPINGS.get(type); 109 } 110 111 /** 112 * Returns the default Java type of the specified shape. 113 */ getJavaDataType(Map<String, Shape> shapes, String shapeName)114 public String getJavaDataType(Map<String, Shape> shapes, String shapeName) { 115 return getJavaDataType(shapes, shapeName, null); 116 } 117 118 /** 119 * Returns the Java type of the specified shape with potential customization (such as 120 * auto-construct list or map). 121 */ getJavaDataType(Map<String, Shape> shapes, String shapeName, CustomizationConfig customConfig)122 public String getJavaDataType(Map<String, Shape> shapes, String shapeName, 123 CustomizationConfig customConfig) { 124 125 if (shapeName == null || shapeName.trim().isEmpty()) { 126 throw new IllegalArgumentException( 127 "Cannot derive shape type. Shape name cannot be null or empty"); 128 } 129 130 Shape shape = shapes.get(shapeName); 131 132 if (shape == null) { 133 throw new IllegalArgumentException( 134 "Cannot derive shape type. No shape information available for " + shapeName); 135 } 136 137 String shapeType = shape.getType(); 138 139 if (shape.isDocument()) { 140 return DATA_TYPE_MAPPINGS.get("document"); 141 } 142 143 if (Structure.getName().equals(shapeType)) { 144 return namingStrategy.getShapeClassName(shapeName); 145 } else if (List.getName().equals(shapeType)) { 146 String listContainerType = DATA_TYPE_MAPPINGS.get(TypeKey.LIST_INTERFACE); 147 return listContainerType + "<" + 148 getJavaDataType(shapes, shape.getListMember().getShape()) + ">"; 149 } else if (Map.getName().equals(shapeType)) { 150 String mapContainerType = DATA_TYPE_MAPPINGS.get(TypeKey.MAP_INTERFACE); 151 return mapContainerType + "<" + 152 getJavaDataType(shapes, shape.getMapKeyType().getShape()) + "," + 153 getJavaDataType(shapes, shape.getMapValueType().getShape()) + ">"; 154 } else { 155 156 if (shape.isStreaming()) { 157 return DATA_TYPE_MAPPINGS.get("stream"); 158 } 159 160 // scalar type. 161 String dataType = DATA_TYPE_MAPPINGS.get(shapeType); 162 if (dataType == null) { 163 throw new RuntimeException( 164 "Equivalent Java data type cannot be found for data type : " + shapeType); 165 } 166 return dataType; 167 } 168 } 169 } 170