@@ -62,9 +62,11 @@ public final class DocumentationUtils {
6262 "iot" , "data.iot" , "machinelearning" , "rekognition" , "s3" , "sdb" , "swf"
6363 ));
6464 private static final Pattern COMMENT_DELIMITER = Pattern .compile ("\\ *\\ /" );
65+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper ();
6566
6667 private static final Logger log = Logger .loggerFor (DocumentationUtils .class );
6768 private static Map <String , String > exampleUrlMap ;
69+ private static Map <String , String > normalizedServiceKeyMap ;
6870
6971 private DocumentationUtils () {
7072 }
@@ -160,14 +162,20 @@ public static String createLinkToServiceDocumentation(Metadata metadata, ShapeMo
160162 */
161163 public static String createLinkToCodeExample (Metadata metadata , String operationName ) {
162164 try {
163- String serviceKey = mapServiceNameToExampleKey (metadata .getServiceName ());
164- String targetExampleId = serviceKey + "_" + operationName ;
165+ String normalizedServiceName = metadata .getServiceName ().toLowerCase (Locale .ROOT );
165166
166- Map <String , String > urlMap = getExampleUrlMap ();
167- String url = urlMap .get (targetExampleId );
168-
169- if (url != null ) {
170- return String .format ("<a href=\" %s\" target=\" _top\" >Code Example</a>" , url );
167+ Map <String , String > normalizedMap = getNormalizedServiceKeyMap ();
168+ String actualServiceKey = normalizedMap .get (normalizedServiceName );
169+
170+ if (actualServiceKey != null ) {
171+ String targetExampleId = actualServiceKey + "_" + operationName ;
172+
173+ Map <String , String > urlMap = getExampleUrlMap ();
174+ String url = urlMap .get (targetExampleId );
175+
176+ if (url != null ) {
177+ return String .format ("<a href=\" %s\" target=\" _top\" >Code Example</a>" , url );
178+ }
171179 }
172180
173181 return "" ;
@@ -215,72 +223,90 @@ public static String defaultExistenceCheck() {
215223 return DEFAULT_EXISTENCE_CHECK ;
216224 }
217225
218- /**
219- * Maps service names from codegen format (e.g., "AutoScaling") to example-meta.json keys (e.g., "auto-scaling").
220- */
221- private static String mapServiceNameToExampleKey (String serviceName ) {
222- if (serviceName == null ) {
223- return "" ;
224- }
225-
226- return serviceName
227- .replaceAll ("([a-z0-9])([A-Z])" , "$1-$2" )
228- .toLowerCase (Locale .ROOT );
229- }
230226
231227 /**
232228 * Gets the cached example URL map for fast operation ID -> URL lookups.
233229 */
234230 private static Map <String , String > getExampleUrlMap () {
235231 if (exampleUrlMap == null ) {
236- exampleUrlMap = buildExampleUrlMap ();
232+ buildExampleMaps ();
237233 }
238234 return exampleUrlMap ;
239235 }
240236
241237 /**
242- * Builds a flat lookup map from example-meta.json: operation ID -> URL
238+ * Gets the cached normalized service key map for service name matching.
243239 */
244- private static Map <String , String > buildExampleUrlMap () {
240+ private static Map <String , String > getNormalizedServiceKeyMap () {
241+ if (normalizedServiceKeyMap == null ) {
242+ buildExampleMaps ();
243+ }
244+ return normalizedServiceKeyMap ;
245+ }
246+
247+ /**
248+ * Builds both the URL lookup map and normalized service key mapping from example-meta.json.
249+ */
250+ private static void buildExampleMaps () {
245251 Map <String , String > urlMap = new HashMap <>();
252+ Map <String , String > normalizedMap = new HashMap <>();
246253
247254 try (InputStream inputStream = DocumentationUtils .class .getClassLoader ()
248255 .getResourceAsStream ("software/amazon/awssdk/codegen/example-meta.json" )) {
249256
250257 if (inputStream == null ) {
251258 log .debug (() -> "example-meta.json not found in classpath" );
252- return urlMap ;
259+ exampleUrlMap = urlMap ;
260+ normalizedServiceKeyMap = normalizedMap ;
261+ return ;
253262 }
254263
255- ObjectMapper objectMapper = new ObjectMapper ();
256- JsonNode root = objectMapper .readTree (inputStream );
257-
264+ JsonNode root = OBJECT_MAPPER .readTree (inputStream );
258265 JsonNode servicesNode = root .get ("services" );
266+
259267 if (servicesNode != null ) {
260- for (JsonNode serviceNode : servicesNode ) {
261- JsonNode examplesNode = serviceNode .get ("examples" );
262- if (examplesNode != null && examplesNode .isArray ()) {
263- for (JsonNode example : examplesNode ) {
264- JsonNode idNode = example .get ("id" );
265- JsonNode urlNode = example .get ("url" );
266-
267- if (idNode != null && urlNode != null ) {
268- String id = idNode .asText ();
269- String url = urlNode .asText ();
270- if (!id .isEmpty () && !url .isEmpty ()) {
271- urlMap .put (id , url );
272- }
273- }
274- }
275- }
276- }
268+ servicesNode .fieldNames ().forEachRemaining (serviceKey -> {
269+ buildNormalizedMapping (serviceKey , normalizedMap );
270+ buildUrlMappingForService (servicesNode .get (serviceKey ), urlMap );
271+ });
277272 }
278273
279- return urlMap ;
274+ exampleUrlMap = urlMap ;
275+ normalizedServiceKeyMap = normalizedMap ;
280276
281277 } catch (IOException e ) {
282278 log .warn (() -> "Failed to load example-meta.json" , e );
283- return urlMap ;
279+ exampleUrlMap = urlMap ;
280+ normalizedServiceKeyMap = normalizedMap ;
281+ }
282+ }
283+
284+ /**
285+ * Builds normalized mapping for a service key (e.g., "medical-imaging" -> "medicalimaging").
286+ */
287+ private static void buildNormalizedMapping (String serviceKey , Map <String , String > normalizedMap ) {
288+ String normalizedKey = serviceKey .replace ("-" , "" ).toLowerCase (Locale .ROOT );
289+ normalizedMap .put (normalizedKey , serviceKey );
290+ }
291+
292+ /**
293+ * Builds URL mappings for all examples in a service.
294+ */
295+ private static void buildUrlMappingForService (JsonNode serviceNode , Map <String , String > urlMap ) {
296+ JsonNode examplesNode = serviceNode .get ("examples" );
297+ if (examplesNode != null && examplesNode .isArray ()) {
298+ for (JsonNode example : examplesNode ) {
299+ JsonNode idNode = example .get ("id" );
300+ JsonNode urlNode = example .get ("url" );
301+
302+ if (idNode != null && urlNode != null ) {
303+ String id = idNode .asText ();
304+ String url = urlNode .asText ();
305+ if (!id .isEmpty () && !url .isEmpty ()) {
306+ urlMap .put (id , url );
307+ }
308+ }
309+ }
284310 }
285311 }
286312}
0 commit comments