1 /*
2 (C) Copyright IBM Corp. 2006, 2011
3
4 THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5 ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6 CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7
8 You can obtain a current copy of the Eclipse Public License from
9 http://www.opensource.org/licenses/eclipse-1.0.php
10
11 @author : Endre Bak, ebak@de.ibm.com
12 *
13 * Flag Date Prog Description
14 * -------------------------------------------------------------------------------
15 * 1565892 2006-11-05 ebak Make SBLIM client JSR48 compliant
16 * 1723607 2007-05-22 ebak IPv6 support in WBEM-URI strings
17 * 2003590 2008-06-30 blaschke-oss Change licensing from CPL to EPL
18 * 2524131 2009-01-21 raman_arora Upgrade client to JDK 1.5 (Phase 1)
19 * 3374012 2011-07-24 blaschke-oss Sblim client CIMObjectPath class defect for LLA format URL
20 */
21
22 package org.metricshub.wbem.sblim.cimclient.internal.uri;
23
24 /*-
25 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
26 * WBEM Java Client
27 * ჻჻჻჻჻჻
28 * Copyright 2023 - 2025 MetricsHub
29 * ჻჻჻჻჻჻
30 * Licensed under the Apache License, Version 2.0 (the "License");
31 * you may not use this file except in compliance with the License.
32 * You may obtain a copy of the License at
33 *
34 * http://www.apache.org/licenses/LICENSE-2.0
35 *
36 * Unless required by applicable law or agreed to in writing, software
37 * distributed under the License is distributed on an "AS IS" BASIS,
38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39 * See the License for the specific language governing permissions and
40 * limitations under the License.
41 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
42 */
43
44 import java.util.regex.Pattern;
45
46 /**
47 * <code>
48 * <b>[ userinfo "@" ] host [ ":" port ]</b><br><br>
49 * userinfo = *( unreserved / pct-encoded / sub-delims / ":" )<br>
50 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"<br>
51 * pct-encoded = "%" HEXDIG HEXDIG<br>
52 * sub-delims = "!" / "$" / "@amp" / "'" / "(" / ")"
53 * / "*" / "+" / "," / ";" / "="<br>
54 * ALPHA = regex([A-Za-z])<br>
55 * DIGIT = regex([0-9])<br><br>
56 * Zone-index = ["%" ( 1*unreserved )]
57 * host = IP-literal / IPv4address / reg-name<br>
58 * IP-literal = "[" ( IPv6address / IPvFuture ) "]"<br>
59 * IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )<br>
60 * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet<br>
61 * reg-name = *( unreserved / pct-encoded / sub-delims )<br><br>
62 *
63 * IPv6address = ( 6( h16 ":" ) ls32<br>
64 * / "::" 5( h16 ":" ) ls32<br>
65 * / [ h16 ] "::" 4( h16 ":" ) ls32<br>
66 * / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32<br>
67 * / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32<br>
68 * / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32<br>
69 * / [ *4( h16 ":" ) h16 ] "::" ls32<br>
70 * / [ *5( h16 ":" ) h16 ] "::" h16<br>
71 * / [ *6( h16 ":" ) h16 ] "::" ) Zone-index<br><br>
72 *
73 * ls32 = ( h16 ":" h16 ) / IPv4address<br>
74 * ; least-significant 32 bits of address<br><br>
75 *
76 * h16 = 1*4HEXDIG<br>
77 * ; 16 bits of address represented in hexadecimal<br>
78 * </code>
79 */
80 public class Authority {
81 private static final String PCTENCODED = "%[0-9A-Fa-f]{2}";
82
83 private static final String UNRESERVED = "A-Za-z0-9\\-\\._~";
84
85 private static final String SUBDELIMS = "!\\$&'\\(\\)\\*\\+,;=";
86
87 private static final String REGNAMEREG = "([" + UNRESERVED + SUBDELIMS + "]|" + PCTENCODED + ")+";
88
89 private static final String ZONEINDEX = "(%[" + UNRESERVED + "]+)?";
90
91 private static final String IPV4 = "([0-9]{1,3}\\.){3}[0-9]{1,3}";
92
93 private static final String H16 = "[0-9A-Fa-f]{1,4}";
94
95 private static final String LS32 = "((" + H16 + ":" + H16 + ")" + "|(" + IPV4 + "))";
96
97 private static final String IPV6 =
98 // 6( h16 ":" ) ls32
99 "(((" +
100 H16 +
101 ":){6}" +
102 LS32 +
103 ")|" +
104 // "::" 5( h16 ":" )
105 "(::(" +
106 H16 +
107 ":){5}" +
108 LS32 +
109 ")|" +
110 // [ h16 ] "::" 4( h16 ":" ) ls32
111 "((" +
112 H16 +
113 ")?::" +
114 "(" +
115 H16 +
116 ":){4}" +
117 LS32 +
118 ")|" +
119 // [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
120 "(((" +
121 H16 +
122 ":){0,1}" +
123 H16 +
124 ")?::(" +
125 H16 +
126 ":){3}" +
127 LS32 +
128 ")|" +
129 // [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
130 "(((" +
131 H16 +
132 ":){0,2}" +
133 H16 +
134 ")?::(" +
135 H16 +
136 ":){2}" +
137 LS32 +
138 ")|" +
139 // [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
140 "(((" +
141 H16 +
142 ":){0,3}" +
143 H16 +
144 ")?::" +
145 H16 +
146 ":" +
147 LS32 +
148 ")|" +
149 // [ *4( h16 ":" ) h16 ] "::" ls32
150 "(((" +
151 H16 +
152 ":){0,4}" +
153 H16 +
154 ")?::" +
155 LS32 +
156 ")|" +
157 // [ *5( h16 ":" ) h16 ] "::" h16
158 "(((" +
159 H16 +
160 ":){0,5}" +
161 H16 +
162 ")?::" +
163 H16 +
164 ")|" +
165 // [ *6( h16 ":" ) h16 ] "::"
166 "(((" +
167 H16 +
168 ":){0,6}" +
169 H16 +
170 ")?::))" +
171 ZONEINDEX;
172
173 // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
174 private static final String IPVFUTURE = "v[0-9A-Fa-f]+\\.([" + UNRESERVED + SUBDELIMS + "]|:)+";
175
176 private static final String IPLITERAL = "\\[(" + IPV6 + "|" + IPVFUTURE + ")\\]";
177
178 private static Pattern USERINFOPAT = Pattern.compile(
179 "^((([" + UNRESERVED + SUBDELIMS + ":]|(" + PCTENCODED + "))*)@).*"
180 );
181
182 private static Pattern HOSTPAT = Pattern.compile("^((" + IPV4 + ")|(" + REGNAMEREG + ")|(" + IPLITERAL + ")).*");
183
184 private static Pattern PORTPAT = Pattern.compile("^([0-9]+).*");
185
186 /**
187 * Parses userInfo, host and port
188 *
189 * @param pUriStr
190 * @return the parsed Authority
191 */
192 public static Authority parse(URIString pUriStr) {
193 // TODO: tracing TRC.log(uriStr.toString());
194 URIString uriStr = pUriStr.deepCopy();
195 String userInfo;
196 if (uriStr.matchAndCut(USERINFOPAT, 1)) {
197 userInfo = uriStr.group(2);
198 } else {
199 userInfo = null;
200 }
201 if (!uriStr.matchAndCut(HOSTPAT, 1)) {
202 return null;
203 }
204 String host = uriStr.group(1);
205 String port = null;
206 if (uriStr.cutStarting(':')) {
207 if (!uriStr.matchAndCut(PORTPAT, 1)) {
208 // TODO: tracing TRC.error("Port not matched while ':' has been
209 // found!");
210 return null;
211 }
212 port = uriStr.group(1);
213 }
214 pUriStr.set(uriStr);
215 return new Authority(userInfo, host, port);
216 }
217
218 private String iUserInfo;
219
220 private String iHost;
221
222 private String iPort;
223
224 private Authority(String pUserInfo, String pHost, String pPort) {
225 this.iUserInfo = pUserInfo;
226 this.iHost = pHost;
227 this.iPort = pPort;
228 }
229
230 /**
231 * str
232 *
233 * @return a String
234 */
235 @Override
236 public String toString() {
237 return (
238 (this.iUserInfo == null ? "" : this.iUserInfo + "@") + this.iHost + (this.iPort == null ? "" : ":" + this.iPort)
239 );
240 }
241
242 /**
243 * getUserInfo
244 *
245 * @return the userInfo String
246 */
247 public String getUserInfo() {
248 return this.iUserInfo;
249 }
250
251 /**
252 * getHost
253 *
254 * @return the host String
255 */
256 public String getHost() {
257 return this.iHost;
258 }
259
260 /**
261 * getPort
262 *
263 * @return the port String
264 */
265 public String getPort() {
266 return this.iPort;
267 }
268 }