Util.java revision 3219:aacc4ceb35c9
11195Srgrimes/* 250472Speter * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. 337Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 438103Speter * 538103Speter * This code is free software; you can redistribute it and/or modify it 655230Speter * under the terms of the GNU General Public License version 2 only, as 755230Speter * published by the Free Software Foundation. Oracle designates this 855230Speter * particular file as subject to the "Classpath" exception as provided 955230Speter * by Oracle in the LICENSE file that accompanied this code. 1055230Speter * 1155230Speter * This code is distributed in the hope that it will be useful, but WITHOUT 1259257Siwasaki * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1357954Sshin * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1455230Speter * version 2 for more details (a copy is included in the LICENSE file that 1557407Sshin * accompanied this code). 1655230Speter * 1755230Speter * You should have received a copy of the GNU General Public License version 1855230Speter * 2 along with this work; if not, write to the Free Software Foundation, 1955230Speter * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201734Sjkh * 2117639Swosch * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2217639Swosch * or visit www.oracle.com if you need additional information or have any 2337Srgrimes * questions. 2457479Speter */ 2557488Speter 2657459Smarkmpackage com.sun.tools.sjavac; 2757459Smarkm 2857459Smarkmimport java.io.File; 2960677Skrisimport java.io.PrintWriter; 3060677Skrisimport java.io.StringWriter; 3160677Skrisimport java.nio.file.Path; 3260677Skrisimport java.util.Arrays; 331773Sjkhimport java.util.Collection; 3448734Siwasakiimport java.util.HashSet; 35147Srgrimesimport java.util.Map; 3627487Sasamiimport java.util.Set; 3727487Sasamiimport java.util.StringTokenizer; 3835832Sacheimport java.util.function.Function; 3943901Sbrianimport java.util.stream.Collectors; 4049110Sbrian 4164598Sgshapiro/** 4264598Sgshapiro * Utilities. 4337Srgrimes * 4417639Swosch * <p><b>This is NOT part of any supported API. 45263Srgrimes * If you write code that depends on this, you do so at your own risk. 462779Srgrimes * This code and its internal interfaces are subject to change or 478857Srgrimes * deletion without notice.</b> 48993Srgrimes */ 49263Srgrimespublic class Util { 5038103Speter 5137Srgrimes public static String toFileSystemPath(String pkgId) { 524487Sphk if (pkgId == null || pkgId.length()==0) return null; 536717Sphk String pn; 5439590Sjkh if (pkgId.charAt(0) == ':') { 5539636Sdima // When the module is the default empty module. 5639590Sjkh // Do not prepend the module directory, because there is none. 5739590Sjkh // Thus :java.foo.bar translates to java/foo/bar (or \) 585948Sjkh pn = pkgId.substring(1).replace('.',File.separatorChar); 594487Sphk } else { 601759Sjkh // There is a module. Thus jdk.base:java.foo.bar translates 619970Sbde // into jdk.base/java/foo/bar 6236902Sguido int cp = pkgId.indexOf(':'); 6343832Sjkh String mn = pkgId.substring(0,cp); 6452609Sdillon pn = mn+File.separatorChar+pkgId.substring(cp+1).replace('.',File.separatorChar); 6558979Siwasaki } 6661981Sbrian return pn; 679970Sbde } 6851033Sn_hibma 699970Sbde public static String justPackageName(String pkgName) { 701759Sjkh int c = pkgName.indexOf(":"); 7157488Speter if (c == -1) 7257488Speter throw new IllegalArgumentException("Expected ':' in package name (" + pkgName + ")"); 7317639Swosch return pkgName.substring(c+1); 7417639Swosch } 7517645Swosch 7638160Sjb public static String extractStringOption(String opName, String s) { 7757488Speter return extractStringOption(opName, s, null); 781759Sjkh } 799970Sbde 8053327Speter public static String extractStringOption(String opName, String s, String deflt) { 8157488Speter int p = s.indexOf(opName+"="); 8257488Speter if (p == -1) return deflt; 8357488Speter p+=opName.length()+1; 8457488Speter int pe = s.indexOf(',', p); 8560677Skris if (pe == -1) pe = s.length(); 8660677Skris return s.substring(p, pe); 8760677Skris } 8860677Skris 8957071Srwatson public static boolean extractBooleanOption(String opName, String s, boolean deflt) { 9057488Speter String str = extractStringOption(opName, s); 9157071Srwatson return "true".equals(str) ? true 921731Sjkh : "false".equals(str) ? false 939970Sbde : deflt; 9437Srgrimes } 959970Sbde 9637Srgrimes public static int extractIntOption(String opName, String s) { 979970Sbde return extractIntOption(opName, s, 0); 9837Srgrimes } 999970Sbde 10037Srgrimes public static int extractIntOption(String opName, String s, int deflt) { 10137Srgrimes int p = s.indexOf(opName+"="); 10237Srgrimes if (p == -1) return deflt; 10337Srgrimes p+=opName.length()+1; 1049970Sbde int pe = s.indexOf(',', p); 1051731Sjkh if (pe == -1) pe = s.length(); 1069970Sbde int v = 0; 1071731Sjkh try { 1089970Sbde v = Integer.parseInt(s.substring(p, pe)); 1096177Samurai } catch (Exception e) {} 11049110Sbrian return v; 11149110Sbrian } 11230589Sjmb 11364598Sgshapiro /** 1149970Sbde * Extract the package name from a fully qualified class name. 11537Srgrimes * 11663097Speter * Example: Given "pkg.subpkg.A" this method returns ":pkg.subpkg". 117147Srgrimes * Given "C" this method returns ":". 11863097Speter * 119147Srgrimes * @returns package name of the given class name 12063097Speter */ 12137Srgrimes public static String pkgNameOfClassName(String fqClassName) { 12263097Speter int i = fqClassName.lastIndexOf('.'); 123288Srgrimes String pkg = i == -1 ? "" : fqClassName.substring(0, i); 12463097Speter return ":" + pkg; 125147Srgrimes } 12613378Sache 12750126Sgreen /** 12850126Sgreen * Clean out unwanted sub options supplied inside a primary option. 12913378Sache * For example to only had portfile remaining from: 13017104Spst * settings="--server:id=foo,portfile=bar" 13117104Spst * do settings = cleanOptions("--server:",Util.set("-portfile"),settings); 13263097Speter * now settings equals "--server:portfile=bar" 133147Srgrimes * 13463097Speter * @param allowedSubOptions A set of the allowed sub options, id portfile etc. 13537Srgrimes * @param s The option settings string. 1369970Sbde */ 1371759Sjkh public static String cleanSubOptions(Set<String> allowedSubOptions, String s) { 1381759Sjkh StringBuilder sb = new StringBuilder(); 1399970Sbde StringTokenizer st = new StringTokenizer(s, ","); 1409970Sbde while (st.hasMoreTokens()) { 14161888Sasmodai String o = st.nextToken(); 1421759Sjkh int p = o.indexOf('='); 14361888Sasmodai if (p>0) { 14437Srgrimes String key = o.substring(0,p); 145147Srgrimes String val = o.substring(p+1); 14663776Smarcel if (allowedSubOptions.contains(key)) { 14763776Smarcel if (sb.length() > 0) sb.append(','); 14863776Smarcel sb.append(key+"="+val); 14963776Smarcel } 1507129Srgrimes } 15163776Smarcel } 15262416Smarkm return sb.toString(); 153410Srgrimes } 1547129Srgrimes 15511635Sache /** 15611635Sache * Convenience method to create a set with strings. 15711635Sache */ 15811635Sache public static Set<String> set(String... ss) { 15911635Sache Set<String> set = new HashSet<>(); 16011635Sache set.addAll(Arrays.asList(ss)); 1617129Srgrimes return set; 16211635Sache } 16311635Sache 16411635Sache /** 16511635Sache * Normalize windows drive letter paths to upper case to enable string 16611635Sache * comparison. 16711635Sache * 16811635Sache * @param file File name to normalize 16911635Sache * @return The normalized string if file has a drive letter at the beginning, 17011635Sache * otherwise the original string. 17111635Sache */ 172147Srgrimes public static String normalizeDriveLetter(String file) { 17348185Ssheldonh if (file.length() > 2 && file.charAt(1) == ':') { 17448185Ssheldonh return Character.toUpperCase(file.charAt(0)) + file.substring(1); 17548185Ssheldonh } else if (file.length() > 3 && file.charAt(0) == '*' 17648185Ssheldonh && file.charAt(2) == ':') { 17748185Ssheldonh // Handle a wildcard * at the beginning of the string. 17852609Sdillon return file.substring(0, 1) + Character.toUpperCase(file.charAt(1)) 17952609Sdillon + file.substring(2); 18058979Siwasaki } 18158979Siwasaki return file; 18262006Snbm } 18361981Sbrian 18448185Ssheldonh /** 18548185Ssheldonh * Locate the setting for the server properties. 18637Srgrimes */ 187 public static String findServerSettings(String[] args) { 188 for (String s : args) { 189 if (s.startsWith("--server:")) { 190 return s; 191 } 192 } 193 return null; 194 } 195 196 public static <E> Set<E> union(Set<? extends E> s1, 197 Set<? extends E> s2) { 198 Set<E> union = new HashSet<>(); 199 union.addAll(s1); 200 union.addAll(s2); 201 return union; 202 } 203 204 public static <E> Set<E> subtract(Set<? extends E> orig, 205 Set<? extends E> toSubtract) { 206 Set<E> difference = new HashSet<>(orig); 207 difference.removeAll(toSubtract); 208 return difference; 209 } 210 211 public static String getStackTrace(Throwable t) { 212 StringWriter sw = new StringWriter(); 213 t.printStackTrace(new PrintWriter(sw)); 214 return sw.toString(); 215 } 216 217 // TODO: Remove when refactoring from java.io.File to java.nio.file.Path. 218 public static File pathToFile(Path path) { 219 return path == null ? null : path.toFile(); 220 } 221 222 public static <E> Set<E> intersection(Collection<? extends E> c1, 223 Collection<? extends E> c2) { 224 Set<E> intersection = new HashSet<E>(c1); 225 intersection.retainAll(c2); 226 return intersection; 227 } 228 229 public static <I, T> Map<I, T> indexBy(Collection<? extends T> c, 230 Function<? super T, ? extends I> indexFunction) { 231 return c.stream().collect(Collectors.<T, I, T>toMap(indexFunction, o -> o)); 232 } 233 234 public static String fileSuffix(Path file) { 235 String fileNameStr = file.getFileName().toString(); 236 int dotIndex = fileNameStr.indexOf('.'); 237 return dotIndex == -1 ? "" : fileNameStr.substring(dotIndex); 238 } 239} 240