1 /*
   2  * Copyright (c) 2019, 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 package jdk.jpackage.test;
  24 
  25 import java.io.File;
  26 import java.nio.file.Path;
  27 
  28 
  29 public final class JavaAppDesc {
  30     public JavaAppDesc() {
  31     }
  32 
  33     public JavaAppDesc setClassName(String v) {
  34         qualifiedClassName = v;
  35         return this;
  36     }
  37 
  38     public JavaAppDesc setModuleName(String v) {
  39         moduleName = v;
  40         return this;
  41     }
  42 
  43     public JavaAppDesc setJarFileName(String v) {
  44         jarFileName = v;
  45         return this;
  46     }
  47 
  48     public JavaAppDesc setModuleVersion(String v) {
  49         moduleVersion = v;
  50         return this;
  51     }
  52 
  53     public JavaAppDesc setJarWithMainClass(boolean v) {
  54         jarWithMainClass = v;
  55         return this;
  56     }
  57 
  58     public String className() {
  59         return qualifiedClassName;
  60     }
  61 
  62     public Path classFilePath() {
  63         return Path.of(qualifiedClassName.replace(".", File.separator)
  64                 + ".class");
  65     }
  66 
  67     public String moduleName() {
  68         return moduleName;
  69     }
  70 
  71     public String packageName() {
  72         int lastDotIdx = qualifiedClassName.lastIndexOf('.');
  73         if (lastDotIdx == -1) {
  74             return null;
  75         }
  76         return qualifiedClassName.substring(0, lastDotIdx);
  77     }
  78 
  79     public String jarFileName() {
  80         return jarFileName;
  81     }
  82 
  83     public String moduleVersion() {
  84         return moduleVersion;
  85     }
  86 
  87     public boolean jarWithMainClass() {
  88         return jarWithMainClass;
  89     }
  90 
  91     @Override
  92     public String toString() {
  93         StringBuilder sb = new StringBuilder();
  94         if (jarFileName != null) {
  95             sb.append(jarFileName).append(':');
  96         }
  97         if (moduleName != null) {
  98             sb.append(moduleName).append('/');
  99         }
 100         if (qualifiedClassName != null) {
 101             sb.append(qualifiedClassName);
 102         }
 103         if (jarWithMainClass) {
 104             sb.append('!');
 105         }
 106         if (moduleVersion != null) {
 107             sb.append('@').append(moduleVersion);
 108         }
 109         return sb.toString();
 110     }
 111 
 112     /**
 113      * Create Java application description form encoded string value.
 114      *
 115      * Syntax of encoded Java application description is
 116      * [jar_file:][module_name/]qualified_class_name[!][@module_version].
 117      *
 118      * E.g.: `duke.jar:com.other/com.other.foo.bar.Buz!@3.7` encodes modular
 119      * application. Module name is `com.other`. Main class is
 120      * `com.other.foo.bar.Buz`. Module version is `3.7`. Application will be
 121      * compiled and packed in `duke.jar` jar file. jar command will set module
 122      * version (3.7) and main class (Buz) attributes in the jar file.
 123      *
 124      * E.g.: `Ciao` encodes non-modular `Ciao` class in the default package.
 125      * jar command will not put main class attribute in the jar file.
 126      * Default name will be picked for jar file - `hello.jar`.
 127      *
 128      * @param cmd jpackage command to configure
 129      * @param javaAppDesc encoded Java application description
 130      */
 131     public static JavaAppDesc parse(String javaAppDesc) {
 132         JavaAppDesc desc = HelloApp.createDefaltAppDesc();
 133 
 134         if (javaAppDesc == null) {
 135             return desc;
 136         }
 137 
 138         String moduleNameAndOther = Functional.identity(() -> {
 139             String[] components = javaAppDesc.split(":", 2);
 140             if (components.length == 2) {
 141                 desc.setJarFileName(components[0]);
 142             }
 143             return components[components.length - 1];
 144         }).get();
 145 
 146         String classNameAndOther = Functional.identity(() -> {
 147             String[] components = moduleNameAndOther.split("/", 2);
 148             if (components.length == 2) {
 149                 desc.setModuleName(components[0]);
 150             }
 151             return components[components.length - 1];
 152         }).get();
 153 
 154         Functional.identity(() -> {
 155             String[] components = classNameAndOther.split("@", 2);
 156             if (components[0].endsWith("!")) {
 157                 components[0] = components[0].substring(0,
 158                         components[0].length() - 1);
 159                 desc.setJarWithMainClass(true);
 160             }
 161             desc.setClassName(components[0]);
 162             if (components.length == 2) {
 163                 desc.setModuleVersion(components[1]);
 164             }
 165         }).run();
 166 
 167         return desc;
 168     }
 169 
 170     private String qualifiedClassName;
 171     private String moduleName;
 172     private String jarFileName;
 173     private String moduleVersion;
 174     private boolean jarWithMainClass;
 175 }