View Javadoc
1   /*
2     (C) Copyright IBM Corp. 2006, 2009
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-12-15  ebak         Make SBLIM client JSR48 compliant
16   * 1742873    2007-06-25  ebak         IPv6 ready cim-client
17   * 1832635    2007-11-15  ebak         less strict parsing for IPv6 hostnames
18   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
19   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
20   */
21  
22  package org.metricshub.wbem.sblim.cimclient.internal.util;
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.Matcher;
45  import java.util.regex.Pattern;
46  
47  /**
48   * XMLHostStr helps to convert XML HOST element style string into JSR48 style
49   * protocol, host and port strings.
50   */
51  public class XMLHostStr {
52  	private String iHostStr, iProtocol, iHost, iPort;
53  
54  	/*
55  	 * [ protocol "://"] host [ ":" port ]
56  	 *
57  	 * hosts: bela@anything.org 172.20.8.1 [ffe8::e391:13a3]
58  	 */
59  
60  	/**
61  	 * Ctor.
62  	 */
63  	public XMLHostStr() {
64  		/* default constructor */
65  	}
66  
67  	/**
68  	 * Ctor.
69  	 *
70  	 * @param pXMLHostStr
71  	 *            - like https://anything.org:5989
72  	 */
73  	public XMLHostStr(String pXMLHostStr) {
74  		set(pXMLHostStr);
75  	}
76  
77  	/**
78  	 * set
79  	 *
80  	 * @param pXMLHostStr
81  	 *            - like https://anything.org:5989
82  	 */
83  	public void set(String pXMLHostStr) {
84  		if (isIPv6Literal(pXMLHostStr)) {
85  			this.iProtocol = this.iPort = null;
86  			this.iHost = pXMLHostStr;
87  		} else {
88  			this.iHostStr = pXMLHostStr;
89  			this.iProtocol = parseProtocol();
90  			this.iPort = parsePort();
91  			this.iHost = this.iHostStr;
92  		}
93  	}
94  
95  	/**
96  	 * getProtocol
97  	 *
98  	 * @return String
99  	 */
100 	public String getProtocol() {
101 		return this.iProtocol;
102 	}
103 
104 	/**
105 	 * getHost
106 	 *
107 	 * @return String
108 	 */
109 	public String getHost() {
110 		return this.iHost;
111 	}
112 
113 	/**
114 	 * getPort
115 	 *
116 	 * @return String
117 	 */
118 	public String getPort() {
119 		return this.iPort;
120 	}
121 
122 	@Override
123 	public String toString() {
124 		return "protocol:" + getProtocol() + ", host:" + getHost() + ", port:" + getPort();
125 	}
126 
127 	private static boolean isIPv6Literal(String pStr) {
128 		if (pStr == null || pStr.length() == 0) return false;
129 		int numOfDoubleColons = 0;
130 		int colonCnt = 0;
131 		int numOfNumbers = 0;
132 		int digitCnt = 0;
133 		for (int i = 0; i < pStr.length(); i++) {
134 			char ch = pStr.charAt(i);
135 			if (Character.digit(ch, 16) >= 0) {
136 				if ((i == 0 && colonCnt == 1) || digitCnt >= 4) return false;
137 				++digitCnt;
138 				colonCnt = 0;
139 			} else if (ch == ':') {
140 				if ((i == pStr.length() - 1 && colonCnt == 0) || colonCnt >= 2) return false;
141 				++colonCnt;
142 				if (colonCnt == 2) {
143 					if (numOfDoubleColons > 0 || numOfNumbers >= 8) return false;
144 					++numOfDoubleColons;
145 				}
146 				if (digitCnt > 0) {
147 					digitCnt = 0;
148 					if (numOfNumbers >= 8) return false;
149 					++numOfNumbers;
150 				}
151 			} else {
152 				return false;
153 			}
154 		}
155 		if (digitCnt > 0) ++numOfNumbers;
156 		if ((numOfNumbers == 8 && numOfDoubleColons > 0) || numOfNumbers > 8) return false;
157 		return true;
158 	}
159 
160 	/*
161 	 * [ protocol "://"] host [ ":" port ]
162 	 *
163 	 * hosts: bela@anything.org 172.20.8.1 [ffe8::e391:13a3]
164 	 */
165 
166 	private static final String PR_SEP = "://";
167 
168 	private String parseProtocol() {
169 		int pos = this.iHostStr.indexOf(PR_SEP);
170 		if (pos < 0) return null;
171 		String protocol = this.iHostStr.substring(0, pos);
172 		this.iHostStr = this.iHostStr.substring(pos + PR_SEP.length());
173 		return protocol;
174 	}
175 
176 	private static final Pattern PORT_PAT = Pattern.compile("^(.+):([0-9]+)$");
177 
178 	private String parsePort() {
179 		Matcher m = PORT_PAT.matcher(this.iHostStr);
180 		if (!m.matches()) return null;
181 		this.iHostStr = m.group(1);
182 		return m.group(2);
183 	}
184 }