1 /* 2 * Copyright (c) 2012, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.net.MalformedURLException; 31 import java.net.URL; 32 import java.text.MessageFormat; 33 import java.util.Arrays; 34 import java.util.Collection; 35 import java.util.Map; 36 import java.util.ResourceBundle; 37 38 import static jdk.jpackage.internal.StandardBundlerParam.*; 39 40 public class LinuxAppBundler extends AbstractImageBundler { 41 42 private static final ResourceBundle I18N = ResourceBundle.getBundle( 43 "jdk.jpackage.internal.resources.LinuxResources"); 44 45 public static final BundlerParamInfo<File> ICON_PNG = 46 new StandardBundlerParam<>( 47 I18N.getString("param.icon-png.name"), 48 I18N.getString("param.icon-png.description"), 49 "icon.png", 50 File.class, 51 params -> { 52 File f = ICON.fetchFrom(params); 53 if (f != null && !f.getName().toLowerCase().endsWith(".png")) { 54 Log.error(MessageFormat.format( 55 I18N.getString("message.icon-not-png"), f)); 56 return null; 57 } 58 return f; 59 }, 60 (s, p) -> new File(s)); 61 62 public static final BundlerParamInfo<String> LINUX_INSTALL_DIR = 63 new StandardBundlerParam<>( 64 I18N.getString("param.linux-install-dir.name"), 65 I18N.getString("param.linux-install-dir.description"), 66 "linux-install-dir", 67 String.class, 68 params -> { 69 String dir = INSTALL_DIR.fetchFrom(params); 70 if (dir != null) { 71 if (dir.endsWith("/")) { 72 dir = dir.substring(0, dir.length()-1); 73 } 74 return dir; 75 } 76 return "/opt"; 77 }, 78 (s, p) -> s 79 ); 80 81 public static final BundlerParamInfo<String> LINUX_PACKAGE_DEPENDENCIES = 82 new StandardBundlerParam<>( 83 I18N.getString("param.linux-package-dependencies.name"), 84 I18N.getString("param.linux-package-dependencies.description"), 85 Arguments.CLIOptions.LINUX_PACKAGE_DEPENDENCIES.getId(), 86 String.class, 87 params -> { 88 return ""; 89 }, 90 (s, p) -> s 91 ); 92 93 @Override 94 public boolean validate(Map<String, ? super Object> p) 95 throws UnsupportedPlatformException, ConfigException { 96 try { 97 if (p == null) throw new ConfigException( 98 I18N.getString("error.parameters-null"), 99 I18N.getString("error.parameters-null.advice")); 100 101 return doValidate(p); 102 } catch (RuntimeException re) { 103 if (re.getCause() instanceof ConfigException) { 104 throw (ConfigException) re.getCause(); 105 } else { 106 throw new ConfigException(re); 107 } 108 } 109 } 110 111 private boolean doValidate(Map<String, ? super Object> p) 112 throws UnsupportedPlatformException, ConfigException { 113 if (Platform.getPlatform() != Platform.LINUX) { 114 throw new UnsupportedPlatformException(); 115 } 116 117 imageBundleValidation(p); 118 119 return true; 120 } 121 122 // it is static for the sake of sharing with "installer" bundlers 123 // that may skip calls to validate/bundle in this class! 124 public static File getRootDir(File outDir, Map<String, ? super Object> p) { 125 return new File(outDir, APP_NAME.fetchFrom(p)); 126 } 127 128 public static String getLauncherCfgName(Map<String, ? super Object> p) { 129 return "app/" + APP_NAME.fetchFrom(p) +".cfg"; 130 } 131 132 File doBundle(Map<String, ? super Object> p, File outputDirectory, 133 boolean dependentTask) throws PackagerException { 134 if (RUNTIME_INSTALLER.fetchFrom(p)) { 135 return doJreBundle(p, outputDirectory, dependentTask); 136 } else { 137 return doAppBundle(p, outputDirectory, dependentTask); 138 } 139 } 140 141 private File doJreBundle(Map<String, ? super Object> p, 142 File outputDirectory, boolean dependentTask) throws PackagerException { 143 try { 144 File rootDirectory = createRoot(p, outputDirectory, dependentTask, 145 APP_NAME.fetchFrom(p), "linuxapp-image-builder"); 146 AbstractAppImageBuilder appBuilder = new LinuxAppImageBuilder( 147 APP_NAME.fetchFrom(p), outputDirectory.toPath()); 148 File predefined = PREDEFINED_RUNTIME_IMAGE.fetchFrom(p); 149 if (predefined == null ) { 150 JLinkBundlerHelper.generateJre(p, appBuilder); 151 } else { 152 return predefined; 153 } 154 return rootDirectory; 155 } catch (PackagerException pe) { 156 throw pe; 157 } catch (Exception ex) { 158 Log.verbose(ex); 159 throw new PackagerException(ex); 160 } 161 } 162 163 private File doAppBundle(Map<String, ? super Object> p, 164 File outputDirectory, boolean dependentTask) throws PackagerException { 165 try { 166 File rootDirectory = createRoot(p, outputDirectory, dependentTask, 167 APP_NAME.fetchFrom(p), "linuxapp-image-builder"); 168 AbstractAppImageBuilder appBuilder = new LinuxAppImageBuilder(p, 169 outputDirectory.toPath()); 170 if (PREDEFINED_RUNTIME_IMAGE.fetchFrom(p) == null ) { 171 JLinkBundlerHelper.execute(p, appBuilder); 172 } else { 173 StandardBundlerParam.copyPredefinedRuntimeImage(p, appBuilder); 174 } 175 return rootDirectory; 176 } catch (PackagerException pe) { 177 throw pe; 178 } catch (Exception ex) { 179 Log.verbose(ex); 180 throw new PackagerException(ex); 181 } 182 } 183 184 @Override 185 public String getName() { 186 return I18N.getString("app.bundler.name"); 187 } 188 189 @Override 190 public String getDescription() { 191 return I18N.getString("app.bundler.description"); 192 } 193 194 @Override 195 public String getID() { 196 return "linux.app"; 197 } 198 199 @Override 200 public String getBundleType() { 201 return "IMAGE"; 202 } 203 204 @Override 205 public Collection<BundlerParamInfo<?>> getBundleParameters() { 206 return getAppBundleParameters(); 207 } 208 209 public static Collection<BundlerParamInfo<?>> getAppBundleParameters() { 210 return Arrays.asList( 211 APP_NAME, 212 APP_RESOURCES, 213 ARGUMENTS, 214 CLASSPATH, 215 JVM_OPTIONS, 216 MAIN_CLASS, 217 MAIN_JAR, 218 PREFERENCES_ID, 219 VERSION, 220 VERBOSE 221 ); 222 } 223 224 @Override 225 public File execute(Map<String, ? super Object> params, 226 File outputParentDir) throws PackagerException { 227 return doBundle(params, outputParentDir, false); 228 } 229 230 @Override 231 public boolean supported(boolean runtimeInstaller) { 232 return (Platform.getPlatform() == Platform.LINUX); 233 } 234 }