1 /* 2 * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jnlp.converter.parser; 25 26 import java.util.Locale; 27 import java.util.ArrayList; 28 import java.util.StringTokenizer; 29 import java.io.BufferedInputStream; 30 import java.io.IOException; 31 import java.io.InputStream; 32 import java.net.MalformedURLException; 33 import java.net.URL; 34 35 /** 36 * Handy class to add some utility methods for dealing with property matching 37 * etc. 38 */ 39 public class GeneralUtil { 40 41 public static boolean prefixMatchStringList(String[] prefixList, String target) { 42 // No prefixes matches everything 43 if (prefixList == null) { 44 return true; 45 } 46 // No target, but a prefix list does not match anything 47 if (target == null) { 48 return false; 49 } 50 for (String prefix : prefixList) { 51 if (target.startsWith(prefix)) { 52 return true; 53 } 54 } 55 return false; 56 } 57 58 private static String getOSArch() { 59 return System.getProperty("os.arch"); 60 } 61 62 public static boolean prefixMatchArch(String[] prefixList) { 63 // No prefixes matches everything 64 if (prefixList == null) { 65 return true; 66 } 67 68 // check for the current arch 69 String arch = getOSArch(); 70 for (String prefix : prefixList) { 71 if (arch.startsWith(prefix)) { 72 return true; 73 } 74 } 75 76 return false; 77 } 78 79 /** 80 * Converts a space delimited string to a list of strings 81 */ 82 public static String[] getStringList(String str) { 83 if (str == null) { 84 return null; 85 } 86 ArrayList<String> list = new ArrayList<>(); 87 int i = 0; 88 int length = str.length(); 89 StringBuffer sb = null; 90 while (i < length) { 91 char ch = str.charAt(i); 92 switch (ch) { 93 case ' ': 94 // A space was hit. Add string to list 95 if (sb != null) { 96 list.add(sb.toString()); 97 sb = null; 98 } 99 break; 100 case '\\': 101 // It is a delimiter. Add next character 102 if (i + 1 < length) { 103 ch = str.charAt(++i); 104 if (sb == null) { 105 sb = new StringBuffer(); 106 } 107 sb.append(ch); 108 } 109 break; 110 default: 111 if (sb == null) { 112 sb = new StringBuffer(); 113 } sb.append(ch); 114 break; 115 } 116 i++; // Next character 117 } 118 // Make sure to add the last part to the list too 119 if (sb != null) { 120 list.add(sb.toString()); 121 } 122 if (list.isEmpty()) { 123 return null; 124 } 125 String[] results = new String[list.size()]; 126 return list.toArray(results); 127 } 128 129 /** 130 * Checks if string list matches default locale 131 */ 132 public static boolean matchLocale(String[] localeList, Locale locale) { 133 // No locale specified matches everything 134 if (localeList == null) { 135 return true; 136 } 137 for (String localeList1 : localeList) { 138 if (matchLocale(localeList1, locale)) { 139 return true; 140 } 141 } 142 return false; 143 } 144 145 /** 146 * Checks if string matches default locale 147 */ 148 public static boolean matchLocale(String localeStr, Locale locale) { 149 if (localeStr == null || localeStr.length() == 0) { 150 return true; 151 } 152 153 // Compare against default locale 154 String language; 155 String country; 156 String variant; 157 158 // The locale string is of the form language_country_variant 159 StringTokenizer st = new StringTokenizer(localeStr, "_", false); 160 if (st.hasMoreElements() && locale.getLanguage().length() > 0) { 161 language = st.nextToken(); 162 if (!language.equalsIgnoreCase(locale.getLanguage())) { 163 return false; 164 } 165 } 166 if (st.hasMoreElements() && locale.getCountry().length() > 0) { 167 country = st.nextToken(); 168 if (!country.equalsIgnoreCase(locale.getCountry())) { 169 return false; 170 } 171 } 172 if (st.hasMoreElements() && locale.getVariant().length() > 0) { 173 variant = st.nextToken(); 174 if (!variant.equalsIgnoreCase(locale.getVariant())) { 175 return false; 176 } 177 } 178 179 return true; 180 } 181 182 public static long heapValToLong(String heapValue) { 183 if (heapValue == null) { 184 return -1; 185 } 186 long multiplier = 1; 187 if (heapValue.toLowerCase().lastIndexOf('m') != -1) { 188 // units are megabytes, 1 megabyte = 1024 * 1024 bytes 189 multiplier = 1024 * 1024; 190 heapValue = heapValue.substring(0, heapValue.length() - 1); 191 } else if (heapValue.toLowerCase().lastIndexOf('k') != -1) { 192 // units are kilobytes, 1 kilobyte = 1024 bytes 193 multiplier = 1024; 194 heapValue = heapValue.substring(0, heapValue.length() - 1); 195 } 196 long theValue; 197 try { 198 theValue = Long.parseLong(heapValue); 199 theValue = theValue * multiplier; 200 } catch (NumberFormatException e) { 201 theValue = -1; 202 } 203 return theValue; 204 } 205 206 public static byte[] readBytes(InputStream is, long size) throws IOException { 207 // Sanity on file size (restrict to 1M) 208 if (size > 1024 * 1024) { 209 throw new IOException("File too large"); 210 } 211 212 BufferedInputStream bis; 213 if (is instanceof BufferedInputStream) { 214 bis = (BufferedInputStream) is; 215 } else { 216 bis = new BufferedInputStream(is); 217 } 218 219 if (size <= 0) { 220 size = 10 * 1024; // Default to 10K 221 } 222 byte[] b = new byte[(int) size]; 223 int n; 224 int bytesRead = 0; 225 n = bis.read(b, bytesRead, b.length - bytesRead); 226 while (n != -1) { 227 bytesRead += n; 228 // Still room in array 229 if (b.length == bytesRead) { 230 byte[] bb = new byte[b.length * 2]; 231 System.arraycopy(b, 0, bb, 0, b.length); 232 b = bb; 233 } 234 // Read next line 235 n = bis.read(b, bytesRead, b.length - bytesRead); 236 } 237 bis.close(); 238 is.close(); 239 240 if (bytesRead != b.length) { 241 byte[] bb = new byte[bytesRead]; 242 System.arraycopy(b, 0, bb, 0, bytesRead); 243 b = bb; 244 } 245 return b; 246 } 247 248 public static String getOSFullName() { 249 return System.getProperty("os.name"); 250 } 251 252 /** 253 * Makes sure a URL is a path URL, i.e., ends with '/' 254 */ 255 public static URL asPathURL(URL url) { 256 if (url == null) { 257 return null; 258 } 259 260 String path = url.getFile(); 261 if (path != null && !path.endsWith("/")) { 262 try { 263 return new URL(url.getProtocol(), 264 url.getHost(), 265 url.getPort(), 266 url.getFile() + "/"); 267 } catch (MalformedURLException mue) { 268 // Should not happen 269 } 270 } 271 // Just return same URl 272 return url; 273 } 274 275 public static Locale getDefaultLocale() { 276 return Locale.getDefault(); 277 } 278 279 public static String toNormalizedString(URL u) { 280 if (u == null) { 281 return ""; 282 } 283 284 try { 285 if (u.getPort() == u.getDefaultPort()) { 286 u = new URL(u.getProtocol().toLowerCase(), 287 u.getHost().toLowerCase(), -1, u.getFile()); 288 } else { 289 u = new URL(u.getProtocol().toLowerCase(), 290 u.getHost().toLowerCase(), u.getPort(), u.getFile()); 291 } 292 } catch (MalformedURLException ex) { 293 } 294 return u.toExternalForm(); 295 } 296 297 public static boolean sameURLs(URL u1, URL u2) { 298 if (u1 == null || u2 == null || (u1 == u2)) { 299 return (u1 == u2); 300 } 301 //NB: do not use URL.sameFile() as it will do DNS lookup 302 // Also, do quick check before slow string comparisons 303 String f1 = u1.getFile(); 304 String f2 = u2.getFile(); 305 return (f1.length() == f2.length()) && sameBase(u1, u2) 306 && f1.equalsIgnoreCase(f2); 307 } 308 309 public static boolean sameBase(URL u1, URL u2) { 310 return u1 != null && u2 != null && 311 sameHost(u1, u2) && samePort(u1, u2) && sameProtocol(u1, u2); 312 } 313 314 private static boolean sameProtocol(URL u1, URL u2) { 315 //protocols are known to be lowercase 316 return u1.getProtocol().equals(u2.getProtocol()); 317 } 318 319 private static boolean sameHost(URL u1, URL u2) { 320 String host = u1.getHost(); 321 String otherHost = u2.getHost(); 322 if (host == null || otherHost == null) { 323 return (host == null && otherHost == null); 324 } else { 325 //avoid slow comparison for strings of different length 326 return ((host.length() == otherHost.length()) 327 && host.equalsIgnoreCase(otherHost)); 328 } 329 } 330 331 private static boolean samePort(URL u1, URL u2) { 332 return getPort(u1) == getPort(u2); 333 } 334 335 public static int getPort(URL u) { 336 if (u.getPort() != -1) { 337 return u.getPort(); 338 } else { 339 return u.getDefaultPort(); 340 } 341 } 342 343 public static URL getBase(URL url) { 344 if (url == null) return null; 345 String file = url.getFile(); 346 if (file != null) { 347 int idx = file.lastIndexOf('/'); 348 if (idx != -1 ) { 349 file = file.substring(0, idx + 1); 350 } 351 try { 352 return new URL( 353 url.getProtocol(), 354 url.getHost(), 355 url.getPort(), 356 file); 357 } catch(MalformedURLException mue) { 358 System.err.println(mue.getMessage()); 359 } 360 } 361 // Just return same URL 362 return url; 363 } 364 365 private static String getEmbeddedVersionPath(String path, String version) { 366 int index = path.lastIndexOf("/"); 367 String filename = path.substring(index + 1); 368 path = path.substring(0, index + 1); 369 370 String ext = null; 371 index = filename.lastIndexOf("."); 372 if (index != -1) { 373 ext = filename.substring(index + 1); 374 filename = filename.substring(0, index); 375 } 376 377 StringBuilder filenameSB = new StringBuilder(filename); 378 if (version != null) { 379 filenameSB.append("__V"); 380 filenameSB.append(version); 381 } 382 if (ext != null) { 383 filenameSB.append("."); 384 filenameSB.append(ext); 385 } 386 387 path += filenameSB.toString(); 388 return path; 389 } 390 391 public static URL getEmbeddedVersionURL(URL u, String version) throws Exception { 392 if (u == null) { 393 return null; 394 } 395 396 if (version == null || version.indexOf("*") != -1 397 || version.indexOf("+") != -1) { 398 // Do not support * or + in version string 399 return u; 400 } 401 402 URL versionURL = null; 403 404 String protocol = u.getProtocol(); 405 String host = u.getHost(); 406 int port = u.getPort(); 407 String path = u.getPath(); 408 409 path = getEmbeddedVersionPath(path, version); 410 411 versionURL = new URL(protocol, host, port, path); 412 413 return versionURL; 414 } 415 }