jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java
changeset 38870 9fcc420c73f9
parent 38869 4bac8f3bce74
child 38871 ec08bf1979d4
equal deleted inserted replaced
38869:4bac8f3bce74 38870:9fcc420c73f9
    27 
    27 
    28 import java.io.File;
    28 import java.io.File;
    29 import java.io.IOException;
    29 import java.io.IOException;
    30 import java.io.PrintWriter;
    30 import java.io.PrintWriter;
    31 import java.nio.file.Files;
    31 import java.nio.file.Files;
       
    32 import java.util.ArrayList;
    32 import java.util.LinkedList;
    33 import java.util.LinkedList;
    33 import java.util.List;
    34 import java.util.List;
    34 import java.util.MissingResourceException;
    35 import java.util.MissingResourceException;
       
    36 import java.util.function.Predicate;
    35 import jdk.internal.jimage.BasicImageReader;
    37 import jdk.internal.jimage.BasicImageReader;
    36 import jdk.internal.jimage.ImageHeader;
    38 import jdk.internal.jimage.ImageHeader;
    37 import jdk.internal.jimage.ImageLocation;
    39 import jdk.internal.jimage.ImageLocation;
    38 import jdk.tools.jlink.internal.ImageResourcesTree;
    40 import jdk.tools.jlink.internal.ImageResourcesTree;
    39 import jdk.tools.jlink.internal.TaskHelper;
    41 import jdk.tools.jlink.internal.TaskHelper;
    41 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
    43 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
    42 import jdk.tools.jlink.internal.TaskHelper.Option;
    44 import jdk.tools.jlink.internal.TaskHelper.Option;
    43 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
    45 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
    44 
    46 
    45 class JImageTask {
    47 class JImageTask {
    46 
       
    47     static final Option<?>[] recognizedOptions = {
    48     static final Option<?>[] recognizedOptions = {
    48         new Option<JImageTask>(true, (task, option, arg) -> {
    49         new Option<JImageTask>(true, (task, option, arg) -> {
    49             task.options.directory = arg;
    50             task.options.directory = arg;
    50         }, "--dir"),
    51         }, "--dir"),
       
    52 
       
    53         new Option<JImageTask>(true, (task, option, arg) -> {
       
    54             task.options.filters = arg;
       
    55         }, "--filter"),
       
    56 
    51         new Option<JImageTask>(false, (task, option, arg) -> {
    57         new Option<JImageTask>(false, (task, option, arg) -> {
    52             task.options.fullVersion = true;
    58             task.options.fullVersion = true;
    53         }, true, "--fullversion"),
    59         }, true, "--fullversion"),
       
    60 
    54         new Option<JImageTask>(false, (task, option, arg) -> {
    61         new Option<JImageTask>(false, (task, option, arg) -> {
    55             task.options.help = true;
    62             task.options.help = true;
    56         }, "--help"),
    63         }, "--help"),
       
    64 
    57         new Option<JImageTask>(false, (task, option, arg) -> {
    65         new Option<JImageTask>(false, (task, option, arg) -> {
    58             task.options.verbose = true;
    66             task.options.verbose = true;
    59         }, "--verbose"),
    67         }, "--verbose"),
       
    68 
    60         new Option<JImageTask>(false, (task, option, arg) -> {
    69         new Option<JImageTask>(false, (task, option, arg) -> {
    61             task.options.version = true;
    70             task.options.version = true;
    62         }, "--version")
    71         }, "--version")
    63     };
    72     };
    64     private static final TaskHelper taskHelper
    73     private static final TaskHelper taskHelper
    65             = new TaskHelper(JIMAGE_BUNDLE);
    74             = new TaskHelper(JIMAGE_BUNDLE);
    66     private static final OptionsHelper<JImageTask> optionsHelper
    75     private static final OptionsHelper<JImageTask> optionsHelper
    67             = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions);
    76             = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions);
       
    77     private static final String PROGNAME = "jimage";
       
    78 
       
    79     private final OptionsValues options;
       
    80     private final List<Predicate<String>> filterPredicates;
       
    81     private PrintWriter log = null;
       
    82 
       
    83     JImageTask() {
       
    84         this.options = new OptionsValues();
       
    85         this.filterPredicates = new ArrayList<>();
       
    86         log = null;
       
    87     }
       
    88 
       
    89     void setLog(PrintWriter out) {
       
    90         log = out;
       
    91         taskHelper.setLog(log);
       
    92     }
    68 
    93 
    69     static class OptionsValues {
    94     static class OptionsValues {
    70         Task task = Task.LIST;
    95         Task task = Task.LIST;
    71         String directory = ".";
    96         String directory = ".";
       
    97         String filters = "";
    72         boolean fullVersion;
    98         boolean fullVersion;
    73         boolean help;
    99         boolean help;
    74         boolean verbose;
   100         boolean verbose;
    75         boolean version;
   101         boolean version;
    76         List<File> jimages = new LinkedList<>();
   102         List<File> jimages = new LinkedList<>();
    77     }
   103     }
    78 
       
    79     private static final String PROGNAME = "jimage";
       
    80     private final OptionsValues options = new OptionsValues();
       
    81 
   104 
    82     enum Task {
   105     enum Task {
    83         EXTRACT,
   106         EXTRACT,
    84         INFO,
   107         INFO,
    85         LIST,
   108         LIST,
   133 
   156 
   134     int run(String[] args) {
   157     int run(String[] args) {
   135         if (log == null) {
   158         if (log == null) {
   136             setLog(new PrintWriter(System.out, true));
   159             setLog(new PrintWriter(System.out, true));
   137         }
   160         }
       
   161 
   138         if (args.length == 0) {
   162         if (args.length == 0) {
   139             log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
   163             log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
   140             return EXIT_ABNORMAL;
   164             return EXIT_ABNORMAL;
   141         }
   165         }
       
   166 
   142         try {
   167         try {
   143             List<String> unhandled = optionsHelper.handleOptions(this, args);
   168             List<String> unhandled = optionsHelper.handleOptions(this, args);
       
   169 
   144             if(!unhandled.isEmpty()) {
   170             if(!unhandled.isEmpty()) {
   145                 try {
   171                 try {
   146                     options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
   172                     options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
   147                 } catch (IllegalArgumentException ex) {
   173                 } catch (IllegalArgumentException ex) {
   148                     throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
   174                     throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
   149                 }
   175                 }
       
   176 
   150                 for(int i = 1; i < unhandled.size(); i++) {
   177                 for(int i = 1; i < unhandled.size(); i++) {
   151                     options.jimages.add(new File(unhandled.get(i)));
   178                     options.jimages.add(new File(unhandled.get(i)));
   152                 }
   179                 }
   153             } else if (!options.help && !options.version && !options.fullVersion) {
   180             } else if (!options.help && !options.version && !options.fullVersion) {
   154                 throw taskHelper.newBadArgs("err.invalid.task", "<unspecified>");
   181                 throw taskHelper.newBadArgs("err.invalid.task", "<unspecified>");
   155             }
   182             }
       
   183 
   156             if (options.help) {
   184             if (options.help) {
   157                 if (unhandled.isEmpty()) {
   185                 if (unhandled.isEmpty()) {
   158                     log.println(taskHelper.getMessage("main.usage", PROGNAME));
   186                     log.println(taskHelper.getMessage("main.usage", PROGNAME));
       
   187 
   159                     for (Option<?> o : recognizedOptions) {
   188                     for (Option<?> o : recognizedOptions) {
   160                         String name = o.aliases()[0];
   189                         String name = o.aliases()[0];
       
   190 
   161                         if (name.startsWith("--")) {
   191                         if (name.startsWith("--")) {
   162                             name = name.substring(2);
   192                             name = name.substring(2);
   163                         } else if (name.startsWith("-")) {
   193                         } else if (name.startsWith("-")) {
   164                             name = name.substring(1);
   194                             name = name.substring(1);
   165                         }
   195                         }
       
   196 
   166                         log.println(taskHelper.getMessage("main.opt." + name));
   197                         log.println(taskHelper.getMessage("main.opt." + name));
   167                     }
   198                     }
   168                 } else {
   199                 } else {
   169                     try {
   200                     try {
   170                         log.println(taskHelper.getMessage("main.usage." + options.task.toString().toLowerCase()));
   201                         log.println(taskHelper.getMessage("main.usage." +
       
   202                                 options.task.toString().toLowerCase()));
   171                     } catch (MissingResourceException ex) {
   203                     } catch (MissingResourceException ex) {
   172                         throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
   204                         throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
   173                     }
   205                     }
   174                 }
   206                 }
   175                 return EXIT_OK;
   207                 return EXIT_OK;
   176             }
   208             }
       
   209 
   177             if (options.version || options.fullVersion) {
   210             if (options.version || options.fullVersion) {
   178                 taskHelper.showVersion(options.fullVersion);
   211                 taskHelper.showVersion(options.fullVersion);
   179 
   212 
   180                 if (unhandled.isEmpty()) {
   213                 if (unhandled.isEmpty()) {
   181                     return EXIT_OK;
   214                     return EXIT_OK;
   182                 }
   215                 }
   183             }
   216             }
       
   217 
       
   218             processFilter(options.filters);
       
   219 
   184             return run() ? EXIT_OK : EXIT_ERROR;
   220             return run() ? EXIT_OK : EXIT_ERROR;
   185         } catch (BadArgs e) {
   221         } catch (BadArgs e) {
   186             taskHelper.reportError(e.key, e.args);
   222             taskHelper.reportError(e.key, e.args);
       
   223 
   187             if (e.showUsage) {
   224             if (e.showUsage) {
   188                 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
   225                 log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
   189             }
   226             }
       
   227 
   190             return EXIT_CMDERR;
   228             return EXIT_CMDERR;
   191         } catch (Exception x) {
   229         } catch (Exception x) {
   192             x.printStackTrace();
   230             x.printStackTrace();
       
   231 
   193             return EXIT_ABNORMAL;
   232             return EXIT_ABNORMAL;
   194         } finally {
   233         } finally {
   195             log.flush();
   234             log.flush();
       
   235         }
       
   236     }
       
   237 
       
   238     private void processFilter(String filters) {
       
   239         if (filters.isEmpty()) {
       
   240             return;
       
   241         }
       
   242 
       
   243         for (String filter : filters.split(",")) {
       
   244             boolean endsWith = filter.startsWith("*");
       
   245             boolean startsWith = filter.endsWith("*");
       
   246             Predicate<String> function;
       
   247 
       
   248             if (startsWith && endsWith) {
       
   249                 final String string = filter.substring(1, filter.length() - 1);
       
   250                 function = (path) -> path.contains(string);
       
   251             } else if (startsWith) {
       
   252                 final String string = filter.substring(0, filter.length() - 1);
       
   253                 function = (path) -> path.startsWith(string);
       
   254             } else if (endsWith) {
       
   255                 final String string = filter.substring(1);
       
   256                 function = (path) -> path.endsWith(string);
       
   257             } else {
       
   258                 final String string = filter;
       
   259                 function = (path) -> path.equals(string);
       
   260             }
       
   261 
       
   262             filterPredicates.add(function);
   196         }
   263         }
   197     }
   264     }
   198 
   265 
   199     private void listTitle(File file, BasicImageReader reader) {
   266     private void listTitle(File file, BasicImageReader reader) {
   200         log.println("jimage: " + file);
   267         log.println("jimage: " + file);
   221         File resource =  new File(directory, name);
   288         File resource =  new File(directory, name);
   222         File parent = resource.getParentFile();
   289         File parent = resource.getParentFile();
   223 
   290 
   224         if (parent.exists()) {
   291         if (parent.exists()) {
   225             if (!parent.isDirectory()) {
   292             if (!parent.isDirectory()) {
   226                 throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
   293                 throw taskHelper.newBadArgs("err.cannot.create.dir",
       
   294                                             parent.getAbsolutePath());
   227             }
   295             }
   228         } else if (!parent.mkdirs()) {
   296         } else if (!parent.mkdirs()) {
   229             throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
   297             throw taskHelper.newBadArgs("err.cannot.create.dir",
       
   298                                         parent.getAbsolutePath());
   230         }
   299         }
   231 
   300 
   232         if (!ImageResourcesTree.isTreeInfoResource(name)) {
   301         if (!ImageResourcesTree.isTreeInfoResource(name)) {
   233             Files.write(resource.toPath(), bytes);
   302             Files.write(resource.toPath(), bytes);
   234         }
   303         }
   329                 if (resourceAction != null) {
   398                 if (resourceAction != null) {
   330                     String[] entryNames = reader.getEntryNames();
   399                     String[] entryNames = reader.getEntryNames();
   331                     String oldModule = "";
   400                     String oldModule = "";
   332 
   401 
   333                     for (String name : entryNames) {
   402                     for (String name : entryNames) {
       
   403                         boolean match = filterPredicates.isEmpty();
       
   404 
       
   405                         for (Predicate<String> predicate : filterPredicates) {
       
   406                             if (predicate.test(name)) {
       
   407                                 match = true;
       
   408                                 break;
       
   409                             }
       
   410                         }
       
   411 
       
   412                         if (!match) {
       
   413                             continue;
       
   414                         }
       
   415 
   334                         if (!ImageResourcesTree.isTreeInfoResource(name)) {
   416                         if (!ImageResourcesTree.isTreeInfoResource(name)) {
   335                             if (moduleAction != null) {
   417                             if (moduleAction != null) {
   336                                 int offset = name.indexOf('/', 1);
   418                                 int offset = name.indexOf('/', 1);
   337 
   419 
   338                                 String newModule = offset != -1 ?
   420                                 String newModule = offset != -1 ?
   367                 break;
   449                 break;
   368             case VERIFY:
   450             case VERIFY:
   369                 iterate(this::listTitle, null, this::verify);
   451                 iterate(this::listTitle, null, this::verify);
   370                 break;
   452                 break;
   371             default:
   453             default:
   372                 throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
   454                 throw taskHelper.newBadArgs("err.invalid.task",
       
   455                         options.task.name()).showUsage(true);
   373         }
   456         }
   374         return true;
   457         return true;
   375     }
   458     }
   376 
       
   377     private PrintWriter log = null;
       
   378 
       
   379     void setLog(PrintWriter out) {
       
   380         log = out;
       
   381         taskHelper.setLog(log);
       
   382     }
       
   383 }
   459 }