--- /dev/null 2019-01-11 12:03:21.000000000 -0500 +++ new/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java 2019-01-11 12:03:20.121516400 -0500 @@ -0,0 +1,902 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.internal; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +import static jdk.jpackage.internal.StandardBundlerParam.*; +import static jdk.jpackage.internal.LinuxAppBundler.ICON_PNG; +import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR; +import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES; + +public class LinuxDebBundler extends AbstractBundler { + + private static final ResourceBundle I18N = ResourceBundle.getBundle( + "jdk.jpackage.internal.resources.LinuxResources"); + + public static final BundlerParamInfo APP_BUNDLER = + new StandardBundlerParam<>( + I18N.getString("param.deb-app-bundler.name"), + I18N.getString("param.deb-app-bundler.description"), + "linux.app.bundler", + LinuxAppBundler.class, + params -> new LinuxAppBundler(), + (s, p) -> null); + + // Debian rules for package naming are used here + // https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Source + // + // Package names must consist only of lower case letters (a-z), + // digits (0-9), plus (+) and minus (-) signs, and periods (.). + // They must be at least two characters long and + // must start with an alphanumeric character. + // + private static final Pattern DEB_BUNDLE_NAME_PATTERN = + Pattern.compile("^[a-z][a-z\\d\\+\\-\\.]+"); + + public static final BundlerParamInfo BUNDLE_NAME = + new StandardBundlerParam<> ( + I18N.getString("param.bundle-name.name"), + I18N.getString("param.bundle-name.description"), + Arguments.CLIOptions.LINUX_BUNDLE_NAME.getId(), + String.class, + params -> { + String nm = APP_NAME.fetchFrom(params); + + if (nm == null) return null; + + // make sure to lower case and spaces/underscores become dashes + nm = nm.toLowerCase().replaceAll("[ _]", "-"); + return nm; + }, + (s, p) -> { + if (!DEB_BUNDLE_NAME_PATTERN.matcher(s).matches()) { + throw new IllegalArgumentException(new ConfigException( + MessageFormat.format(I18N.getString( + "error.invalid-value-for-package-name"), s), + I18N.getString( + "error.invalid-value-for-package-name.advice"))); + } + + return s; + }); + + public static final BundlerParamInfo FULL_PACKAGE_NAME = + new StandardBundlerParam<> ( + I18N.getString("param.full-package-name.name"), + I18N.getString("param.full-package-name.description"), + "linux.deb.fullPackageName", + String.class, + params -> BUNDLE_NAME.fetchFrom(params) + "-" + + VERSION.fetchFrom(params), + (s, p) -> s); + + public static final BundlerParamInfo DEB_IMAGE_DIR = + new StandardBundlerParam<>( + I18N.getString("param.image-dir.name"), + I18N.getString("param.image-dir.description"), + "linux.deb.imageDir", + File.class, + params -> { + File imagesRoot = IMAGES_ROOT.fetchFrom(params); + if (!imagesRoot.exists()) imagesRoot.mkdirs(); + return new File(new File(imagesRoot, "linux-deb.image"), + FULL_PACKAGE_NAME.fetchFrom(params)); + }, + (s, p) -> new File(s)); + + public static final BundlerParamInfo APP_IMAGE_ROOT = + new StandardBundlerParam<>( + I18N.getString("param.app-image-root.name"), + I18N.getString("param.app-image-root.description"), + "linux.deb.imageRoot", + File.class, + params -> { + File imageDir = DEB_IMAGE_DIR.fetchFrom(params); + return new File(imageDir, LINUX_INSTALL_DIR.fetchFrom(params)); + }, + (s, p) -> new File(s)); + + public static final BundlerParamInfo CONFIG_DIR = + new StandardBundlerParam<>( + I18N.getString("param.config-dir.name"), + I18N.getString("param.config-dir.description"), + "linux.deb.configDir", + File.class, + params -> new File(DEB_IMAGE_DIR.fetchFrom(params), "DEBIAN"), + (s, p) -> new File(s)); + + public static final BundlerParamInfo EMAIL = + new StandardBundlerParam<> ( + I18N.getString("param.maintainer-email.name"), + I18N.getString("param.maintainer-email.description"), + BundleParams.PARAM_EMAIL, + String.class, + params -> "Unknown", + (s, p) -> s); + + public static final BundlerParamInfo MAINTAINER = + new StandardBundlerParam<> ( + I18N.getString("param.maintainer-name.name"), + I18N.getString("param.maintainer-name.description"), + Arguments.CLIOptions.LINUX_DEB_MAINTAINER.getId(), + String.class, + params -> VENDOR.fetchFrom(params) + " <" + + EMAIL.fetchFrom(params) + ">", + (s, p) -> s); + + public static final BundlerParamInfo LICENSE_TEXT = + new StandardBundlerParam<> ( + I18N.getString("param.license-text.name"), + I18N.getString("param.license-text.description"), + "linux.deb.licenseText", + String.class, + params -> { + try { + String licenseFile = LICENSE_FILE.fetchFrom(params); + if (licenseFile != null) { + return Files.readString(new File(licenseFile).toPath()); + } + } catch (Exception e) { + if (Log.isDebug()) { + e.printStackTrace(); + } + } + return "Unknown"; + }, + (s, p) -> s); + + public static final BundlerParamInfo XDG_FILE_PREFIX = + new StandardBundlerParam<> ( + I18N.getString("param.xdg-prefix.name"), + I18N.getString("param.xdg-prefix.description"), + "linux.xdg-prefix", + String.class, + params -> { + try { + String vendor; + if (params.containsKey(VENDOR.getID())) { + vendor = VENDOR.fetchFrom(params); + } else { + vendor = "jpackage"; + } + String appName = APP_FS_NAME.fetchFrom(params); + + return (appName + "-" + vendor).replaceAll("\\s", ""); + } catch (Exception e) { + if (Log.isDebug()) { + e.printStackTrace(); + } + } + return "unknown-MimeInfo.xml"; + }, + (s, p) -> s); + + private final static String DEFAULT_ICON = "javalogo_white_32.png"; + private final static String DEFAULT_CONTROL_TEMPLATE = "template.control"; + private final static String DEFAULT_PRERM_TEMPLATE = "template.prerm"; + private final static String DEFAULT_PREINSTALL_TEMPLATE = + "template.preinst"; + private final static String DEFAULT_POSTRM_TEMPLATE = "template.postrm"; + private final static String DEFAULT_POSTINSTALL_TEMPLATE = + "template.postinst"; + private final static String DEFAULT_COPYRIGHT_TEMPLATE = + "template.copyright"; + private final static String DEFAULT_DESKTOP_FILE_TEMPLATE = + "template.desktop"; + + public final static String TOOL_DPKG = "dpkg-deb"; + + public static boolean testTool(String toolName, String minVersion) { + try { + ProcessBuilder pb = new ProcessBuilder( + toolName, + "--version"); + // not interested in the output + IOUtils.exec(pb, Log.isDebug(), true); + } catch (Exception e) { + Log.verbose(MessageFormat.format(I18N.getString( + "message.test-for-tool"), toolName, e.getMessage())); + return false; + } + return true; + } + + @Override + public boolean validate(Map p) + throws UnsupportedPlatformException, ConfigException { + try { + if (p == null) throw new ConfigException( + I18N.getString("error.parameters-null"), + I18N.getString("error.parameters-null.advice")); + + //run basic validation to ensure requirements are met + //we are not interested in return code, only possible exception + APP_BUNDLER.fetchFrom(p).validate(p); + + // NOTE: Can we validate that the required tools are available + // before we start? + if (!testTool(TOOL_DPKG, "1")){ + throw new ConfigException(MessageFormat.format( + I18N.getString("error.tool-not-found"), TOOL_DPKG), + I18N.getString("error.tool-not-found.advice")); + } + + + // Show warning is license file is missing + String licenseFile = LICENSE_FILE.fetchFrom(p); + if (licenseFile == null) { + Log.verbose(I18N.getString("message.debs-like-licenses")); + } + + // only one mime type per association, at least one file extention + List> associations = + FILE_ASSOCIATIONS.fetchFrom(p); + if (associations != null) { + for (int i = 0; i < associations.size(); i++) { + Map assoc = associations.get(i); + List mimes = FA_CONTENT_TYPE.fetchFrom(assoc); + if (mimes == null || mimes.isEmpty()) { + String msgKey = + "error.no-content-types-for-file-association"; + throw new ConfigException( + MessageFormat.format(I18N.getString(msgKey), i), + I18N.getString(msgKey + ".advise")); + + } else if (mimes.size() > 1) { + String msgKey = + "error.too-many-content-types-for-file-association"; + throw new ConfigException( + MessageFormat.format(I18N.getString(msgKey), i), + I18N.getString(msgKey + ".advise")); + } + } + } + + // bundle name has some restrictions + // the string converter will throw an exception if invalid + BUNDLE_NAME.getStringConverter().apply(BUNDLE_NAME.fetchFrom(p), p); + + return true; + } catch (RuntimeException re) { + if (re.getCause() instanceof ConfigException) { + throw (ConfigException) re.getCause(); + } else { + throw new ConfigException(re); + } + } + } + + private boolean prepareProto(Map p) + throws IOException { + File appImage = StandardBundlerParam.getPredefinedAppImage(p); + File appDir = null; + + // we either have an application image or need to build one + if (appImage != null) { + appDir = new File(APP_IMAGE_ROOT.fetchFrom(p), + APP_NAME.fetchFrom(p)); + // copy everything from appImage dir into appDir/name + IOUtils.copyRecursive(appImage.toPath(), appDir.toPath()); + } else { + appDir = APP_BUNDLER.fetchFrom(p).doBundle(p, + APP_IMAGE_ROOT.fetchFrom(p), true); + } + return appDir != null; + } + + //@Override + public File bundle(Map p, File outdir) { + if (!outdir.isDirectory() && !outdir.mkdirs()) { + throw new RuntimeException(MessageFormat.format( + I18N.getString("error.cannot-create-output-dir"), + outdir.getAbsolutePath())); + } + if (!outdir.canWrite()) { + throw new RuntimeException(MessageFormat.format( + I18N.getString("error.cannot-write-to-output-dir"), + outdir.getAbsolutePath())); + } + + // we want to create following structure + // + // DEBIAN + // control (file with main package details) + // menu (request to create menu) + // ... other control files if needed .... + // opt (by default) + // AppFolder (this is where app image goes) + // launcher executable + // app + // runtime + + File imageDir = DEB_IMAGE_DIR.fetchFrom(p); + File configDir = CONFIG_DIR.fetchFrom(p); + + try { + + imageDir.mkdirs(); + configDir.mkdirs(); + if (prepareProto(p) && prepareProjectConfig(p)) { + return buildDeb(p, outdir); + } + return null; + } catch (IOException ex) { + ex.printStackTrace(); + return null; + } + } + + /* + * set permissions with a string like "rwxr-xr-x" + * + * This cannot be directly backport to 22u which is built with 1.6 + */ + private void setPermissions(File file, String permissions) { + Set filePermissions = + PosixFilePermissions.fromString(permissions); + try { + if (file.exists()) { + Files.setPosixFilePermissions(file.toPath(), filePermissions); + } + } catch (IOException ex) { + Logger.getLogger(LinuxDebBundler.class.getName()).log( + Level.SEVERE, null, ex); + } + + } + + private String getArch() { + String arch = System.getProperty("os.arch"); + if ("i386".equals(arch)) + return "i386"; + else + return "amd64"; + } + + private long getInstalledSizeKB(Map params) { + return getInstalledSizeKB(APP_IMAGE_ROOT.fetchFrom(params)) >> 10; + } + + private long getInstalledSizeKB(File dir) { + long count = 0; + File[] children = dir.listFiles(); + if (children != null) { + for (File file : children) { + if (file.isFile()) { + count += file.length(); + } + else if (file.isDirectory()) { + count += getInstalledSizeKB(file); + } + } + } + return count; + } + + private boolean prepareProjectConfig(Map params) + throws IOException { + Map data = createReplacementData(params); + File rootDir = LinuxAppBundler.getRootDir(APP_IMAGE_ROOT.fetchFrom( + params), params); + + File iconTarget = getConfig_IconFile(rootDir, params); + File icon = ICON_PNG.fetchFrom(params); + if (!Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) { + // prepare installer icon + if (icon == null || !icon.exists()) { + fetchResource(iconTarget.getName(), + I18N.getString("resource.menu-icon"), + DEFAULT_ICON, + iconTarget, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + } else { + fetchResource(iconTarget.getName(), + I18N.getString("resource.menu-icon"), + icon, + iconTarget, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + } + } + + StringBuilder installScripts = new StringBuilder(); + StringBuilder removeScripts = new StringBuilder(); + for (Map secondaryLauncher : + SECONDARY_LAUNCHERS.fetchFrom(params)) { + Map secondaryLauncherData = + createReplacementData(secondaryLauncher); + secondaryLauncherData.put("APPLICATION_FS_NAME", + data.get("APPLICATION_FS_NAME")); + secondaryLauncherData.put("DESKTOP_MIMES", ""); + + if (!Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) { + // prepare desktop shortcut + Writer w = new BufferedWriter(new FileWriter( + getConfig_DesktopShortcutFile( + rootDir, secondaryLauncher))); + String content = preprocessTextResource( + getConfig_DesktopShortcutFile(rootDir, + secondaryLauncher).getName(), + I18N.getString("resource.menu-shortcut-descriptor"), + DEFAULT_DESKTOP_FILE_TEMPLATE, + secondaryLauncherData, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + } + + // prepare installer icon + iconTarget = getConfig_IconFile(rootDir, secondaryLauncher); + icon = ICON_PNG.fetchFrom(secondaryLauncher); + if (icon == null || !icon.exists()) { + fetchResource(iconTarget.getName(), + I18N.getString("resource.menu-icon"), + DEFAULT_ICON, + iconTarget, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + } else { + fetchResource(iconTarget.getName(), + I18N.getString("resource.menu-icon"), + icon, + iconTarget, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + } + + // postinst copying of desktop icon + installScripts.append( + " xdg-desktop-menu install --novendor "); + installScripts.append(LINUX_INSTALL_DIR.fetchFrom(params)); + installScripts.append("/"); + installScripts.append(data.get("APPLICATION_FS_NAME")); + installScripts.append("/"); + installScripts.append( + secondaryLauncherData.get("APPLICATION_LAUNCHER_FILENAME")); + installScripts.append(".desktop\n"); + + // postrm cleanup of desktop icon + removeScripts.append( + " xdg-desktop-menu uninstall --novendor "); + removeScripts.append(LINUX_INSTALL_DIR.fetchFrom(params)); + removeScripts.append("/"); + removeScripts.append(data.get("APPLICATION_FS_NAME")); + removeScripts.append("/"); + removeScripts.append( + secondaryLauncherData.get("APPLICATION_LAUNCHER_FILENAME")); + removeScripts.append(".desktop\n"); + } + data.put("SECONDARY_LAUNCHERS_INSTALL", installScripts.toString()); + data.put("SECONDARY_LAUNCHERS_REMOVE", removeScripts.toString()); + + List> associations = + FILE_ASSOCIATIONS.fetchFrom(params); + data.put("FILE_ASSOCIATION_INSTALL", ""); + data.put("FILE_ASSOCIATION_REMOVE", ""); + data.put("DESKTOP_MIMES", ""); + if (associations != null) { + String mimeInfoFile = XDG_FILE_PREFIX.fetchFrom(params) + + "-MimeInfo.xml"; + StringBuilder mimeInfo = new StringBuilder( + "\n\n"); + StringBuilder registrations = new StringBuilder(); + StringBuilder deregistrations = new StringBuilder(); + StringBuilder desktopMimes = new StringBuilder("MimeType="); + boolean addedEntry = false; + + for (Map assoc : associations) { + // + // Awesome document + // + // + // + + if (assoc == null) { + continue; + } + + String description = FA_DESCRIPTION.fetchFrom(assoc); + File faIcon = FA_ICON.fetchFrom(assoc); + List extensions = FA_EXTENSIONS.fetchFrom(assoc); + if (extensions == null) { + Log.error(I18N.getString( + "message.creating-association-with-null-extension")); + } + + List mimes = FA_CONTENT_TYPE.fetchFrom(assoc); + if (mimes == null || mimes.isEmpty()) { + continue; + } + String thisMime = mimes.get(0); + String dashMime = thisMime.replace('/', '-'); + + mimeInfo.append(" \n"); + if (description != null && !description.isEmpty()) { + mimeInfo.append(" ") + .append(description) + .append("\n"); + } + + if (extensions != null) { + for (String ext : extensions) { + mimeInfo.append(" \n"); + } + } + + mimeInfo.append(" \n"); + if (!addedEntry) { + registrations.append(" xdg-mime install ") + .append(LINUX_INSTALL_DIR.fetchFrom(params)) + .append("/") + .append(data.get("APPLICATION_FS_NAME")) + .append("/") + .append(mimeInfoFile) + .append("\n"); + + deregistrations.append(" xdg-mime uninstall ") + .append(LINUX_INSTALL_DIR.fetchFrom(params)) + .append("/") + .append(data.get("APPLICATION_FS_NAME")) + .append("/") + .append(mimeInfoFile) + .append("\n"); + addedEntry = true; + } else { + desktopMimes.append(";"); + } + desktopMimes.append(thisMime); + + if (faIcon != null && faIcon.exists()) { + int size = getSquareSizeOfImage(faIcon); + + if (size > 0) { + File target = new File(rootDir, + APP_FS_NAME.fetchFrom(params) + + "_fa_" + faIcon.getName()); + IOUtils.copyFile(faIcon, target); + + // xdg-icon-resource install --context mimetypes + // --size 64 awesomeapp_fa_1.png + // application-x.vnd-awesome + registrations.append( + " xdg-icon-resource install " + + "--context mimetypes --size ") + .append(size) + .append(" ") + .append(LINUX_INSTALL_DIR.fetchFrom(params)) + .append("/") + .append(data.get("APPLICATION_FS_NAME")) + .append("/") + .append(target.getName()) + .append(" ") + .append(dashMime) + .append("\n"); + + // x dg-icon-resource uninstall --context mimetypes + // --size 64 awesomeapp_fa_1.png + // application-x.vnd-awesome + deregistrations.append( + " xdg-icon-resource uninstall " + + "--context mimetypes --size ") + .append(size) + .append(" ") + .append(LINUX_INSTALL_DIR.fetchFrom(params)) + .append("/") + .append(data.get("APPLICATION_FS_NAME")) + .append("/") + .append(target.getName()) + .append(" ") + .append(dashMime) + .append("\n"); + } + } + } + mimeInfo.append(""); + + if (addedEntry) { + Writer w = new BufferedWriter(new FileWriter( + new File(rootDir, mimeInfoFile))); + w.write(mimeInfo.toString()); + w.close(); + data.put("FILE_ASSOCIATION_INSTALL", registrations.toString()); + data.put("FILE_ASSOCIATION_REMOVE", deregistrations.toString()); + data.put("DESKTOP_MIMES", desktopMimes.toString()); + } + } + + if (!Arguments.CREATE_JRE_INSTALLER.fetchFrom(params)) { + //prepare desktop shortcut + Writer w = new BufferedWriter(new FileWriter( + getConfig_DesktopShortcutFile(rootDir, params))); + String content = preprocessTextResource( + getConfig_DesktopShortcutFile( + rootDir, params).getName(), + I18N.getString("resource.menu-shortcut-descriptor"), + DEFAULT_DESKTOP_FILE_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + } + // prepare control file + Writer w = new BufferedWriter(new FileWriter( + getConfig_ControlFile(params))); + String content = preprocessTextResource( + getConfig_ControlFile(params).getName(), + I18N.getString("resource.deb-control-file"), + DEFAULT_CONTROL_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + + w = new BufferedWriter(new FileWriter( + getConfig_PreinstallFile(params))); + content = preprocessTextResource( + getConfig_PreinstallFile(params).getName(), + I18N.getString("resource.deb-preinstall-script"), + DEFAULT_PREINSTALL_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + setPermissions(getConfig_PreinstallFile(params), "rwxr-xr-x"); + + w = new BufferedWriter(new FileWriter(getConfig_PrermFile(params))); + content = preprocessTextResource( + getConfig_PrermFile(params).getName(), + I18N.getString("resource.deb-prerm-script"), + DEFAULT_PRERM_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + setPermissions(getConfig_PrermFile(params), "rwxr-xr-x"); + + w = new BufferedWriter(new FileWriter( + getConfig_PostinstallFile(params))); + content = preprocessTextResource( + getConfig_PostinstallFile(params).getName(), + I18N.getString("resource.deb-postinstall-script"), + DEFAULT_POSTINSTALL_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + setPermissions(getConfig_PostinstallFile(params), "rwxr-xr-x"); + + w = new BufferedWriter(new FileWriter(getConfig_PostrmFile(params))); + content = preprocessTextResource( + getConfig_PostrmFile(params).getName(), + I18N.getString("resource.deb-postrm-script"), + DEFAULT_POSTRM_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + setPermissions(getConfig_PostrmFile(params), "rwxr-xr-x"); + + w = new BufferedWriter(new FileWriter(getConfig_CopyrightFile(params))); + content = preprocessTextResource( + getConfig_CopyrightFile(params).getName(), + I18N.getString("resource.deb-copyright-file"), + DEFAULT_COPYRIGHT_TEMPLATE, + data, + VERBOSE.fetchFrom(params), + RESOURCE_DIR.fetchFrom(params)); + w.write(content); + w.close(); + + return true; + } + + private Map createReplacementData( + Map params) { + Map data = new HashMap<>(); + + data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params)); + data.put("APPLICATION_FS_NAME", APP_FS_NAME.fetchFrom(params)); + data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params)); + data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params)); + data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params)); + data.put("APPLICATION_VERSION", VERSION.fetchFrom(params)); + data.put("APPLICATION_LAUNCHER_FILENAME", + APP_FS_NAME.fetchFrom(params)); + data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params)); + data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params)); + data.put("DEPLOY_BUNDLE_CATEGORY", CATEGORY.fetchFrom(params)); + data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params)); + data.put("APPLICATION_SUMMARY", TITLE.fetchFrom(params)); + data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params)); + data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params)); + data.put("APPLICATION_ARCH", getArch()); + data.put("APPLICATION_INSTALLED_SIZE", + Long.toString(getInstalledSizeKB(params))); + String deps = LINUX_PACKAGE_DEPENDENCIES.fetchFrom(params); + data.put("PACKAGE_DEPENDENCIES", + deps.isEmpty() ? "" : "Depends: " + deps); + data.put("CREATE_JRE_INSTALLER", + Arguments.CREATE_JRE_INSTALLER.fetchFrom(params).toString()); + + return data; + } + + private File getConfig_DesktopShortcutFile(File rootDir, + Map params) { + return new File(rootDir, + APP_FS_NAME.fetchFrom(params) + ".desktop"); + } + + private File getConfig_IconFile(File rootDir, + Map params) { + return new File(rootDir, + APP_FS_NAME.fetchFrom(params) + ".png"); + } + + private File getConfig_InitScriptFile(Map params) { + return new File(LinuxAppBundler.getRootDir( + APP_IMAGE_ROOT.fetchFrom(params), params), + BUNDLE_NAME.fetchFrom(params) + ".init"); + } + + private File getConfig_ControlFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "control"); + } + + private File getConfig_PreinstallFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "preinst"); + } + + private File getConfig_PrermFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "prerm"); + } + + private File getConfig_PostinstallFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "postinst"); + } + + private File getConfig_PostrmFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "postrm"); + } + + private File getConfig_CopyrightFile(Map params) { + return new File(CONFIG_DIR.fetchFrom(params), "copyright"); + } + + private File buildDeb(Map params, + File outdir) throws IOException { + File outFile = new File(outdir, + FULL_PACKAGE_NAME.fetchFrom(params)+".deb"); + Log.verbose(MessageFormat.format(I18N.getString( + "message.outputting-to-location"), outFile.getAbsolutePath())); + + outFile.getParentFile().mkdirs(); + + // run dpkg + ProcessBuilder pb = new ProcessBuilder( + "fakeroot", TOOL_DPKG, "-b", + FULL_PACKAGE_NAME.fetchFrom(params), + outFile.getAbsolutePath()); + pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile()); + IOUtils.exec(pb, false); + + Log.verbose(MessageFormat.format(I18N.getString( + "message.output-to-location"), outFile.getAbsolutePath())); + + return outFile; + } + + @Override + public String getName() { + return I18N.getString("deb.bundler.name"); + } + + @Override + public String getDescription() { + return I18N.getString("deb.bundler.description"); + } + + @Override + public String getID() { + return "deb"; + } + + @Override + public String getBundleType() { + return "INSTALLER"; + } + + @Override + public Collection> getBundleParameters() { + Collection> results = new LinkedHashSet<>(); + results.addAll(LinuxAppBundler.getAppBundleParameters()); + results.addAll(getDebBundleParameters()); + return results; + } + + public static Collection> getDebBundleParameters() { + return Arrays.asList( + BUNDLE_NAME, + COPYRIGHT, + CATEGORY, + DESCRIPTION, + EMAIL, + ICON_PNG, + LICENSE_FILE, + TITLE, + VENDOR + ); + } + + @Override + public File execute(Map params, + File outputParentDir) { + return bundle(params, outputParentDir); + } + + @Override + public boolean supported() { + return (Platform.getPlatform() == Platform.LINUX); + } + + public int getSquareSizeOfImage(File f) { + try { + BufferedImage bi = ImageIO.read(f); + if (bi.getWidth() == bi.getHeight()) { + return bi.getWidth(); + } else { + return 0; + } + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } +}