From 1c0876d0d5afafdd6472fbb873a5472fb62adf0a Mon Sep 17 00:00:00 2001 From: Jiri Vanek Date: Wed, 13 Nov 2013 09:48:41 +0100 Subject: Enabled access to manifests' attributes from JNLPFile class, implemented http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#app_name --- ChangeLog | 20 +++ NEWS | 1 + netx/net/sourceforge/jnlp/JNLPFile.java | 121 +++++++++++++++ netx/net/sourceforge/jnlp/PluginBridge.java | 13 +- netx/net/sourceforge/jnlp/ResourcesDesc.java | 29 ++-- .../sourceforge/jnlp/runtime/JNLPClassLoader.java | 27 ++-- .../sourceforge/jnlp/security/CertWarningPane.java | 21 +-- .../net/sourceforge/jnlp/runtime/JNLPFileTest.java | 162 +++++++++++++++++++++ .../jnlp/runtime/ResourcesDescTest.java | 105 +++++++++++++ .../jnlp/mock/DummyJNLPFileWithJar.java | 8 +- 10 files changed, 476 insertions(+), 31 deletions(-) create mode 100644 tests/netx/unit/net/sourceforge/jnlp/runtime/JNLPFileTest.java create mode 100644 tests/netx/unit/net/sourceforge/jnlp/runtime/ResourcesDescTest.java diff --git a/ChangeLog b/ChangeLog index 970293b..2ccde62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2013-11-13 Jiri Vanek + + Enabled access to manifests' attributes from JNLPFile class + Implemented http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#app_name + * netx/net/sourceforge/jnlp/JNLPFile.java: Added (manifestsAttributes) field. + Added (ManifestsAttributes) inner class, to encapsulate access to attributes. + (getTitle) can handle manifests too. + * netx/net/sourceforge/jnlp/PluginBridge.java: is following app_name recommendations. + * netx/net/sourceforge/jnlp/ResourcesDesc.java: (getMainJAR) made more granular + * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: (init) inject itself + to file's ManifestsAttributes. (checkForAttributeInJars) renamed field + mainClassInThisJar to attributeInThisJar. Added getter for mainClass. + * netx/net/sourceforge/jnlp/security/CertWarningPane.java: bracketing cleanup. + * tests/netx/unit/net/sourceforge/jnlp/runtime/JNLPFileTest.java: new test to + check new functionalites + * tests/netx/unit/net/sourceforge/jnlp/runtime/ResourcesDescTest.java: same + * tests/test-extensions/net/sourceforge/jnlp/mock/DummyJNLPFileWithJar.java: + can set info + * NEWS: mentioned first u45 attribute + 2013-11-10 Jiri Vanek Fixed lock in awt threads. JavaConsole window is now disposed instead of hidden. diff --git a/NEWS b/NEWS index 271f4bc..e0df8d8 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ New in release 1.5 (2013-XX-XX): * JDK older then 1.5 no longer supported * IcedTea-Web is now following XDG .config and .cache specification(RH947647) * A console for debugging plugin and javaws +* Support for u45 new manifest attributes (Application-Name) * Cache Viewer - Can be closed by ESC key - Enabling and disabling of operational buttons is handled properly diff --git a/netx/net/sourceforge/jnlp/JNLPFile.java b/netx/net/sourceforge/jnlp/JNLPFile.java index 9f38d4b..65c4538 100644 --- a/netx/net/sourceforge/jnlp/JNLPFile.java +++ b/netx/net/sourceforge/jnlp/JNLPFile.java @@ -27,9 +27,11 @@ import java.util.Calendar; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.jar.Attributes; import net.sourceforge.jnlp.cache.ResourceTracker; import net.sourceforge.jnlp.cache.UpdatePolicy; +import net.sourceforge.jnlp.runtime.JNLPClassLoader; import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.util.logging.OutputController; @@ -51,6 +53,13 @@ import net.sourceforge.jnlp.util.logging.OutputController; * @version $Revision: 1.21 $ */ public class JNLPFile { + + + public static final String APP_NAME = "Application-Name"; + public static final String CALLER_ALLOWABLE = "Caller-Allowable-Codebase"; + public static final String APP_LIBRARY_ALLOWABLE = "Application-Library-Allowable-Codebase"; + + // todo: save the update policy, then if file was not updated // then do not check resources for being updated. @@ -121,6 +130,10 @@ public class JNLPFile { * List of acceptable properties (not-special) */ private String[] generalProperties = SecurityDesc.getJnlpRIAPermissions(); + + /** important manifests' attributes */ + private final ManifestsAttributes manifestsAttributes = new ManifestsAttributes(); + { // initialize defaults if security allows try { @@ -293,10 +306,46 @@ public class JNLPFile { /** * Returns the JNLP file's best localized title. This method returns the same * value as InformationDesc.getTitle(). + * + * Since jdk7 u45, also manifest title, and mainclass are taken to consideration; + * See PluginBridge */ public String getTitle() { + String jnlpTitle = getTitleFromJnlp(); + String manifestTitle = getTitleFromManifest(); + if (jnlpTitle != null && manifestTitle != null) { + if (jnlpTitle.equals(manifestTitle)) { + return jnlpTitle; + } + return jnlpTitle+" ("+manifestTitle+")"; + } + if (jnlpTitle != null && manifestTitle == null) { + return jnlpTitle; + } + if (jnlpTitle == null && manifestTitle != null) { + return manifestTitle; + } + String mainClass = getManifestsAttributes().getMainClass(); + return mainClass; + } + + /** + * Returns the JNLP file's best localized title. This method returns the same + * value as InformationDesc.getTitle(). + */ + public String getTitleFromJnlp() { return getInformation().getTitle(); } + + public String getTitleFromManifest() { + String inManifestTitle = getManifestsAttributes().getApplicationName(); + if (inManifestTitle == null && getManifestsAttributes().isLoader()){ + OutputController.getLogger().log(OutputController.Level.WARNING_ALL,"Application title was not found in manifest. Check with application vendor"); + } + return inManifestTitle; + } + + /** * Returns the JNLP file's best localized vendor. This method returns the same @@ -818,4 +867,76 @@ public class JNLPFile { public void setSignedJNLPAsMissing() { missingSignedJNLP = true; } + + public ManifestsAttributes getManifestsAttributes() { + return manifestsAttributes; + } + + + public class ManifestsAttributes{ + private JNLPClassLoader loader; + + + public void setLoader(JNLPClassLoader loader) { + this.loader = loader; + } + + public boolean isLoader() { + return loader != null; + } + + + + /** + * main class can be defined outside of manifest. + * This method is mostly for completeness + */ + public String getMainClass(){ + if (loader == null) { + OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Jars not ready to provide main class"); + return null; + } + return loader.getMainClass(); + } + + /** + * http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#app_name + */ + public String getApplicationName(){ + return getAttribute(APP_NAME); + } + + /** + * http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#caller_allowable + */ + public String getCallerAllowableCodebase(){ + return getAttribute(CALLER_ALLOWABLE); + } + + /** + * http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#app_library + */ + public String getApplicationLibraryAllowableCodebase(){ + return getAttribute(APP_LIBRARY_ALLOWABLE); + } + + /** + * get custom attribute. + */ + public String getAttribute(String name){ + return getAttribute(new Attributes.Name(name)); + } + + /** + * get standard attribute + */ + public String getAttribute(Attributes.Name name){ + if (loader == null) { + OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "Jars not ready to provide attribute "+ name); + return null; + } + return loader.checkForAttributeInJars(Arrays.asList(getResources().getJARs()), name); + } + } + } diff --git a/netx/net/sourceforge/jnlp/PluginBridge.java b/netx/net/sourceforge/jnlp/PluginBridge.java index 3b1cf37..7228521 100644 --- a/netx/net/sourceforge/jnlp/PluginBridge.java +++ b/netx/net/sourceforge/jnlp/PluginBridge.java @@ -184,7 +184,7 @@ public class PluginBridge extends JNLPFile { // the class name should be of the form foo.bar.Baz not foo/bar/Baz String mainClass = main.replace('/', '.'); - launchType = new AppletDesc(params.getAppletTitle(), mainClass, documentBase, width, + launchType = new AppletDesc(getTitle(), mainClass, documentBase, width, height, params.getUnmodifiableMap()); if (main.endsWith(".class")) //single class file only @@ -231,7 +231,18 @@ public class PluginBridge extends JNLPFile { return new DownloadOptions(usePack, useVersion); } + @Override public String getTitle() { + String inManifestTitle = super.getTitleFromManifest(); + if (inManifestTitle != null) { + return inManifestTitle; + } + //specification is recommending main class instead of html parameter + //http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/manifest.html#app_name + String mainClass = getManifestsAttributes().getMainClass(); + if (mainClass != null) { + return mainClass; + } return params.getAppletTitle(); } diff --git a/netx/net/sourceforge/jnlp/ResourcesDesc.java b/netx/net/sourceforge/jnlp/ResourcesDesc.java index 42eec01..988c55b 100644 --- a/netx/net/sourceforge/jnlp/ResourcesDesc.java +++ b/netx/net/sourceforge/jnlp/ResourcesDesc.java @@ -67,23 +67,30 @@ public class ResourcesDesc { return resources.toArray(new JREDesc[resources.size()]); } - /** - * Returns the main JAR for these resources. There first JAR - * is returned if no JARs are specified as the main JAR, and if - * there are no JARs defined then null is returned. - */ - public JARDesc getMainJAR() { - JARDesc jars[] = getJARs(); + public static JARDesc getMainJAR(JARDesc jars[] ) { + return getMainJAR(Arrays.asList(jars)); + } + public static JARDesc getMainJAR(List jars) { for (JARDesc jar : jars) { - if (jar.isMain()) + if (jar.isMain()) { return jar; + } } - if (jars.length > 0) - return jars[0]; - else + if (jars.size() > 0) { + return jars.get(0); + } else { return null; + } + } + /** + * Returns the main JAR for these resources. There first JAR + * is returned if no JARs are specified as the main JAR, and if + * there are no JARs defined then null is returned. + */ + public JARDesc getMainJAR() { + return getMainJAR(getJARs()); } /** diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java index a9a84ba..e694b9e 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java @@ -115,7 +115,7 @@ public class JNLPClassLoader extends URLClassLoader { /** Signed JNLP File and Template */ final public static String TEMPLATE = "JNLP-INF/APPLICATION_TEMPLATE.JNLP"; final public static String APPLICATION = "JNLP-INF/APPLICATION.JNLP"; - + /** Actions to specify how cache is to be managed **/ public static enum DownloadAction { DOWNLOAD_TO_CACHE, REMOVE_FROM_CACHE, CHECK_CACHE @@ -200,7 +200,7 @@ public class JNLPClassLoader extends URLClassLoader { /** Name of the application's main class */ private String mainClass = null; - + /** * Variable to track how many times this loader is in use */ @@ -245,6 +245,9 @@ public class JNLPClassLoader extends URLClassLoader { this.mainClass = mainName; + //as it is harmless, we can set is as soon as possible. + file.getManifestsAttributes().setLoader(this); + AppVerifier verifier; if (file instanceof PluginBridge && !((PluginBridge)file).useJNLPHref()) { @@ -259,13 +262,15 @@ public class JNLPClassLoader extends URLClassLoader { initializeExtensions(); initializeResources(); + // initialize permissions initializePermissions(); setSecurity(); - + installShutdownHooks(); + } @@ -786,7 +791,7 @@ public class JNLPClassLoader extends URLClassLoader { String result = null; // Check main jar - JARDesc mainJarDesc = file.getResources().getMainJAR(); + JARDesc mainJarDesc = ResourcesDesc.getMainJAR(jars); result = getManifestAttribute(mainJarDesc.getLocation(), name); if (result != null) { @@ -803,10 +808,10 @@ public class JNLPClassLoader extends URLClassLoader { // Still not found? Iterate and set if only 1 was found for (JARDesc jarDesc: jars) { - String mainClassInThisJar = getManifestAttribute(jarDesc.getLocation(), name); - if (mainClassInThisJar != null) { + String attributeInThisJar = getManifestAttribute(jarDesc.getLocation(), name); + if (attributeInThisJar != null) { if (result == null) { // first main class - result = mainClassInThisJar; + result = attributeInThisJar; } else { // There is more than one main class. Set to null and break. result = null; break; @@ -2193,6 +2198,10 @@ public class JNLPClassLoader extends URLClassLoader { return new AccessControlContext(new ProtectionDomain[] { pd }); } + + public String getMainClass() { + return mainClass; + } /* * Helper class to expose protected URLClassLoader methods. @@ -2317,6 +2326,6 @@ public class JNLPClassLoader extends URLClassLoader { return null; } } - - + + } diff --git a/netx/net/sourceforge/jnlp/security/CertWarningPane.java b/netx/net/sourceforge/jnlp/security/CertWarningPane.java index f9273fa..dae8030 100644 --- a/netx/net/sourceforge/jnlp/security/CertWarningPane.java +++ b/netx/net/sourceforge/jnlp/security/CertWarningPane.java @@ -107,13 +107,14 @@ public class CertWarningPane extends SecurityDialogPanel { //these strings -- we just want to fill in as many as possible. try { if ((certVerifier instanceof HttpsCertVerifier) && - (c instanceof X509Certificate)) + (c instanceof X509Certificate)) { name = SecurityUtil.getCN(((X509Certificate) c) .getSubjectX500Principal().getName()); - else if (file instanceof PluginBridge) + } else if (file instanceof PluginBridge) { name = file.getTitle(); - else + } else { name = file.getInformation().getTitle(); + } } catch (Exception e) { } @@ -126,10 +127,11 @@ public class CertWarningPane extends SecurityDialogPanel { } try { - if (file instanceof PluginBridge) + if (file instanceof PluginBridge) { from = file.getCodeBase().getHost(); - else + } else { from = file.getInformation().getHomepage().toString(); + } } catch (Exception e) { } @@ -146,7 +148,7 @@ public class CertWarningPane extends SecurityDialogPanel { topLabelText = R("SHttpsUnverified") + " " + R("Continue"); propertyName = "OptionPane.warningIcon"; iconLocation += "warning.png"; - } else + } else { switch (type) { case VERIFIED: topLabelText = R("SSigVerified"); @@ -167,7 +169,7 @@ public class CertWarningPane extends SecurityDialogPanel { bottomLabelText += " " + R("SWarnFullPermissionsIgnorePolicy"); break; } - + } ImageIcon icon = new ImageIcon((new sun.misc.Launcher()) .getClassLoader().getResource(iconLocation)); JLabel topLabel = new JLabel(htmlWrap(topLabelText), icon, SwingConstants.LEFT); @@ -195,8 +197,9 @@ public class CertWarningPane extends SecurityDialogPanel { infoPanel.add(nameLabel); infoPanel.add(publisherLabel); - if (!(certVerifier instanceof HttpsCertVerifier)) + if (!(certVerifier instanceof HttpsCertVerifier)) { infoPanel.add(fromLabel); + } infoPanel.add(alwaysTrust); infoPanel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25)); @@ -225,7 +228,7 @@ public class CertWarningPane extends SecurityDialogPanel { add(infoPanel); add(buttonPanel); - JLabel bottomLabel = new JLabel(htmlWrap(bottomLabelText));; + JLabel bottomLabel = new JLabel(htmlWrap(bottomLabelText)); JButton moreInfo = new JButton(R("ButMoreInformation")); moreInfo.addActionListener(new MoreInfoButtonListener()); diff --git a/tests/netx/unit/net/sourceforge/jnlp/runtime/JNLPFileTest.java b/tests/netx/unit/net/sourceforge/jnlp/runtime/JNLPFileTest.java new file mode 100644 index 0000000..7d57ad9 --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/runtime/JNLPFileTest.java @@ -0,0 +1,162 @@ +/* + Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea 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 for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.runtime; + +import java.io.File; +import java.util.Arrays; +import java.util.Locale; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import net.sourceforge.jnlp.InformationDesc; +import net.sourceforge.jnlp.JNLPFile; +import net.sourceforge.jnlp.cache.UpdatePolicy; +import net.sourceforge.jnlp.mock.DummyJNLPFileWithJar; +import net.sourceforge.jnlp.util.FileTestUtils; +import org.junit.Assert; +import org.junit.Test; + +public class JNLPFileTest { + + @Test + public void removeTitle() throws Exception { + File tempDirectory = FileTestUtils.createTempDirectory(); + tempDirectory.deleteOnExit(); + File jarLocation1 = new File(tempDirectory, "test1.jar"); + File jarLocation2 = new File(tempDirectory, "test2.jar"); + File jarLocation3 = new File(tempDirectory, "test3.jar"); + File jarLocation4 = new File(tempDirectory, "test4.jar"); + File jarLocation5 = new File(tempDirectory, "test5.jar"); + + /* Test with various attributes in manifest!s! */ + Manifest manifest1 = new Manifest(); + manifest1.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "DummyClass1"); //two times, but one in main jar, see DummyJNLPFileWithJar constructor with int + + Manifest manifest2 = new Manifest(); + manifest2.getMainAttributes().put(Attributes.Name.IMPLEMENTATION_VENDOR, "rh1"); //two times, both in not main jar, see DummyJNLPFileWithJar constructor with int + + Manifest manifest3 = new Manifest(); + manifest3.getMainAttributes().put(Attributes.Name.IMPLEMENTATION_TITLE, "it"); //jsut once in not main jar, see DummyJNLPFileWithJar constructor with int + manifest3.getMainAttributes().put(Attributes.Name.IMPLEMENTATION_VENDOR, "rh2"); + + Manifest manifest4 = new Manifest(); + manifest4.getMainAttributes().put(Attributes.Name.MAIN_CLASS, "DummyClass2"); //see jnlpFile.setMainJar(3); + manifest4.getMainAttributes().put(Attributes.Name.IMPLEMENTATION_URL, "some url2"); //see DummyJNLPFileWithJar constructor with int + + //first jar + Manifest manifest5 = new Manifest(); + manifest5.getMainAttributes().put(Attributes.Name.IMPLEMENTATION_URL, "some url1"); //see DummyJNLPFileWithJar constructor with int + manifest5.getMainAttributes().put(new Attributes.Name(JNLPFile.APP_NAME), "Manifested Name"); + + + FileTestUtils.createJarWithContents(jarLocation1, manifest1); + FileTestUtils.createJarWithContents(jarLocation2, manifest2); + FileTestUtils.createJarWithContents(jarLocation3, manifest3); + FileTestUtils.createJarWithContents(jarLocation4, manifest4); + FileTestUtils.createJarWithContents(jarLocation5, manifest5); + + final DummyJNLPFileWithJar jnlpFile = new DummyJNLPFileWithJar(3, jarLocation5, jarLocation3, jarLocation4, jarLocation1, jarLocation2); //jar 1 should be main + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getMainClass()); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR)); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_TITLE)); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.MAIN_CLASS)); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR_ID)); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_URL)); + Assert.assertNull("no classlaoder attached, should be null", jnlpFile.getManifestsAttributes().getAttribute(new Attributes.Name(JNLPFile.APP_NAME))); + + Assert.assertNull(jnlpFile.getTitleFromJnlp()); + Assert.assertNull(jnlpFile.getTitleFromManifest()); + Assert.assertNull(jnlpFile.getTitle()); + + setTitle(jnlpFile); + + Assert.assertEquals("jnlp title", jnlpFile.getTitleFromJnlp()); + Assert.assertNull(jnlpFile.getTitleFromManifest()); + Assert.assertEquals("jnlp title", jnlpFile.getTitle()); + + removeTitle(jnlpFile); + + Assert.assertNull(jnlpFile.getTitleFromJnlp()); + Assert.assertNull(jnlpFile.getTitleFromManifest()); + Assert.assertNull(jnlpFile.getTitle()); + + final JNLPClassLoader classLoader = new JNLPClassLoader(jnlpFile, UpdatePolicy.ALWAYS); + + // thsi si strange, but not part of this test + // Assert.assertNotNull("classlaoder attached, should be not null", jnlpFile.getManifestsAttributes().getMainClass()); + Assert.assertNull("defined twice, shoud be null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR)); + Assert.assertNotNull("classlaoder attached, should be not null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_TITLE)); + Assert.assertNotNull("classlaoder attached, should be not null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.MAIN_CLASS)); + Assert.assertNull("not deffined, should benull", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR_ID)); + Assert.assertNotNull("classlaoder attached, should be not null", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_URL)); + Assert.assertNotNull("classlaoder attached, should be not null", jnlpFile.getManifestsAttributes().getAttribute(new Attributes.Name(JNLPFile.APP_NAME))); + //correct values are also tested in JnlpClassloaderTest + Assert.assertEquals("classlaoder attached, should be not null", "it", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_TITLE)); + Assert.assertEquals("classlaoder attached, should be not null", "DummyClass1", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.MAIN_CLASS)); + Assert.assertEquals("classlaoder attached, should be not null", "some url1", jnlpFile.getManifestsAttributes().getAttribute(Attributes.Name.IMPLEMENTATION_URL)); + Assert.assertEquals("classlaoder attached, should be not null", "Manifested Name", jnlpFile.getManifestsAttributes().getAttribute(new Attributes.Name(JNLPFile.APP_NAME))); + + Assert.assertNull(jnlpFile.getTitleFromJnlp()); + Assert.assertEquals("Manifested Name", jnlpFile.getTitleFromManifest()); + Assert.assertEquals("Manifested Name", jnlpFile.getTitle()); + + setTitle(jnlpFile); + + Assert.assertEquals("jnlp title", jnlpFile.getTitleFromJnlp()); + Assert.assertEquals("Manifested Name", jnlpFile.getTitleFromManifest()); + Assert.assertEquals("jnlp title (Manifested Name)", jnlpFile.getTitle()); + + } + + private void setTitle(final DummyJNLPFileWithJar jnlpFile) { + setTitle(jnlpFile, "jnlp title"); + } + + private void setTitle(final DummyJNLPFileWithJar jnlpFile, final String title) { + jnlpFile.setInfo(Arrays.asList(new InformationDesc[]{ + new InformationDesc(new Locale[]{}) { + @Override + public String getTitle() { + return title; + } + } + })); + } + + private void removeTitle(final DummyJNLPFileWithJar jnlpFile) { + jnlpFile.setInfo(Arrays.asList(new InformationDesc[]{})); + } +} diff --git a/tests/netx/unit/net/sourceforge/jnlp/runtime/ResourcesDescTest.java b/tests/netx/unit/net/sourceforge/jnlp/runtime/ResourcesDescTest.java new file mode 100644 index 0000000..f5ade1b --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/runtime/ResourcesDescTest.java @@ -0,0 +1,105 @@ +/* + Copyright (C) 2013 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea 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 for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.runtime; + +import java.io.File; +import java.util.jar.Manifest; +import net.sourceforge.jnlp.JARDesc; +import net.sourceforge.jnlp.mock.DummyJNLPFileWithJar; +import net.sourceforge.jnlp.util.FileTestUtils; +import org.junit.Assert; +import org.junit.Test; + +public class ResourcesDescTest { + + @Test + public void checkGetMainJar_noMainSet() throws Exception { + File tempDirectory = FileTestUtils.createTempDirectory(); + tempDirectory.deleteOnExit(); + + File jarLocation1 = new File(tempDirectory, "test1.jar"); + File jarLocation2 = new File(tempDirectory, "test2.jar"); + File jarLocation3 = new File(tempDirectory, "test3.jar"); + + Manifest manifest1 = new Manifest(); + Manifest manifest2 = new Manifest(); + Manifest manifest3 = new Manifest(); + Manifest manifest4 = new Manifest(); + Manifest manifest5 = new Manifest(); + + FileTestUtils.createJarWithContents(jarLocation1, manifest1); + FileTestUtils.createJarWithContents(jarLocation2, manifest2); + FileTestUtils.createJarWithContents(jarLocation3, manifest3); + + final DummyJNLPFileWithJar jnlpFile = new DummyJNLPFileWithJar(jarLocation1, jarLocation2, jarLocation3); + JARDesc result = jnlpFile.getResources().getMainJAR(); + Assert.assertTrue("first jar must be returned", result.getLocation().getFile().endsWith("test1.jar")); + } + + @Test + public void checkGetMainJar_mainSet() throws Exception { + File tempDirectory = FileTestUtils.createTempDirectory(); + tempDirectory.deleteOnExit(); + + File jarLocation1 = new File(tempDirectory, "test1.jar"); + File jarLocation2 = new File(tempDirectory, "test2.jar"); + File jarLocation3 = new File(tempDirectory, "test3.jar"); + + Manifest manifest1 = new Manifest(); + Manifest manifest2 = new Manifest(); + Manifest manifest3 = new Manifest(); + Manifest manifest4 = new Manifest(); + Manifest manifest5 = new Manifest(); + + FileTestUtils.createJarWithContents(jarLocation1, manifest1); + FileTestUtils.createJarWithContents(jarLocation2, manifest2); + FileTestUtils.createJarWithContents(jarLocation3, manifest3); + + DummyJNLPFileWithJar jnlpFile = new DummyJNLPFileWithJar(0, jarLocation1, jarLocation2, jarLocation3); + JARDesc result = jnlpFile.getResources().getMainJAR(); + Assert.assertTrue("main jar must be returned", result.getLocation().getFile().endsWith("test1.jar")); + + jnlpFile = new DummyJNLPFileWithJar(1, jarLocation1, jarLocation2, jarLocation3); + result = jnlpFile.getResources().getMainJAR(); + Assert.assertTrue("main jar must be returned", result.getLocation().getFile().endsWith("test2.jar")); + + jnlpFile = new DummyJNLPFileWithJar(2, jarLocation1, jarLocation2, jarLocation3); + result = jnlpFile.getResources().getMainJAR(); + Assert.assertTrue("main jar must be returned", result.getLocation().getFile().endsWith("test3.jar")); + } + +} diff --git a/tests/test-extensions/net/sourceforge/jnlp/mock/DummyJNLPFileWithJar.java b/tests/test-extensions/net/sourceforge/jnlp/mock/DummyJNLPFileWithJar.java index 0ef4e10..018f044 100644 --- a/tests/test-extensions/net/sourceforge/jnlp/mock/DummyJNLPFileWithJar.java +++ b/tests/test-extensions/net/sourceforge/jnlp/mock/DummyJNLPFileWithJar.java @@ -4,6 +4,7 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import net.sourceforge.jnlp.InformationDesc; @@ -21,7 +22,6 @@ public class DummyJNLPFileWithJar extends JNLPFile { return new JARDesc(jarLocation, new Version("1"), null, false,main, false,false); } - private final URL codeBase; private final JARDesc[] jarDescs; private final File[] jarFiles; @@ -91,4 +91,10 @@ public class DummyJNLPFileWithJar extends JNLPFile { public SecurityDesc getSecurity() { return new SecurityDesc(this, SecurityDesc.SANDBOX_PERMISSIONS, null); } + + public void setInfo(List info) { + this.info = info; + } + + } \ No newline at end of file -- cgit v1.2.3