1 /*
   2  * Copyright (c) 2018, 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 
  24 package jnlp.converter.parser;
  25 
  26 import java.net.URL;
  27 import java.util.ArrayList;
  28 import java.util.Enumeration;
  29 import java.util.List;
  30 import java.util.Properties;
  31 import jnlp.converter.Log;
  32 
  33 import jnlp.converter.parser.ResourcesDesc.JARDesc;
  34 import jnlp.converter.parser.ResourcesDesc.JREDesc;
  35 
  36 public class JNLPDesc {
  37     private String specVersion = null;
  38     private String codebase = null;
  39     private String version = null;
  40     private String href = null;
  41     private String name = null;
  42     private String title = null;
  43     private String vendor = null;
  44     private String mainJar = null;
  45     private String [] descriptions = null;
  46     private IconDesc [] icons = null;
  47     private ShortcutDesc shortcuts = null;
  48     private AssociationDesc [] associations = null;
  49     private String mainClass = null;
  50     private final List<String> arguments  = new ArrayList<>();
  51     private final List<String> files = new ArrayList<>();
  52     private final List<JARDesc> resources = new ArrayList<>();
  53     private final List<String> vmArgs = new ArrayList<>();
  54     private boolean isLibrary = false;
  55     private boolean isInstaller = false;
  56     private boolean isJRESet = false;
  57     private ResourcesDesc resourcesDesc;
  58     private boolean isVersionEnabled = false;
  59     private boolean isSandbox = true;
  60     private boolean isFXApp = false;
  61 
  62     public void setSpecVersion(String specVersion) {
  63         this.specVersion = specVersion;
  64 
  65         // Valid values are 1.0, 1.5, 6.0, 6.0.10, 6.0.18, 7.0, 8.20, 9 or a wildcard such as 1.0+.
  66         if (!specVersion.startsWith("1.0") &&
  67             !specVersion.startsWith("1.5") &&
  68             !specVersion.startsWith("6.0") &&
  69             !specVersion.startsWith("6.0.10") &&
  70             !specVersion.startsWith("6.0.18") &&
  71             !specVersion.startsWith("7.0") &&
  72             !specVersion.startsWith("8.20") &&
  73             !specVersion.startsWith("9")) {
  74                 System.out.println("Warning: Invalid version of the JNLP specification found: "
  75                         + specVersion + ". Valid values are 1.0, 1.5, 6.0, 6.0.10, 6.0.18, 7.0,"
  76                         + " 8.20, 9 or a wildcard such as 1.0+.");
  77         }
  78     }
  79 
  80     public String getSpecVersion() {
  81         return specVersion;
  82     }
  83 
  84     public void setCodebase(String codebase) {
  85         this.codebase = codebase;
  86     }
  87 
  88     public String getCodebase() {
  89         return codebase;
  90     }
  91 
  92     public void setVersion(String version) {
  93         this.version = version;
  94     }
  95 
  96     public String getVersion() {
  97         return version;
  98     }
  99 
 100     public void setHref(String href) {
 101         this.href = href;
 102     }
 103 
 104     public String getHref() {
 105         return href;
 106     }
 107 
 108     public void setName(String name) {
 109         this.name = name;
 110     }
 111 
 112     public String getName() {
 113         return name;
 114     }
 115 
 116     public void setTitle(String title) {
 117         this.title = title;
 118     }
 119 
 120     public String getTitle() {
 121         return title;
 122     }
 123 
 124     public void setVendor(String vendor) {
 125         this.vendor = vendor;
 126     }
 127 
 128     public String getVendor() {
 129         return vendor;
 130     }
 131 
 132     public void setMainJar(String mainJar) {
 133         if (this.mainJar == null) {
 134             this.mainJar = mainJar;
 135         } else {
 136             Log.warning("Main jar already set to '" + this.mainJar + "'. "
 137                     + "Attempt to set main jar to '" + mainJar + "' will be ignored.");
 138         }
 139     }
 140 
 141     public String getMainJar() {
 142         return mainJar;
 143     }
 144 
 145     public void setDescriptions(String [] descriptions) {
 146         this.descriptions = descriptions;
 147     }
 148 
 149     public String getDescription() {
 150         String description = null;
 151         if (descriptions != null) {
 152             if (descriptions[InformationDesc.DESC_DEFAULT] != null) {
 153                 description = descriptions[InformationDesc.DESC_DEFAULT];
 154             } else if (descriptions[InformationDesc.DESC_SHORT] != null) {
 155                 description = descriptions[InformationDesc.DESC_SHORT];
 156             } else if (descriptions[InformationDesc.DESC_ONELINE] != null) {
 157                 description = descriptions[InformationDesc.DESC_ONELINE];
 158             } else if (descriptions[InformationDesc.DESC_TOOLTIP] != null) {
 159                 description = descriptions[InformationDesc.DESC_TOOLTIP];
 160             }
 161 
 162             if (description != null) {
 163                 if (description.contains("\r") || description.contains("\n")) {
 164                     Log.warning("Multiple lines of text in description is not supported and description will be converted to single line by replacing new lines with spaces.");
 165                     Log.warning("Original description:");
 166                     Log.warning(description);
 167                     String descs[] = description.split("\n");
 168                     description = "";
 169                     for (String desc : descs) {
 170                         desc = desc.trim();
 171                         if (desc.endsWith("\r")) { // In case new line was \r\n
 172                             if (desc.length() != 1) {
 173                                 desc = desc.substring(0, desc.length() - 1);
 174                             } else {
 175                                 continue;
 176                             }
 177                         }
 178 
 179                         if (desc.isEmpty()) {
 180                             continue;
 181                         }
 182 
 183                         if (!description.isEmpty()) {
 184                             description += " ";
 185                         }
 186 
 187                         description += desc;
 188                     }
 189                     Log.warning("Converted description:");
 190                     Log.warning(description);
 191                 }
 192             }
 193         }
 194 
 195         return description;
 196     }
 197 
 198     public void setIcons(IconDesc [] icons) {
 199         this.icons = icons;
 200     }
 201 
 202     public IconDesc getIcon() {
 203         for (IconDesc icon : icons) {
 204             if (icon.getKind() == IconDesc.ICON_KIND_DEFAULT) {
 205                 return icon;
 206             }
 207         }
 208 
 209         for (IconDesc icon : icons) {
 210             if (icon.getKind() == IconDesc.ICON_KIND_SHORTCUT) {
 211                 return icon;
 212             }
 213         }
 214 
 215         return null;
 216     }
 217 
 218     public String getIconLocation() {
 219         IconDesc icon = getIcon();
 220         if (icon != null) {
 221             return icon.getLocalLocation();
 222         }
 223 
 224         return null;
 225     }
 226 
 227     public void setShortcuts(ShortcutDesc shortcuts) {
 228         this.shortcuts = shortcuts;
 229     }
 230 
 231     public boolean isDesktopHint() {
 232         if (shortcuts != null) {
 233             return shortcuts.getDesktop();
 234         }
 235 
 236         return false;
 237     }
 238 
 239     public boolean isMenuHint() {
 240         if (shortcuts != null) {
 241             return shortcuts.getMenu();
 242         }
 243 
 244         return false;
 245     }
 246 
 247     public String getSubMenu() {
 248         if (shortcuts != null) {
 249             return shortcuts.getSubmenu();
 250         }
 251 
 252         return null;
 253     }
 254 
 255     public void setAssociations(AssociationDesc [] associations) {
 256         this.associations = associations;
 257     }
 258 
 259     public AssociationDesc [] getAssociations() {
 260          return associations;
 261     }
 262 
 263     public void setMainClass(String mainClass, boolean isJavafxDesc) {
 264         if (isJavafxDesc) {
 265             this.mainClass = mainClass;
 266         } else if (this.mainClass == null) {
 267             this.mainClass = mainClass;
 268         }
 269     }
 270 
 271     public String getMainClass() {
 272         return mainClass;
 273     }
 274 
 275     public void addArguments(String argument) {
 276         if (argument != null && !argument.isEmpty()) {
 277             arguments.add(argument);
 278         }
 279     }
 280 
 281     public List<String> getArguments() {
 282         return arguments;
 283     }
 284 
 285     public void setProperty(String name, String value) {
 286         if (name.equalsIgnoreCase("jnlp.versionEnabled") && value.equalsIgnoreCase("true")) {
 287             isVersionEnabled = true;
 288             return;
 289         }
 290 
 291         addVMArg("-D" + name + "=" + value);
 292     }
 293 
 294     public boolean isVersionEnabled() {
 295         return isVersionEnabled;
 296     }
 297 
 298     public boolean isSandbox() {
 299         return isSandbox;
 300     }
 301 
 302     public void setIsSandbox(boolean value) {
 303         isSandbox = value;
 304     }
 305 
 306     public boolean isFXApp() {
 307         return isFXApp;
 308     }
 309 
 310     public void setIsFXApp(boolean value) {
 311         isFXApp = value;
 312     }
 313 
 314     public void addFile(String file) {
 315         if (file != null) {
 316             files.add(file);
 317         }
 318     }
 319 
 320     public List<String> getFiles() {
 321         return files;
 322     }
 323 
 324     private boolean isResourceExists(JARDesc resource) {
 325         for (JARDesc r : resources) {
 326             if (r.getLocation().equals(resource.getLocation())) {
 327                 return true;
 328             }
 329         }
 330 
 331         return false;
 332     }
 333 
 334     public void addResource(JARDesc resource) {
 335         if (resource != null) {
 336             if (isResourceExists(resource)) {
 337                 Log.warning("Ignoring repeated resource " + resource.getLocation());
 338                 return;
 339             }
 340             resources.add(resource);
 341         }
 342     }
 343 
 344     public List<JARDesc> getResources() {
 345         return resources;
 346     }
 347 
 348     public void addVMArg(String arg) {
 349         if (arg != null) {
 350             vmArgs.add(arg);
 351         }
 352     }
 353 
 354     public List<String> getVMArgs() {
 355         return vmArgs;
 356     }
 357 
 358     public void setIsLibrary(boolean isLibrary) {
 359         this.isLibrary = isLibrary;
 360     }
 361 
 362     public boolean isLibrary() {
 363         return isLibrary;
 364     }
 365 
 366     public void setIsInstaller(boolean isInstaller) {
 367         this.isInstaller = isInstaller;
 368     }
 369 
 370     public boolean isInstaller() {
 371         return isInstaller;
 372     }
 373 
 374     public void setIsJRESet(boolean isJRESet) {
 375         this.isJRESet = isJRESet;
 376     }
 377 
 378     public boolean isJRESet() {
 379         return isJRESet;
 380     }
 381 
 382     public void setResourcesDesc(ResourcesDesc resourcesDesc) {
 383         this.resourcesDesc = resourcesDesc;
 384     }
 385 
 386     public ResourcesDesc getResourcesDesc() {
 387         return resourcesDesc;
 388     }
 389 
 390     public void parseResourceDesc() throws Exception {
 391         if (resourcesDesc != null && !resourcesDesc.isEmpty()) {
 392             setMainJar(resourcesDesc.getMainJar().getName());
 393 
 394             JARDesc[] jars = resourcesDesc.getAllJarDescs();
 395             for (JARDesc jar : jars) {
 396                 addResource(jar);
 397             }
 398 
 399             JREDesc jreDesc = resourcesDesc.getJreDesc();
 400             if (jreDesc != null) {
 401                 String [] args = jreDesc.getVmArgsList();
 402                 if (args != null) {
 403                     for (String arg : args) {
 404                         addVMArg(arg);
 405                     }
 406                 }
 407 
 408                 if (jreDesc.getMinHeap() != -1) {
 409                     addVMArg("-Xms" + jreDesc.getMinHeap());
 410                 }
 411 
 412                 if (jreDesc.getMaxHeap() != -1) {
 413                     addVMArg("-Xmx" + jreDesc.getMaxHeap());
 414                 }
 415             }
 416 
 417             Properties props = resourcesDesc.getResourceProperties();
 418             Enumeration e = props.propertyNames();
 419             while (e.hasMoreElements()) {
 420                 String key = (String) e.nextElement();
 421                 String value = props.getProperty(key);
 422                 setProperty(key, value);
 423             }
 424         }
 425     }
 426 
 427     public static class InformationDesc {
 428 
 429         private final String _title;
 430         private final String _vendor;
 431         private final String[] _descriptions;
 432         private final IconDesc[] _icons;
 433         private ShortcutDesc _shortcutHints;
 434         private AssociationDesc[] _associations;
 435 
 436         public InformationDesc(String title, String vendor,
 437                 String[] descriptions,
 438                 IconDesc[] icons,
 439                 ShortcutDesc shortcutHints,
 440                 AssociationDesc[] associations) {
 441             _title = (title == null) ? "" : title;
 442             _vendor = (vendor == null) ? "" : vendor;
 443             if (descriptions == null) {
 444                 descriptions = new String[NOF_DESC];
 445             }
 446             _descriptions = descriptions;
 447             _icons = icons;
 448             _shortcutHints = shortcutHints;
 449             _associations = associations;
 450         }
 451 
 452         /**
 453          * Constants for the getInfoDescription
 454          */
 455         final public static int DESC_DEFAULT = 0;
 456         final public static int DESC_SHORT = 1;
 457         final public static int DESC_ONELINE = 2;
 458         final public static int DESC_TOOLTIP = 3;
 459         final public static int NOF_DESC = 4;
 460 
 461         /**
 462          * Information
 463          */
 464         public String getTitle() {
 465             return _title;
 466         }
 467 
 468         public String getVendor() {
 469             return _vendor;
 470         }
 471 
 472         public IconDesc[] getIcons() {
 473             return _icons;
 474         }
 475 
 476         public ShortcutDesc getShortcut() {
 477             if (_shortcutHints == null) {
 478                 return null;
 479             }
 480             return new ShortcutDesc(_shortcutHints.getDesktop(), _shortcutHints.getMenu(), _shortcutHints.getSubmenu());
 481         }
 482 
 483         public AssociationDesc[] getAssociations() {
 484             return _associations;
 485         }
 486 
 487         /**
 488          * Sets new shortcut hints.
 489          *
 490          * @param shortcutDesc the new shortcut hints to set
 491          */
 492         public void setShortcut(ShortcutDesc shortcut) {
 493             _shortcutHints = shortcut;
 494         }
 495 
 496         /**
 497          * Sets new associations.
 498          *
 499          * @param assoc the association to set
 500          */
 501         public void setAssociation(AssociationDesc assoc) {
 502             if (assoc == null) {
 503                 _associations = null;
 504             } else {
 505                 _associations = new AssociationDesc[]{assoc};
 506             }
 507         }
 508 
 509         /**
 510          * Returns the description of the given kind. will return null if none
 511          * there
 512          */
 513         public String getDescription(int kind) {
 514             return _descriptions[kind];
 515         }
 516 
 517         public String[] getDescription() {
 518             return _descriptions;
 519         }
 520     }
 521 
 522     public static class IconDesc {
 523 
 524         private final String _location;
 525         private String _localLocation;
 526         private final int _kind;
 527 
 528         final public static int ICON_KIND_DEFAULT = 0;
 529         final public static int ICON_KIND_SHORTCUT = 5;
 530 
 531         public IconDesc(URL location, int kind) {
 532             _location = location.toExternalForm();
 533             _kind = kind;
 534         }
 535 
 536         public String getLocation() {
 537             return _location;
 538         }
 539 
 540         public void setLocalLocation(String localLocation) {
 541             _localLocation = localLocation;
 542         }
 543 
 544         public String getLocalLocation() {
 545             return _localLocation;
 546         }
 547 
 548         public int getKind() {
 549             return _kind;
 550         }
 551     }
 552 
 553     public static class ShortcutDesc {
 554 
 555         private final boolean _desktop;
 556         private final boolean _menu;
 557         private final String _submenu;
 558 
 559         public ShortcutDesc(boolean desktop, boolean menu, String submenu) {
 560             _desktop = desktop;
 561             _menu = menu;
 562             _submenu = submenu;
 563         }
 564 
 565         public boolean getDesktop() {
 566             return _desktop;
 567         }
 568 
 569         public boolean getMenu() {
 570             return _menu;
 571         }
 572 
 573         public String getSubmenu() {
 574             return _submenu;
 575         }
 576     }
 577 
 578     public static class AssociationDesc {
 579 
 580         private final String _extensions;
 581         private final String _mimeType;
 582         private final String _description;
 583         private final String _icon;
 584         private String _iconLocalLocation;
 585 
 586         public AssociationDesc(String extensions, String mimeType, String description, URL icon) {
 587             _extensions = extensions;
 588             _mimeType = mimeType;
 589             _description = description;
 590             _icon = (icon != null) ? icon.toExternalForm() : null;
 591         }
 592 
 593         public void setIconLocalLocation(String localLocation) {
 594             _iconLocalLocation = localLocation;
 595         }
 596 
 597         public String getIconLocalLocation() {
 598             return _iconLocalLocation;
 599         }
 600 
 601         public String getExtensions() {
 602             return _extensions;
 603         }
 604 
 605         public String getMimeType() {
 606             return _mimeType;
 607         }
 608 
 609         public String getMimeDescription() {
 610             return _description;
 611         }
 612 
 613         public String getIconUrl() {
 614             return _icon;
 615         }
 616     }
 617 }