< prev index next >

src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java

Print this page




  32 import java.nio.file.attribute.PosixFilePermission;
  33 import java.nio.file.attribute.PosixFilePermissions;
  34 import java.text.MessageFormat;
  35 import java.util.*;
  36 import java.util.logging.Level;
  37 import java.util.logging.Logger;
  38 import java.util.regex.Matcher;
  39 import java.util.regex.Pattern;
  40 
  41 import static jdk.jpackage.internal.StandardBundlerParam.*;
  42 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR;
  43 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES;
  44 
  45 public class LinuxRpmBundler extends AbstractBundler {
  46 
  47     private static final ResourceBundle I18N = ResourceBundle.getBundle(
  48             "jdk.jpackage.internal.resources.LinuxResources");
  49 
  50     public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER =
  51             new StandardBundlerParam<>(
  52             I18N.getString("param.rpm-app-bundler.name"),
  53             I18N.getString("param.rpm-app-bundler.description"),
  54             "linux.app.bundler",
  55             LinuxAppBundler.class,
  56             params -> new LinuxAppBundler(),
  57             null);
  58 
  59     public static final BundlerParamInfo<File> RPM_IMAGE_DIR =
  60             new StandardBundlerParam<>(
  61             I18N.getString("param.image-dir.name"),
  62             I18N.getString("param.image-dir.description"),
  63             "linux.rpm.imageDir",
  64             File.class,
  65             params -> {
  66                 File imagesRoot = IMAGES_ROOT.fetchFrom(params);
  67                 if (!imagesRoot.exists()) imagesRoot.mkdirs();
  68                 return new File(imagesRoot, "linux-rpm.image");
  69             },
  70             (s, p) -> new File(s));
  71 
  72     // Fedora rules for package naming are used here
  73     // https://fedoraproject.org/wiki/Packaging:NamingGuidelines?rd=Packaging/NamingGuidelines
  74     //
  75     // all Fedora packages must be named using only the following ASCII
  76     // characters. These characters are displayed here:
  77     //
  78     // abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._+
  79     //
  80     private static final Pattern RPM_BUNDLE_NAME_PATTERN =
  81             Pattern.compile("[a-z\\d\\+\\-\\.\\_]+", Pattern.CASE_INSENSITIVE);
  82 
  83     public static final BundlerParamInfo<String> BUNDLE_NAME =
  84             new StandardBundlerParam<> (
  85             I18N.getString("param.bundle-name.name"),
  86             I18N.getString("param.bundle-name.description"),
  87             Arguments.CLIOptions.LINUX_BUNDLE_NAME.getId(),
  88             String.class,
  89             params -> {
  90                 String nm = APP_NAME.fetchFrom(params);
  91                 if (nm == null) return null;
  92 
  93                 // make sure to lower case and spaces become dashes
  94                 nm = nm.toLowerCase().replaceAll("[ ]", "-");
  95 
  96                 return nm;
  97             },
  98             (s, p) -> {
  99                 if (!RPM_BUNDLE_NAME_PATTERN.matcher(s).matches()) {
 100                     String msgKey = "error.invalid-value-for-package-name";
 101                     throw new IllegalArgumentException(
 102                             new ConfigException(MessageFormat.format(
 103                                     I18N.getString(msgKey), s),
 104                                     I18N.getString(msgKey + ".advice")));
 105                 }
 106 
 107                 return s;
 108             }
 109         );
 110 








 111     public static final BundlerParamInfo<String> LICENSE_TYPE =
 112         new StandardBundlerParam<>(
 113                 I18N.getString("param.license-type.name"),
 114                 I18N.getString("param.license-type.description"),
 115                 Arguments.CLIOptions.LINUX_RPM_LICENSE_TYPE.getId(),
 116                 String.class,
 117                 params -> I18N.getString("param.license-type.default"),
 118                 (s, p) -> s
 119         );
 120 
 121     public static final BundlerParamInfo<String> XDG_FILE_PREFIX =
 122             new StandardBundlerParam<> (
 123             I18N.getString("param.xdg-prefix.name"),
 124             I18N.getString("param.xdg-prefix.description"),
 125             "linux.xdg-prefix",
 126             String.class,
 127             params -> {
 128                 try {
 129                     String vendor;
 130                     if (params.containsKey(VENDOR.getID())) {
 131                         vendor = VENDOR.fetchFrom(params);
 132                     } else {
 133                         vendor = "jpackage";
 134                     }
 135                     String appName = APP_NAME.fetchFrom(params);
 136 
 137                     return (vendor + "-" + appName).replaceAll("\\s", "");
 138                 } catch (Exception e) {
 139                     if (Log.isDebug()) {
 140                         e.printStackTrace();
 141                     }
 142                 }
 143                 return "unknown-MimeInfo.xml";
 144             },


 299             sb.append("%license ");
 300             sb.append(LINUX_INSTALL_DIR.fetchFrom(params));
 301             sb.append("/");
 302             sb.append(APP_NAME.fetchFrom(params));
 303             sb.append("/app/");
 304             sb.append(licenseFile.getName());
 305         }
 306 
 307         return sb.toString();
 308     }
 309 
 310     private boolean prepareProjectConfig(Map<String, ? super Object> params)
 311             throws IOException {
 312         Map<String, String> data = createReplacementData(params);
 313         File rootDir =
 314             LinuxAppBundler.getRootDir(RPM_IMAGE_DIR.fetchFrom(params), params);
 315 
 316         // prepare installer icon
 317         File iconTarget = getConfig_IconFile(rootDir, params);
 318         File icon = LinuxAppBundler.ICON_PNG.fetchFrom(params);
 319         if (!RUNTIME_INSTALLER.fetchFrom(params)) {
 320             if (icon == null || !icon.exists()) {
 321                 fetchResource(iconTarget.getName(),
 322                         I18N.getString("resource.menu-icon"),
 323                         DEFAULT_ICON,
 324                         iconTarget,
 325                         VERBOSE.fetchFrom(params),
 326                         RESOURCE_DIR.fetchFrom(params));
 327             } else {
 328                 fetchResource(iconTarget.getName(),
 329                         I18N.getString("resource.menu-icon"),
 330                         icon,
 331                         iconTarget,
 332                         VERBOSE.fetchFrom(params),
 333                         RESOURCE_DIR.fetchFrom(params));
 334             }
 335         }
 336 
 337         StringBuilder installScripts = new StringBuilder();
 338         StringBuilder removeScripts = new StringBuilder();
 339         for (Map<String, ? super Object> secondaryLauncher :
 340                 SECONDARY_LAUNCHERS.fetchFrom(params)) {
 341             Map<String, String> secondaryLauncherData =
 342                     createReplacementData(secondaryLauncher);
 343             secondaryLauncherData.put("APPLICATION_FS_NAME",
 344                     data.get("APPLICATION_FS_NAME"));
 345             secondaryLauncherData.put("DESKTOP_MIMES", "");
 346 
 347             // prepare desktop shortcut
 348             Writer w = new BufferedWriter(new FileWriter(
 349                     getConfig_DesktopShortcutFile(rootDir, secondaryLauncher)));
 350             String content = preprocessTextResource(
 351                     getConfig_DesktopShortcutFile(rootDir,
 352                     secondaryLauncher).getName(),
 353                     I18N.getString("resource.menu-shortcut-descriptor"),
 354                     DEFAULT_DESKTOP_FILE_TEMPLATE, secondaryLauncherData,
 355                     VERBOSE.fetchFrom(params),
 356                     RESOURCE_DIR.fetchFrom(params));
 357             w.write(content);
 358             w.close();
 359 
 360             // prepare installer icon
 361             iconTarget = getConfig_IconFile(rootDir, secondaryLauncher);
 362             icon = LinuxAppBundler.ICON_PNG.fetchFrom(secondaryLauncher);
 363             if (icon == null || !icon.exists()) {
 364                 fetchResource(iconTarget.getName(),
 365                         I18N.getString("resource.menu-icon"),
 366                         DEFAULT_ICON,
 367                         iconTarget,
 368                         VERBOSE.fetchFrom(params),
 369                         RESOURCE_DIR.fetchFrom(params));
 370             } else {
 371                 fetchResource(iconTarget.getName(),
 372                         I18N.getString("resource.menu-icon"),
 373                         icon,
 374                         iconTarget,
 375                         VERBOSE.fetchFrom(params),
 376                         RESOURCE_DIR.fetchFrom(params));
 377             }
 378 
 379             // post copying of desktop icon
 380             installScripts.append("xdg-desktop-menu install --novendor ");
 381             installScripts.append(LINUX_INSTALL_DIR.fetchFrom(params));
 382             installScripts.append("/");
 383             installScripts.append(data.get("APPLICATION_FS_NAME"));
 384             installScripts.append("/");
 385             installScripts.append(secondaryLauncherData.get(
 386                     "APPLICATION_LAUNCHER_FILENAME"));
 387             installScripts.append(".desktop\n");
 388 
 389             // preun cleanup of desktop icon
 390             removeScripts.append("xdg-desktop-menu uninstall --novendor ");
 391             removeScripts.append(LINUX_INSTALL_DIR.fetchFrom(params));
 392             removeScripts.append("/");
 393             removeScripts.append(data.get("APPLICATION_FS_NAME"));
 394             removeScripts.append("/");
 395             removeScripts.append(secondaryLauncherData.get(
 396                     "APPLICATION_LAUNCHER_FILENAME"));
 397             removeScripts.append(".desktop\n");
 398 
 399         }
 400         data.put("SECONDARY_LAUNCHERS_INSTALL", installScripts.toString());
 401         data.put("SECONDARY_LAUNCHERS_REMOVE", removeScripts.toString());
 402 
 403         StringBuilder cdsScript = new StringBuilder();
 404 
 405         data.put("APP_CDS_CACHE", cdsScript.toString());
 406 
 407         List<Map<String, ? super Object>> associations =
 408                 FILE_ASSOCIATIONS.fetchFrom(params);
 409         data.put("FILE_ASSOCIATION_INSTALL", "");
 410         data.put("FILE_ASSOCIATION_REMOVE", "");
 411         data.put("DESKTOP_MIMES", "");
 412         if (associations != null) {
 413             String mimeInfoFile = XDG_FILE_PREFIX.fetchFrom(params)
 414                     + "-MimeInfo.xml";
 415             StringBuilder mimeInfo = new StringBuilder(
 416                 "<?xml version=\"1.0\"?>\n<mime-info xmlns="
 417                 +"'http://www.freedesktop.org/standards/shared-mime-info'>\n");
 418             StringBuilder registrations = new StringBuilder();
 419             StringBuilder deregistrations = new StringBuilder();
 420             StringBuilder desktopMimes = new StringBuilder("MimeType=");
 421             boolean addedEntry = false;


 527                                 .append(target.getName())
 528                                 .append(" ")
 529                                 .append(dashMime)
 530                                 .append("\n");
 531                     }
 532                 }
 533             }
 534             mimeInfo.append("</mime-info>");
 535 
 536             if (addedEntry) {
 537                 Writer w = new BufferedWriter(new FileWriter(
 538                         new File(rootDir, mimeInfoFile)));
 539                 w.write(mimeInfo.toString());
 540                 w.close();
 541                 data.put("FILE_ASSOCIATION_INSTALL", registrations.toString());
 542                 data.put("FILE_ASSOCIATION_REMOVE", deregistrations.toString());
 543                 data.put("DESKTOP_MIMES", desktopMimes.toString());
 544             }
 545         }
 546 
 547         if (!RUNTIME_INSTALLER.fetchFrom(params)) {
 548             //prepare desktop shortcut
 549             Writer w = new BufferedWriter(new FileWriter(
 550                     getConfig_DesktopShortcutFile(rootDir, params)));
 551             String content = preprocessTextResource(
 552                     getConfig_DesktopShortcutFile(rootDir, params).getName(),
 553                     I18N.getString("resource.menu-shortcut-descriptor"),
 554                     DEFAULT_DESKTOP_FILE_TEMPLATE, data,
 555                     VERBOSE.fetchFrom(params),
 556                     RESOURCE_DIR.fetchFrom(params));
 557             w.write(content);
 558             w.close();
 559         }
 560 
 561         // prepare spec file
 562         Writer w = new BufferedWriter(
 563                 new FileWriter(getConfig_SpecFile(params)));
 564         String content = preprocessTextResource(
 565                 getConfig_SpecFile(params).getName(),
 566                 I18N.getString("resource.rpm-spec-file"),
 567                 DEFAULT_SPEC_TEMPLATE, data,
 568                 VERBOSE.fetchFrom(params),
 569                 RESOURCE_DIR.fetchFrom(params));
 570         w.write(content);
 571         w.close();
 572 
 573         return true;
 574     }
 575 
 576     private Map<String, String> createReplacementData(
 577             Map<String, ? super Object> params) throws IOException {
 578         Map<String, String> data = new HashMap<>();
 579 
 580         data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
 581         data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params));
 582         data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
 583         data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
 584         data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
 585         data.put("APPLICATION_LAUNCHER_FILENAME", APP_NAME.fetchFrom(params));
 586         data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params));
 587         data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params));
 588         data.put("DEPLOY_BUNDLE_CATEGORY", CATEGORY.fetchFrom(params));
 589         // TODO rpm categories
 590         data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params));
 591         data.put("APPLICATION_SUMMARY", TITLE.fetchFrom(params));
 592         data.put("APPLICATION_LICENSE_TYPE", LICENSE_TYPE.fetchFrom(params));
 593         data.put("APPLICATION_LICENSE_FILE", getLicenseFileString(params));
 594         String deps = LINUX_PACKAGE_DEPENDENCIES.fetchFrom(params);
 595         data.put("PACKAGE_DEPENDENCIES",
 596                 deps.isEmpty() ? "" : "Requires: " + deps);
 597         data.put("RUNTIME_INSTALLER",
 598                 RUNTIME_INSTALLER.fetchFrom(params).toString());
 599         return data;
 600     }
 601 
 602     private File getConfig_DesktopShortcutFile(File rootDir,
 603             Map<String, ? super Object> params) {
 604         return new File(rootDir, APP_NAME.fetchFrom(params) + ".desktop");
 605     }
 606 
 607     private File getConfig_IconFile(File rootDir,
 608             Map<String, ? super Object> params) {
 609         return new File(rootDir, APP_NAME.fetchFrom(params) + ".png");
 610     }
 611 
 612     private File getConfig_SpecFile(Map<String, ? super Object> params) {
 613         return new File(RPM_IMAGE_DIR.fetchFrom(params),
 614                 APP_NAME.fetchFrom(params) + ".spec");
 615     }
 616 
 617     private File buildRPM(Map<String, ? super Object> params,
 618             File outdir) throws IOException {
 619         Log.verbose(MessageFormat.format(I18N.getString(
 620                 "message.outputting-bundle-location"),
 621                 outdir.getAbsolutePath()));
 622 
 623         File broot = new File(BUILD_ROOT.fetchFrom(params), "rmpbuildroot");
 624 
 625         outdir.mkdirs();
 626 
 627         //run rpmbuild
 628         ProcessBuilder pb = new ProcessBuilder(
 629                 TOOL_RPMBUILD,
 630                 "-bb", getConfig_SpecFile(params).getAbsolutePath(),
 631                 "--define", "%_sourcedir "
 632                         + RPM_IMAGE_DIR.fetchFrom(params).getAbsolutePath(),
 633                 // save result to output dir
 634                 "--define", "%_rpmdir " + outdir.getAbsolutePath(),
 635                 // do not use other system directories to build as current user
 636                 "--define", "%_topdir " + broot.getAbsolutePath()
 637         );
 638         pb = pb.directory(RPM_IMAGE_DIR.fetchFrom(params));
 639         IOUtils.exec(pb, false);
 640 
 641         Log.verbose(MessageFormat.format(
 642                 I18N.getString("message.output-bundle-location"),
 643                 outdir.getAbsolutePath()));


 674     public String getID() {
 675         return "rpm";
 676     }
 677 
 678     @Override
 679     public String getBundleType() {
 680         return "INSTALLER";
 681     }
 682 
 683     @Override
 684     public Collection<BundlerParamInfo<?>> getBundleParameters() {
 685         Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
 686         results.addAll(LinuxAppBundler.getAppBundleParameters());
 687         results.addAll(getRpmBundleParameters());
 688         return results;
 689     }
 690 
 691     public static Collection<BundlerParamInfo<?>> getRpmBundleParameters() {
 692         return Arrays.asList(
 693                 BUNDLE_NAME,
 694                 CATEGORY,
 695                 DESCRIPTION,
 696                 LinuxAppBundler.ICON_PNG,
 697                 LICENSE_FILE,
 698                 LICENSE_TYPE,
 699                 TITLE,
 700                 VENDOR
 701         );
 702     }
 703 
 704     @Override
 705     public File execute(Map<String, ? super Object> params,
 706             File outputParentDir) throws PackagerException {
 707         return bundle(params, outputParentDir);
 708     }
 709 
 710     @Override
 711     public boolean supported(boolean runtimeInstaller) {
 712         return (Platform.getPlatform() == Platform.LINUX);
 713     }
 714 


  32 import java.nio.file.attribute.PosixFilePermission;
  33 import java.nio.file.attribute.PosixFilePermissions;
  34 import java.text.MessageFormat;
  35 import java.util.*;
  36 import java.util.logging.Level;
  37 import java.util.logging.Logger;
  38 import java.util.regex.Matcher;
  39 import java.util.regex.Pattern;
  40 
  41 import static jdk.jpackage.internal.StandardBundlerParam.*;
  42 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR;
  43 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES;
  44 
  45 public class LinuxRpmBundler extends AbstractBundler {
  46 
  47     private static final ResourceBundle I18N = ResourceBundle.getBundle(
  48             "jdk.jpackage.internal.resources.LinuxResources");
  49 
  50     public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER =
  51             new StandardBundlerParam<>(


  52             "linux.app.bundler",
  53             LinuxAppBundler.class,
  54             params -> new LinuxAppBundler(),
  55             null);
  56 
  57     public static final BundlerParamInfo<File> RPM_IMAGE_DIR =
  58             new StandardBundlerParam<>(


  59             "linux.rpm.imageDir",
  60             File.class,
  61             params -> {
  62                 File imagesRoot = IMAGES_ROOT.fetchFrom(params);
  63                 if (!imagesRoot.exists()) imagesRoot.mkdirs();
  64                 return new File(imagesRoot, "linux-rpm.image");
  65             },
  66             (s, p) -> new File(s));
  67 
  68     // Fedora rules for package naming are used here
  69     // https://fedoraproject.org/wiki/Packaging:NamingGuidelines?rd=Packaging/NamingGuidelines
  70     //
  71     // all Fedora packages must be named using only the following ASCII
  72     // characters. These characters are displayed here:
  73     //
  74     // abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._+
  75     //
  76     private static final Pattern RPM_BUNDLE_NAME_PATTERN =
  77             Pattern.compile("[a-z\\d\\+\\-\\.\\_]+", Pattern.CASE_INSENSITIVE);
  78 
  79     public static final BundlerParamInfo<String> BUNDLE_NAME =
  80             new StandardBundlerParam<> (


  81             Arguments.CLIOptions.LINUX_BUNDLE_NAME.getId(),
  82             String.class,
  83             params -> {
  84                 String nm = APP_NAME.fetchFrom(params);
  85                 if (nm == null) return null;
  86 
  87                 // make sure to lower case and spaces become dashes
  88                 nm = nm.toLowerCase().replaceAll("[ ]", "-");
  89 
  90                 return nm;
  91             },
  92             (s, p) -> {
  93                 if (!RPM_BUNDLE_NAME_PATTERN.matcher(s).matches()) {
  94                     String msgKey = "error.invalid-value-for-package-name";
  95                     throw new IllegalArgumentException(
  96                             new ConfigException(MessageFormat.format(
  97                                     I18N.getString(msgKey), s),
  98                                     I18N.getString(msgKey + ".advice")));
  99                 }
 100 
 101                 return s;
 102             }
 103         );
 104 
 105     public static final BundlerParamInfo<String> MENU_GROUP =
 106         new StandardBundlerParam<>(
 107                 Arguments.CLIOptions.LINUX_MENU_GROUP.getId(),
 108                 String.class,
 109                 params -> I18N.getString("param.menu-group.default"),
 110                 (s, p) -> s
 111         );
 112 
 113     public static final BundlerParamInfo<String> LICENSE_TYPE =
 114         new StandardBundlerParam<>(


 115                 Arguments.CLIOptions.LINUX_RPM_LICENSE_TYPE.getId(),
 116                 String.class,
 117                 params -> I18N.getString("param.license-type.default"),
 118                 (s, p) -> s
 119         );
 120 
 121     public static final BundlerParamInfo<String> XDG_FILE_PREFIX =
 122             new StandardBundlerParam<> (


 123             "linux.xdg-prefix",
 124             String.class,
 125             params -> {
 126                 try {
 127                     String vendor;
 128                     if (params.containsKey(VENDOR.getID())) {
 129                         vendor = VENDOR.fetchFrom(params);
 130                     } else {
 131                         vendor = "jpackage";
 132                     }
 133                     String appName = APP_NAME.fetchFrom(params);
 134 
 135                     return (vendor + "-" + appName).replaceAll("\\s", "");
 136                 } catch (Exception e) {
 137                     if (Log.isDebug()) {
 138                         e.printStackTrace();
 139                     }
 140                 }
 141                 return "unknown-MimeInfo.xml";
 142             },


 297             sb.append("%license ");
 298             sb.append(LINUX_INSTALL_DIR.fetchFrom(params));
 299             sb.append("/");
 300             sb.append(APP_NAME.fetchFrom(params));
 301             sb.append("/app/");
 302             sb.append(licenseFile.getName());
 303         }
 304 
 305         return sb.toString();
 306     }
 307 
 308     private boolean prepareProjectConfig(Map<String, ? super Object> params)
 309             throws IOException {
 310         Map<String, String> data = createReplacementData(params);
 311         File rootDir =
 312             LinuxAppBundler.getRootDir(RPM_IMAGE_DIR.fetchFrom(params), params);
 313 
 314         // prepare installer icon
 315         File iconTarget = getConfig_IconFile(rootDir, params);
 316         File icon = LinuxAppBundler.ICON_PNG.fetchFrom(params);
 317         if (!StandardBundlerParam.isRuntimeInstaller(params)) {
 318             if (icon == null || !icon.exists()) {
 319                 fetchResource(iconTarget.getName(),
 320                         I18N.getString("resource.menu-icon"),
 321                         DEFAULT_ICON,
 322                         iconTarget,
 323                         VERBOSE.fetchFrom(params),
 324                         RESOURCE_DIR.fetchFrom(params));
 325             } else {
 326                 fetchResource(iconTarget.getName(),
 327                         I18N.getString("resource.menu-icon"),
 328                         icon,
 329                         iconTarget,
 330                         VERBOSE.fetchFrom(params),
 331                         RESOURCE_DIR.fetchFrom(params));
 332             }
 333         }
 334 
 335         StringBuilder installScripts = new StringBuilder();
 336         StringBuilder removeScripts = new StringBuilder();
 337         for (Map<String, ? super Object> addLauncher :
 338                 ADD_LAUNCHERS.fetchFrom(params)) {
 339             Map<String, String> addLauncherData =
 340                     createReplacementData(addLauncher);
 341             addLauncherData.put("APPLICATION_FS_NAME",
 342                     data.get("APPLICATION_FS_NAME"));
 343             addLauncherData.put("DESKTOP_MIMES", "");
 344 
 345             // prepare desktop shortcut
 346             Writer w = new BufferedWriter(new FileWriter(
 347                     getConfig_DesktopShortcutFile(rootDir, addLauncher)));
 348             String content = preprocessTextResource(
 349                     getConfig_DesktopShortcutFile(rootDir,
 350                     addLauncher).getName(),
 351                     I18N.getString("resource.menu-shortcut-descriptor"),
 352                     DEFAULT_DESKTOP_FILE_TEMPLATE, addLauncherData,
 353                     VERBOSE.fetchFrom(params),
 354                     RESOURCE_DIR.fetchFrom(params));
 355             w.write(content);
 356             w.close();
 357 
 358             // prepare installer icon
 359             iconTarget = getConfig_IconFile(rootDir, addLauncher);
 360             icon = LinuxAppBundler.ICON_PNG.fetchFrom(addLauncher);
 361             if (icon == null || !icon.exists()) {
 362                 fetchResource(iconTarget.getName(),
 363                         I18N.getString("resource.menu-icon"),
 364                         DEFAULT_ICON,
 365                         iconTarget,
 366                         VERBOSE.fetchFrom(params),
 367                         RESOURCE_DIR.fetchFrom(params));
 368             } else {
 369                 fetchResource(iconTarget.getName(),
 370                         I18N.getString("resource.menu-icon"),
 371                         icon,
 372                         iconTarget,
 373                         VERBOSE.fetchFrom(params),
 374                         RESOURCE_DIR.fetchFrom(params));
 375             }
 376 
 377             // post copying of desktop icon
 378             installScripts.append("xdg-desktop-menu install --novendor ");
 379             installScripts.append(LINUX_INSTALL_DIR.fetchFrom(params));
 380             installScripts.append("/");
 381             installScripts.append(data.get("APPLICATION_FS_NAME"));
 382             installScripts.append("/");
 383             installScripts.append(addLauncherData.get(
 384                     "APPLICATION_LAUNCHER_FILENAME"));
 385             installScripts.append(".desktop\n");
 386 
 387             // preun cleanup of desktop icon
 388             removeScripts.append("xdg-desktop-menu uninstall --novendor ");
 389             removeScripts.append(LINUX_INSTALL_DIR.fetchFrom(params));
 390             removeScripts.append("/");
 391             removeScripts.append(data.get("APPLICATION_FS_NAME"));
 392             removeScripts.append("/");
 393             removeScripts.append(addLauncherData.get(
 394                     "APPLICATION_LAUNCHER_FILENAME"));
 395             removeScripts.append(".desktop\n");
 396 
 397         }
 398         data.put("ADD_LAUNCHERS_INSTALL", installScripts.toString());
 399         data.put("ADD_LAUNCHERS_REMOVE", removeScripts.toString());
 400 
 401         StringBuilder cdsScript = new StringBuilder();
 402 
 403         data.put("APP_CDS_CACHE", cdsScript.toString());
 404 
 405         List<Map<String, ? super Object>> associations =
 406                 FILE_ASSOCIATIONS.fetchFrom(params);
 407         data.put("FILE_ASSOCIATION_INSTALL", "");
 408         data.put("FILE_ASSOCIATION_REMOVE", "");
 409         data.put("DESKTOP_MIMES", "");
 410         if (associations != null) {
 411             String mimeInfoFile = XDG_FILE_PREFIX.fetchFrom(params)
 412                     + "-MimeInfo.xml";
 413             StringBuilder mimeInfo = new StringBuilder(
 414                 "<?xml version=\"1.0\"?>\n<mime-info xmlns="
 415                 +"'http://www.freedesktop.org/standards/shared-mime-info'>\n");
 416             StringBuilder registrations = new StringBuilder();
 417             StringBuilder deregistrations = new StringBuilder();
 418             StringBuilder desktopMimes = new StringBuilder("MimeType=");
 419             boolean addedEntry = false;


 525                                 .append(target.getName())
 526                                 .append(" ")
 527                                 .append(dashMime)
 528                                 .append("\n");
 529                     }
 530                 }
 531             }
 532             mimeInfo.append("</mime-info>");
 533 
 534             if (addedEntry) {
 535                 Writer w = new BufferedWriter(new FileWriter(
 536                         new File(rootDir, mimeInfoFile)));
 537                 w.write(mimeInfo.toString());
 538                 w.close();
 539                 data.put("FILE_ASSOCIATION_INSTALL", registrations.toString());
 540                 data.put("FILE_ASSOCIATION_REMOVE", deregistrations.toString());
 541                 data.put("DESKTOP_MIMES", desktopMimes.toString());
 542             }
 543         }
 544 
 545         if (!StandardBundlerParam.isRuntimeInstaller(params)) {
 546             //prepare desktop shortcut
 547             Writer w = new BufferedWriter(new FileWriter(
 548                     getConfig_DesktopShortcutFile(rootDir, params)));
 549             String content = preprocessTextResource(
 550                     getConfig_DesktopShortcutFile(rootDir, params).getName(),
 551                     I18N.getString("resource.menu-shortcut-descriptor"),
 552                     DEFAULT_DESKTOP_FILE_TEMPLATE, data,
 553                     VERBOSE.fetchFrom(params),
 554                     RESOURCE_DIR.fetchFrom(params));
 555             w.write(content);
 556             w.close();
 557         }
 558 
 559         // prepare spec file
 560         Writer w = new BufferedWriter(
 561                 new FileWriter(getConfig_SpecFile(params)));
 562         String content = preprocessTextResource(
 563                 getConfig_SpecFile(params).getName(),
 564                 I18N.getString("resource.rpm-spec-file"),
 565                 DEFAULT_SPEC_TEMPLATE, data,
 566                 VERBOSE.fetchFrom(params),
 567                 RESOURCE_DIR.fetchFrom(params));
 568         w.write(content);
 569         w.close();
 570 
 571         return true;
 572     }
 573 
 574     private Map<String, String> createReplacementData(
 575             Map<String, ? super Object> params) throws IOException {
 576         Map<String, String> data = new HashMap<>();
 577 
 578         data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
 579         data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params));
 580         data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
 581         data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
 582         data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
 583         data.put("APPLICATION_LAUNCHER_FILENAME", APP_NAME.fetchFrom(params));
 584         data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params));
 585         data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params));
 586         data.put("DEPLOY_BUNDLE_CATEGORY", MENU_GROUP.fetchFrom(params));
 587         // TODO rpm categories
 588         data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params));
 589         data.put("APPLICATION_SUMMARY", TITLE.fetchFrom(params));
 590         data.put("APPLICATION_LICENSE_TYPE", LICENSE_TYPE.fetchFrom(params));
 591         data.put("APPLICATION_LICENSE_FILE", getLicenseFileString(params));
 592         String deps = LINUX_PACKAGE_DEPENDENCIES.fetchFrom(params);
 593         data.put("PACKAGE_DEPENDENCIES",
 594                 deps.isEmpty() ? "" : "Requires: " + deps);
 595         data.put("RUNTIME_INSTALLER", "" +
 596                 StandardBundlerParam.isRuntimeInstaller(params));
 597         return data;
 598     }
 599 
 600     private File getConfig_DesktopShortcutFile(File rootDir,
 601             Map<String, ? super Object> params) {
 602         return new File(rootDir, APP_NAME.fetchFrom(params) + ".desktop");
 603     }
 604 
 605     private File getConfig_IconFile(File rootDir,
 606             Map<String, ? super Object> params) {
 607         return new File(rootDir, APP_NAME.fetchFrom(params) + ".png");
 608     }
 609 
 610     private File getConfig_SpecFile(Map<String, ? super Object> params) {
 611         return new File(RPM_IMAGE_DIR.fetchFrom(params),
 612                 APP_NAME.fetchFrom(params) + ".spec");
 613     }
 614 
 615     private File buildRPM(Map<String, ? super Object> params,
 616             File outdir) throws IOException {
 617         Log.verbose(MessageFormat.format(I18N.getString(
 618                 "message.outputting-bundle-location"),
 619                 outdir.getAbsolutePath()));
 620 
 621         File broot = new File(TEMP_ROOT.fetchFrom(params), "rmpbuildroot");
 622 
 623         outdir.mkdirs();
 624 
 625         //run rpmbuild
 626         ProcessBuilder pb = new ProcessBuilder(
 627                 TOOL_RPMBUILD,
 628                 "-bb", getConfig_SpecFile(params).getAbsolutePath(),
 629                 "--define", "%_sourcedir "
 630                         + RPM_IMAGE_DIR.fetchFrom(params).getAbsolutePath(),
 631                 // save result to output dir
 632                 "--define", "%_rpmdir " + outdir.getAbsolutePath(),
 633                 // do not use other system directories to build as current user
 634                 "--define", "%_topdir " + broot.getAbsolutePath()
 635         );
 636         pb = pb.directory(RPM_IMAGE_DIR.fetchFrom(params));
 637         IOUtils.exec(pb, false);
 638 
 639         Log.verbose(MessageFormat.format(
 640                 I18N.getString("message.output-bundle-location"),
 641                 outdir.getAbsolutePath()));


 672     public String getID() {
 673         return "rpm";
 674     }
 675 
 676     @Override
 677     public String getBundleType() {
 678         return "INSTALLER";
 679     }
 680 
 681     @Override
 682     public Collection<BundlerParamInfo<?>> getBundleParameters() {
 683         Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
 684         results.addAll(LinuxAppBundler.getAppBundleParameters());
 685         results.addAll(getRpmBundleParameters());
 686         return results;
 687     }
 688 
 689     public static Collection<BundlerParamInfo<?>> getRpmBundleParameters() {
 690         return Arrays.asList(
 691                 BUNDLE_NAME,
 692                 MENU_GROUP,
 693                 DESCRIPTION,
 694                 LinuxAppBundler.ICON_PNG,
 695                 LICENSE_FILE,
 696                 LICENSE_TYPE,
 697                 TITLE,
 698                 VENDOR
 699         );
 700     }
 701 
 702     @Override
 703     public File execute(Map<String, ? super Object> params,
 704             File outputParentDir) throws PackagerException {
 705         return bundle(params, outputParentDir);
 706     }
 707 
 708     @Override
 709     public boolean supported(boolean runtimeInstaller) {
 710         return (Platform.getPlatform() == Platform.LINUX);
 711     }
 712 
< prev index next >