1 /*
   2  * Copyright (c) 2017, 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 import java.io.IOException;
  25 import java.io.InputStream;
  26 import java.io.OutputStream;
  27 import java.lang.reflect.InvocationTargetException;
  28 import java.nio.file.Paths;
  29 import java.util.ArrayList;
  30 import java.util.List;
  31 import java.util.Properties;
  32 
  33 /**
  34  * Replaces all {@code ${<X>}} with value of corresponding property({@code X}),
  35  * resulting string is handled similarly to {@code @run main} in jtreg.
  36  * In other words, {@code main} of first token will be executed with the rest
  37  * tokens as arguments.
  38  *
  39  * If one of properties can't be resolved, {@link Error} will be thrown.
  40  */
  41 public class PropertyResolvingWrapper {
  42     private static final Properties properties;
  43     static {
  44         Properties p = System.getProperties();
  45         String name = p.getProperty("os.name");
  46         String arch = p.getProperty("os.arch");
  47         String family;
  48         String simple_arch;
  49 
  50         // copy from jtreg/src/share/classes/com/sun/javatest/regtest/config/OS.java
  51         if (name.startsWith("AIX"))
  52             family = "aix";
  53         else if (name.startsWith("Linux"))
  54             family = "linux";
  55         else if (name.startsWith("Mac") || name.startsWith("Darwin"))
  56             family = "mac";
  57         else if (name.startsWith("OS400") || name.startsWith("OS/400") )
  58             family = "os400";
  59         else if (name.startsWith("SunOS") || name.startsWith("Solaris"))
  60             family = "solaris";
  61         else if (name.startsWith("Windows"))
  62             family = "windows";
  63         else
  64             family = name.replaceFirst("^([^ ]+).*", "$1"); // use first word of name
  65 
  66         if (arch.contains("64")
  67                  && !arch.equals("ia64")
  68                  && !arch.equals("ppc64")
  69                  && !arch.equals("ppc64le")
  70                  && !arch.equals("zArch_64")
  71                  && !arch.equals("aarch64"))
  72              simple_arch = "x64";
  73         else if (arch.contains("86"))
  74             simple_arch = "i586";
  75         else if (arch.equals("ppc") || arch.equals("powerpc"))
  76             simple_arch = "ppc";
  77         else if (arch.equals("s390x") || arch.equals("zArch_64"))
  78             simple_arch = "s390x";
  79         else
  80             simple_arch = arch;
  81 
  82         p.setProperty("os.family", family);
  83         p.setProperty("os.simpleArch", simple_arch);
  84         properties = p;
  85     }
  86 
  87     public static void main(String[] args) throws Throwable {
  88         List<String> command = new ArrayList<>(args.length);
  89         for (int i = 0; i < args.length; ++i) {
  90             StringBuilder arg = new StringBuilder(args[i]);
  91             while (i < args.length - 1
  92                     && (arg.chars()
  93                        .filter(c -> c == '"')
  94                        .count() % 2) != 0) {
  95                 arg.append(" ")
  96                    .append(args[++i]);
  97             }
  98             command.add(eval(arg.toString()));
  99         }
 100         System.out.println("run " + command);
 101         try {
 102             Class.forName(command.remove(0))
 103                  .getMethod("main", String[].class)
 104                  .invoke(null, new Object[]{command.toArray(new String[0])});
 105         } catch (InvocationTargetException e) {
 106            Throwable t = e.getCause();
 107            t = t != null ? t : e;
 108            throw t;
 109         }
 110     }
 111 
 112     private static String eval(String string) {
 113         int index;
 114         int current = 0;
 115         StringBuilder result = new StringBuilder();
 116         while (current < string.length() && (index = string.indexOf("${", current)) >= 0) {
 117             result.append(string.substring(current, index));
 118             int endName = string.indexOf('}', index);
 119             current = endName + 1;
 120             String name = string.substring(index + 2, endName);
 121             String value = properties.getProperty(name);
 122             if (value == null) {
 123                 throw new Error("can't find property " + name);
 124             }
 125             result.append(value);
 126         }
 127         if (current < string.length()) {
 128             result.append(string.substring(current));
 129         }
 130         int length = result.length();
 131 
 132         if (length > 1 && result.charAt(0) == '"' && result.charAt(length - 1) == '"') {
 133             result.deleteCharAt(length - 1);
 134             result.deleteCharAt(0);
 135         }
 136         return result.toString();
 137     }
 138 }