1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License.
3
4 package com.azure.storage.blob;
5
6 import com.azure.core.implementation.http.UrlBuilder;
7
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.util.HashMap;
11 import java.util.Map;
12
13 /**
14 * A BlobURLParts object represents the components that make up an Azure Storage Container/Blob URL. You may parse an
15 * existing URL into its parts with the {@link URLParser} class. You may construct a URL from parts by calling toURL().
16 * It is also possible to use the empty constructor to buildClient a blobURL from scratch.
17 * NOTE: Changing any SAS-related field requires computing a new SAS signature.
18 *
19 * @apiNote ## Sample Code \n
20 * [!code-java[Sample_Code](../azure-storage-java/src/test/java/com/microsoft/azure/storage/Samples.java?name=url_parts "Sample code for BlobURLParts")] \n
21 * For more samples, please see the [Samples file](%https://github.com/Azure/azure-storage-java/blob/master/src/test/java/com/microsoft/azure/storage/Samples.java)
22 */
23 final class BlobURLParts {
24
25 private String scheme;
26
27 private String host;
28
29 private String containerName;
30
31 private String blobName;
32
33 private String snapshot;
34
35 private SASQueryParameters sasQueryParameters;
36
37 private Map<String, String[]> unparsedParameters;
38
39 /**
40 * Initializes a BlobURLParts object with all fields set to null, except unparsedParameters, which is an empty map.
41 * This may be useful for constructing a URL to a blob storage resource from scratch when the constituent parts are
42 * already known.
43 */
44 BlobURLParts() {
45 unparsedParameters = new HashMap<>();
46 }
47
48 /**
49 * The scheme. Ex: "https://".
50 */
51 public String scheme() {
52 return scheme;
53 }
54
55 /**
56 * The scheme. Ex: "https://".
57 */
58 public BlobURLParts scheme(String scheme) {
59 this.scheme = scheme;
60 return this;
61 }
62
63 /**
64 * The host. Ex: "account.blob.core.windows.net".
65 */
66 public String host() {
67 return host;
68 }
69
70 /**
71 * The host. Ex: "account.blob.core.windows.net".
72 */
73 public BlobURLParts host(String host) {
74 this.host = host;
75 return this;
76 }
77
78 /**
79 * The container name or {@code null} if a {@link StorageAsyncRawClient} was parsed.
80 */
81 public String containerName() {
82 return containerName;
83 }
84
85 /**
86 * The container name or {@code null} if a {@link StorageAsyncRawClient} was parsed.
87 */
88 public BlobURLParts containerName(String containerName) {
89 this.containerName = containerName;
90 return this;
91 }
92
93 /**
94 * The blob name or {@code null} if a {@link StorageAsyncRawClient} or {@link ContainerAsyncClient} was parsed.
95 */
96 public String blobName() {
97 return blobName;
98 }
99
100 /**
101 * The blob name or {@code null} if a {@link StorageAsyncRawClient} or {@link ContainerAsyncClient} was parsed.
102 */
103 public BlobURLParts blobName(String blobName) {
104 this.blobName = blobName;
105 return this;
106 }
107
108 /**
109 * The snapshot time or {@code null} if anything except a URL to a snapshot was parsed.
110 */
111 public String snapshot() {
112 return snapshot;
113 }
114
115 /**
116 * The snapshot time or {@code null} if anything except a URL to a snapshot was parsed.
117 */
118 public BlobURLParts snapshot(String snapshot) {
119 this.snapshot = snapshot;
120 return this;
121 }
122
123 /**
124 * A {@link SASQueryParameters} representing the SAS query parameters or {@code null} if there were no such
125 * parameters.
126 */
127 public SASQueryParameters sasQueryParameters() {
128 return sasQueryParameters;
129 }
130
131 /**
132 * A {@link SASQueryParameters} representing the SAS query parameters or {@code null} if there were no such
133 * parameters.
134 */
135 public BlobURLParts sasQueryParameters(SASQueryParameters sasQueryParameters) {
136 this.sasQueryParameters = sasQueryParameters;
137 return this;
138 }
139
140 /**
141 * The query parameter key value pairs aside from SAS parameters and snapshot time or {@code null} if there were
142 * no such parameters.
143 */
144 public Map<String, String[]> unparsedParameters() {
145 return unparsedParameters;
146 }
147
148 /**
149 * The query parameter key value pairs aside from SAS parameters and snapshot time or {@code null} if there were
150 * no such parameters.
151 */
152 public BlobURLParts unparsedParameters(Map<String, String[]> unparsedParameters) {
153 this.unparsedParameters = unparsedParameters;
154 return this;
155 }
156
157 /**
158 * Converts the blob URL parts to a {@link URL}.
159 *
160 * @return A {@code java.net.URL} to the blob resource composed of all the elements in the object.
161 *
162 * @throws MalformedURLException
163 * The fields present on the BlobURLParts object were insufficient to construct a valid URL or were
164 * ill-formatted.
165 */
166 public URL toURL() throws MalformedURLException {
167 UrlBuilder/http/UrlBuilder.html#UrlBuilder">UrlBuilder url = new UrlBuilder().scheme(this.scheme).host(this.host);
168
169 StringBuilder path = new StringBuilder();
170 if (this.containerName != null) {
171 path.append(this.containerName);
172 if (this.blobName != null) {
173 path.append('/');
174 path.append(this.blobName);
175 }
176 }
177 url.path(path.toString());
178
179 if (this.snapshot != null) {
180 url.setQueryParameter(Constants.SNAPSHOT_QUERY_PARAMETER, this.snapshot);
181 }
182 if (this.sasQueryParameters != null) {
183 String encodedSAS = this.sasQueryParameters.encode();
184 if (encodedSAS.length() != 0) {
185 url.query(encodedSAS);
186 }
187 }
188
189 for (Map.Entry<String, String[]> entry : this.unparsedParameters.entrySet()) {
190 // The commas are intentionally encoded.
191 url.setQueryParameter(entry.getKey(),
192 Utility.safeURLEncode(String.join(",", entry.getValue())));
193 }
194
195 return url.toURL();
196 }
197 }