1 /* 2 * Copyright (c) 2015, 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. 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.incubator.jpackage.internal; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.nio.file.Files; 31 import java.nio.file.Path; 32 import java.text.MessageFormat; 33 import java.util.List; 34 import java.util.Map; 35 import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; 36 import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; 37 import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; 38 39 public class LinuxAppImageBuilder extends AbstractAppImageBuilder { 40 41 static final BundlerParamInfo<Path> ICON_PNG = 42 new StandardBundlerParam<>( 43 "icon.png", 44 Path.class, 45 params -> { 46 Path f = ICON.fetchFrom(params); 47 if (f != null && f.getFileName() != null && !f.getFileName() 48 .toString().toLowerCase().endsWith(".png")) { 49 Log.error(MessageFormat.format( 50 I18N.getString("message.icon-not-png"), f)); 51 return null; 52 } 53 return f; 54 }, 55 (s, p) -> Path.of(s)); 56 57 final static String DEFAULT_ICON = "java32.png"; 58 59 LinuxAppImageBuilder(Path imageOutDir) { 60 super(imageOutDir); 61 } 62 63 private void writeEntry(InputStream in, Path dstFile) throws IOException { 64 Files.createDirectories(dstFile.getParent()); 65 Files.copy(in, dstFile); 66 } 67 68 public static String getLauncherName(Map<String, ? super Object> params) { 69 return APP_NAME.fetchFrom(params); 70 } 71 72 @Override 73 public void prepareApplicationFiles(Map<String, ? super Object> params) 74 throws IOException { 75 appLayout.roots().stream().forEach(dir -> { 76 try { 77 IOUtils.writableOutputDir(dir); 78 } catch (PackagerException pe) { 79 throw new RuntimeException(pe); 80 } 81 }); 82 83 // create the primary launcher 84 createLauncherForEntryPoint(params, null); 85 86 // create the additional launchers, if any 87 List<Map<String, ? super Object>> entryPoints 88 = ADD_LAUNCHERS.fetchFrom(params); 89 for (Map<String, ? super Object> entryPoint : entryPoints) { 90 createLauncherForEntryPoint(AddLauncherArguments.merge(params, 91 entryPoint, ICON.getID(), ICON_PNG.getID()), params); 92 } 93 94 // Copy class path entries to Java folder 95 copyApplication(params); 96 } 97 98 private void createLauncherForEntryPoint(Map<String, ? super Object> params, 99 Map<String, ? super Object> mainParams) throws IOException { 100 // Copy executable to launchers folder 101 Path executableFile = appLayout.launchersDirectory().resolve(getLauncherName(params)); 102 try (InputStream is_launcher = 103 getResourceAsStream("jpackageapplauncher")) { 104 writeEntry(is_launcher, executableFile); 105 } 106 107 executableFile.toFile().setExecutable(true, false); 108 executableFile.toFile().setWritable(true, true); 109 110 writeCfgFile(params); 111 112 var iconResource = createIconResource(DEFAULT_ICON, ICON_PNG, params, 113 mainParams); 114 if (iconResource != null) { 115 Path iconTarget = appLayout.destktopIntegrationDirectory().resolve( 116 APP_NAME.fetchFrom(params) + IOUtils.getSuffix(Path.of( 117 DEFAULT_ICON))); 118 iconResource.saveToFile(iconTarget); 119 } 120 } 121 }