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.protocols.core;
17
18 import software.amazon.awssdk.annotations.SdkProtectedApi;
19 import software.amazon.awssdk.utils.Validate;
20 import software.amazon.awssdk.utils.http.SdkHttpUtils;
21
22 @SdkProtectedApi
23 public abstract class PathMarshaller {
24
25     /**
26      * Marshaller for non greedy path labels. Value is URL encoded and then replaced in the request URI.
27      */

28     public static final PathMarshaller NON_GREEDY = new NonGreedyPathMarshaller();
29
30     /**
31      * Marshaller for greedy path labels. Value is not URL encoded and replaced in the request URI.
32      */

33     public static final PathMarshaller GREEDY = new GreedyPathMarshaller();
34
35     /**
36      * Marshaller for greedy path labels that allows leading slahes. Value is not URL encoded and
37      * replaced in the request URI.
38      */

39     public static final PathMarshaller GREEDY_WITH_SLASHES = new GreedyLeadingSlashPathMarshaller();
40
41     private PathMarshaller() {
42     }
43
44     private static String trimLeadingSlash(String value) {
45         if (value.startsWith("/")) {
46             return value.replaceFirst("/""");
47         }
48         return value;
49     }
50
51     /**
52      * @param resourcePath Current resource path with path param placeholder
53      * @param paramName Name of parameter (i.e. placeholder value {Foo})
54      * @param pathValue String value of path parameter.
55      * @return New URI with placeholder replaced with marshalled value.
56      */

57     public abstract String marshall(String resourcePath, String paramName, String pathValue);
58
59     private static class NonGreedyPathMarshaller extends PathMarshaller {
60         @Override
61         public String marshall(String resourcePath, String paramName, String pathValue) {
62             Validate.notEmpty(pathValue, "%s cannot be empty.", paramName);
63             return resourcePath.replace(String.format("{%s}", paramName), SdkHttpUtils.urlEncode(pathValue));
64         }
65     }
66
67     private static class GreedyPathMarshaller extends PathMarshaller {
68
69         @Override
70         public String marshall(String resourcePath, String paramName, String pathValue) {
71             Validate.notEmpty(pathValue, "%s cannot be empty.", paramName);
72             return resourcePath.replace(String.format("{%s+}", paramName),
73                                         SdkHttpUtils.urlEncodeIgnoreSlashes(trimLeadingSlash(pathValue)));
74         }
75     }
76
77     private static class GreedyLeadingSlashPathMarshaller extends PathMarshaller {
78
79         @Override
80         public String marshall(String resourcePath, String paramName, String pathValue) {
81             Validate.notEmpty(pathValue, "%s cannot be empty.", paramName);
82             return resourcePath.replace(String.format("{%s+}", paramName),
83                                         SdkHttpUtils.urlEncodeIgnoreSlashes(pathValue));
84         }
85     }
86
87 }
88