1 /*
   2  * Copyright (c) 2017, 2020, 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("Windows"))
  60             family = "windows";
  61         else
  62             family = name.replaceFirst("^([^ ]+).*", "$1"); // use first word of name
  63 
  64         if (arch.contains("64")
  65                  && !arch.equals("ia64")
  66                  && !arch.equals("ppc64")
  67                  && !arch.equals("ppc64le")
  68                  && !arch.equals("zArch_64")
  69                  && !arch.equals("aarch64"))
  70              simple_arch = "x64";
  71         else if (arch.contains("86"))
  72             simple_arch = "i586";
  73         else if (arch.equals("ppc") || arch.equals("powerpc"))
  74             simple_arch = "ppc";
  75         else if (arch.equals("s390x") || arch.equals("zArch_64"))
  76             simple_arch = "s390x";
  77         else
  78             simple_arch = arch;
  79 
  80         p.setProperty("os.family", family);
  81         p.setProperty("os.simpleArch", simple_arch);
  82         properties = p;
  83     }
  84 
  85     public static void main(String[] args) throws Throwable {
  86         List<String> command = new ArrayList<>(args.length);
  87         for (int i = 0; i < args.length; ++i) {
  88             StringBuilder arg = new StringBuilder(args[i]);
  89             while (i < args.length - 1
  90                     && (arg.chars()
  91                        .filter(c -> c == '"')
  92                        .count() % 2) != 0) {
  93                 arg.append(" ")
  94                    .append(args[++i]);
  95             }
  96             command.add(eval(arg.toString()));
  97         }
  98         System.out.println("run " + command);
  99         try {
 100             Class.forName(command.remove(0))
 101                  .getMethod("main", String[].class)
 102                  .invoke(null, new Object[]{command.toArray(new String[0])});
 103         } catch (InvocationTargetException e) {
 104            Throwable t = e.getCause();
 105            t = t != null ? t : e;
 106            throw t;
 107         }
 108     }
 109 
 110     private static String eval(String string) {
 111         int index;
 112         int current = 0;
 113         StringBuilder result = new StringBuilder();
 114         while (current < string.length() && (index = string.indexOf("${", current)) >= 0) {
 115             result.append(string.substring(current, index));
 116             int endName = string.indexOf('}', index);
 117             current = endName + 1;
 118             String name = string.substring(index + 2, endName);
 119             String value = properties.getProperty(name);
 120             if (value == null) {
 121                 throw new Error("can't find property " + name);
 122             }
 123             result.append(value);
 124         }
 125         if (current < string.length()) {
 126             result.append(string.substring(current));
 127         }
 128         int length = result.length();
 129 
 130         if (length > 1 && result.charAt(0) == '"' && result.charAt(length - 1) == '"') {
 131             result.deleteCharAt(length - 1);
 132             result.deleteCharAt(0);
 133         }
 134         return result.toString();
 135     }
 136 }