View Javadoc
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 }