diff options
author | Danesh Dadachanji <[email protected]> | 2012-08-08 11:48:06 -0400 |
---|---|---|
committer | Danesh Dadachanji <[email protected]> | 2012-08-08 11:48:06 -0400 |
commit | 491377046ce85cbd7fc34811f778278e1864fe5c (patch) | |
tree | 7d155d87093a2ce4201b598ec73940f4387d4412 /netx | |
parent | cbf4c1118d8f44453fefb8f2223b3a6fe743fa3f (diff) |
Fix PR955: regression: SweetHome3D fails to run
Diffstat (limited to 'netx')
-rw-r--r-- | netx/net/sourceforge/jnlp/JNLPFile.java | 152 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/MissingInformationException.java | 44 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/MissingTitleException.java | 45 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/MissingVendorException.java | 44 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/Parser.java | 46 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/RequiredElementException.java | 41 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/resources/Messages.properties | 7 |
7 files changed, 328 insertions, 51 deletions
diff --git a/netx/net/sourceforge/jnlp/JNLPFile.java b/netx/net/sourceforge/jnlp/JNLPFile.java index 6c458f8..5fc626e 100644 --- a/netx/net/sourceforge/jnlp/JNLPFile.java +++ b/netx/net/sourceforge/jnlp/JNLPFile.java @@ -99,18 +99,18 @@ public class JNLPFile { /** the security descriptor */ protected SecurityDesc security; - /** the default OS */ + /** the default JVM locale */ protected Locale defaultLocale = null; - /** the default arch */ + /** the default OS */ protected String defaultOS = null; - /** the default jvm */ + /** the default arch */ protected String defaultArch = null; - + /** A signed JNLP file is missing from the main jar */ private boolean missingSignedJNLP = false; - + /** JNLP file contains special properties */ private boolean containsSpecialProperties = false; @@ -118,7 +118,7 @@ public class JNLPFile { * List of acceptable properties (not-special) */ private String[] generalProperties = SecurityDesc.getJnlpRIAPermissions(); - + { // initialize defaults if security allows try { defaultLocale = Locale.getDefault(); @@ -129,6 +129,8 @@ public class JNLPFile { } } + static enum Match { LANG_COUNTRY_VARIANT, LANG_COUNTRY, LANG, GENERALIZED } + /** * Empty stub, allowing child classes to override the constructor */ @@ -185,9 +187,9 @@ public class JNLPFile { * @throws ParseException if the JNLP file was invalid */ public JNLPFile(URL location, Version version, boolean strict, UpdatePolicy policy) throws IOException, ParseException { - this(location, version, strict, policy, null); + this(location, version, strict, policy, null); } - + /** * Create a JNLPFile from a URL and a version, checking for updates * using the specified policy. @@ -284,7 +286,7 @@ public class JNLPFile { } /** - * Returns the JNLP file's title. This method returns the same + * Returns the JNLP file's best localized title. This method returns the same * value as InformationDesc.getTitle(). */ public String getTitle() { @@ -292,6 +294,14 @@ public class JNLPFile { } /** + * Returns the JNLP file's best localized vendor. This method returns the same + * value as InformationDesc.getVendor(). + */ + public String getVendor() { + return getInformation().getVendor(); + } + + /** * Returns the JNLP file's network location as specified in the * JNLP file. */ @@ -349,18 +359,53 @@ public class JNLPFile { */ public InformationDesc getInformation(final Locale locale) { return new InformationDesc(this, new Locale[] { locale }) { + @Override protected List<Object> getItems(Object key) { List<Object> result = new ArrayList<Object>(); - for (int i = 0; i < info.size(); i++) { - InformationDesc infoDesc = info.get(i); + for (Match precision : Match.values()) { + for (InformationDesc infoDesc : JNLPFile.this.info) { + if (localeMatches(locale, infoDesc.getLocales(), precision)) { + result.addAll(infoDesc.getItems(key)); + } + } - if (localMatches(locale, infoDesc.getLocales())) - result.addAll(infoDesc.getItems(key)); + if (result.size() > 0) { + return result; + } } - return result; } + + @Override + public String getTitle() { + for (Match precision : Match.values()) { + for (InformationDesc infoDesc : JNLPFile.this.info) { + String title = infoDesc.getTitle(); + if (localeMatches(locale, infoDesc.getLocales(), precision) + && title != null && !"".equals(title)) { + return title; + } + } + } + + return null; + } + + @Override + public String getVendor() { + for (Match precision : Match.values()) { + for (InformationDesc infoDesc : JNLPFile.this.info) { + String vendor = infoDesc.getVendor(); + if (localeMatches(locale, infoDesc.getLocales(), precision) + && vendor != null && !"".equals(vendor)) { + return vendor; + } + } + } + + return null; + } }; } @@ -393,11 +438,17 @@ public class JNLPFile { */ public ResourcesDesc getResources(final Locale locale, final String os, final String arch) { return new ResourcesDesc(this, new Locale[] { locale }, new String[] { os }, new String[] { arch }) { + + @Override public <T> List<T> getResources(Class<T> launchType) { List<T> result = new ArrayList<T>(); for (ResourcesDesc rescDesc : resources) { - if (localMatches(locale, rescDesc.getLocales()) + boolean hasUsableLocale = false; + for (Match match : Match.values()) { + hasUsableLocale |= localeMatches(locale, rescDesc.getLocales(), match); + } + if (hasUsableLocale && stringMatches(os, rescDesc.getOS()) && stringMatches(arch, rescDesc.getArch())) result.addAll(rescDesc.getResources(launchType)); @@ -408,6 +459,7 @@ public class JNLPFile { return result; } + @Override public void addResource(Object resource) { // todo: honor the current locale, os, arch values sharedResources.addResource(resource); @@ -433,7 +485,11 @@ public class JNLPFile { public ResourcesDesc[] getResourcesDescs(final Locale locale, final String os, final String arch) { List<ResourcesDesc> matchingResources = new ArrayList<ResourcesDesc>(); for (ResourcesDesc rescDesc: resources) { - if (localMatches(locale, rescDesc.getLocales()) + boolean hasUsableLocale = false; + for (Match match : Match.values()) { + hasUsableLocale |= localeMatches(locale, rescDesc.getLocales(), match); + } + if (hasUsableLocale && stringMatches(os, rescDesc.getOS()) && stringMatches(arch, rescDesc.getArch())) { matchingResources.add(rescDesc); @@ -546,28 +602,48 @@ public class JNLPFile { * * @param requested the local * @param available the available locales + * @param precision the depth with which to match locales. 1 checks only + * language, 2 checks language and country, 3 checks language, country and + * variant for matches. Passing 0 will always return true. * @return true if requested matches any of available, or if * available is empty or null. */ - private boolean localMatches(Locale requested, Locale available[]) { - if (available == null || available.length == 0) - return true; - - for (int i = 0; i < available.length; i++) { - String language = requested.getLanguage(); // "" but never null - String country = requested.getCountry(); - String variant = requested.getVariant(); - - if (!"".equals(language) && !language.equalsIgnoreCase(available[i].getLanguage())) - continue; - if (!"".equals(country) && !country.equalsIgnoreCase(available[i].getCountry())) - continue; - if (!"".equals(variant) && !variant.equalsIgnoreCase(available[i].getVariant())) - continue; - - return true; + public boolean localeMatches(Locale requested, Locale available[], Match matchLevel) { + + if (matchLevel == Match.GENERALIZED) + return available == null || available.length == 0; + + String language = requested.getLanguage(); // "" but never null + String country = requested.getCountry(); + String variant = requested.getVariant(); + + for (Locale locale : available) { + switch (matchLevel) { + case LANG: + if (!language.isEmpty() + && language.equals(locale.getLanguage()) + && locale.getCountry().isEmpty() + && locale.getVariant().isEmpty()) + return true; + break; + case LANG_COUNTRY: + if (!language.isEmpty() + && language.equals(locale.getLanguage()) + && !country.isEmpty() + && country.equals(locale.getCountry()) + && locale.getVariant().isEmpty()) + return true; + break; + case LANG_COUNTRY_VARIANT: + if (language.equals(locale.getLanguage()) + && country.equals(locale.getCountry()) + && variant.equals(locale.getVariant())) + return true; + break; + default: + break; + } } - return false; } @@ -612,14 +688,15 @@ public class JNLPFile { codeBase = parser.getCodeBase(); sourceLocation = parser.getFileLocation() != null ? parser.getFileLocation() : location; info = parser.getInfo(root); + parser.checkForInformation(); update = parser.getUpdate(root); resources = parser.getResources(root, false); // false == not a j2se/java resources section launchType = parser.getLauncher(root); component = parser.getComponent(root); security = parser.getSecurity(root); - + checkForSpecialProperties(); - + } catch (ParseException ex) { throw ex; } catch (Exception ex) { @@ -729,7 +806,7 @@ public class JNLPFile { /** * Returns a boolean after determining if a signed JNLP warning should be * displayed in the 'More Information' panel. - * + * * @return true if a warning should be displayed; otherwise false */ public boolean requiresSignedJNLPWarning() { @@ -742,5 +819,4 @@ public class JNLPFile { public void setSignedJNLPAsMissing() { missingSignedJNLP = true; } - } diff --git a/netx/net/sourceforge/jnlp/MissingInformationException.java b/netx/net/sourceforge/jnlp/MissingInformationException.java new file mode 100644 index 0000000..99871d8 --- /dev/null +++ b/netx/net/sourceforge/jnlp/MissingInformationException.java @@ -0,0 +1,44 @@ +// Copyright (C) 2012 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +package net.sourceforge.jnlp; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +/** + * Thrown when the required information tag is not found + * under the current JVM's locale or as a generalized element. + */ +public class MissingInformationException extends RequiredElementException { + + private static final long serialVersionUID = 1L; + private static final String message = R("PNoInfoElement"); + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String) + */ + public MissingInformationException() { + super(message); + } + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String, Throwable) + */ + public MissingInformationException(Throwable cause) { + super(message, cause); + } +} diff --git a/netx/net/sourceforge/jnlp/MissingTitleException.java b/netx/net/sourceforge/jnlp/MissingTitleException.java new file mode 100644 index 0000000..209af24 --- /dev/null +++ b/netx/net/sourceforge/jnlp/MissingTitleException.java @@ -0,0 +1,45 @@ +// Copyright (C) 2012 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +package net.sourceforge.jnlp; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +/** + * Thrown when a title that is required from the information tag is not found + * under the current JVM's locale or as a generalized element. + */ +public class MissingTitleException extends RequiredElementException { + + private static final long serialVersionUID = 1L; + + private static final String message = R("PMissingElement", R("PMissingTitle")); + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String) + */ + public MissingTitleException() { + super(message); + } + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String, Throwable) + */ + public MissingTitleException(Throwable cause) { + super(message, cause); + } +} diff --git a/netx/net/sourceforge/jnlp/MissingVendorException.java b/netx/net/sourceforge/jnlp/MissingVendorException.java new file mode 100644 index 0000000..ffd33fc --- /dev/null +++ b/netx/net/sourceforge/jnlp/MissingVendorException.java @@ -0,0 +1,44 @@ +// Copyright (C) 2012 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +package net.sourceforge.jnlp; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +/** + * Thrown when a vendor that is required from the information tag is not found + * under the current JVM's locale or as a generalized element. + */ +public class MissingVendorException extends RequiredElementException { + + private static final long serialVersionUID = 1L; + private static final String message = R("PMissingElement", R("PMissingVendor")); + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String) + */ + public MissingVendorException() { + super(message); + } + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String, Throwable) + */ + public MissingVendorException(Throwable cause) { + super(message, cause); + } +} diff --git a/netx/net/sourceforge/jnlp/Parser.java b/netx/net/sourceforge/jnlp/Parser.java index 60cd9b4..d24c0fd 100644 --- a/netx/net/sourceforge/jnlp/Parser.java +++ b/netx/net/sourceforge/jnlp/Parser.java @@ -1,5 +1,5 @@ // Copyright (C) 2001-2003 Jon A. Maxwell (JAM) -// Copyright (C) 2009 Red Hat, Inc. +// Copyright (C) 2012 Red Hat, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,7 @@ import java.util.*; //import gd.xml.tiny.*; import net.sourceforge.jnlp.UpdateDesc.Check; import net.sourceforge.jnlp.UpdateDesc.Policy; +import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.nanoxml.*; /** @@ -425,6 +426,35 @@ class Parser { // /** + * Make sure a title and vendor are present and nonempty and localized as + * best matching as possible for the JVM's current locale. Fallback to a + * generalized title and vendor otherwise. If none is found, throw an exception. + * + * Additionally prints homepage, description, title and vendor to stdout + * if in Debug mode. + * @throws RequiredElementException + */ + void checkForInformation() throws RequiredElementException { + if (JNLPRuntime.isDebug()) { + System.out.println("Homepage: " + file.getInformation().getHomepage()); + System.out.println("Description: " + file.getInformation().getDescription()); + } + + String title = file.getTitle(); + String vendor = file.getVendor(); + + if (title == null || title.trim().isEmpty()) + throw new MissingTitleException(); + else if (JNLPRuntime.isDebug()) + System.out.println("Acceptable title tag found, contains: " + title); + + if (vendor == null || vendor.trim().isEmpty()) + throw new MissingVendorException(); + else if (JNLPRuntime.isDebug()) + System.out.println("Acceptable vendor tag found, contains: " + vendor); + } + + /** * Returns all of the information elements under the specified * node. * @@ -438,11 +468,12 @@ class Parser { // ensure that there are at least one information section present if (info.length == 0) - throw new ParseException(R("PNoInfoElement")); + throw new MissingInformationException(); // create objects from the info sections - for (int i = 0; i < info.length; i++) - result.add(getInformationDesc(info[i])); + for (Node infoNode : info) { + result.add(getInformationDesc(infoNode)); + } return result; } @@ -504,11 +535,6 @@ class Parser { child = child.getNextSibling(); } - if (info.getTitle() == null || info.getTitle().trim().isEmpty()) - throw new ParseException(R("PNoTitleElement")); - if (info.getVendor() == null || info.getVendor().trim().isEmpty()) - throw new ParseException(R("PNoVendorElement")); - return info; } @@ -896,7 +922,7 @@ class Parser { String language = localeStr.substring(0, 2); String country = (localeStr.length() < 5) ? "" : localeStr.substring(3, 5); - String variant = (localeStr.length() < 7) ? "" : localeStr.substring(6, 8); + String variant = (localeStr.length() > 7) ? localeStr.substring(6) : ""; // null is not allowed n locale but "" is return new Locale(language, country, variant); diff --git a/netx/net/sourceforge/jnlp/RequiredElementException.java b/netx/net/sourceforge/jnlp/RequiredElementException.java new file mode 100644 index 0000000..cd27600 --- /dev/null +++ b/netx/net/sourceforge/jnlp/RequiredElementException.java @@ -0,0 +1,41 @@ +// Copyright (C) 2012 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +package net.sourceforge.jnlp; + +/** + * Thrown when a field that is required from the information tag is not found + * under the current JVM's locale or as a generalized element. + */ +public class RequiredElementException extends ParseException { + + private static final long serialVersionUID = 1L; + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String) + */ + public RequiredElementException(String message) { + super(message); + } + + /* (non-Javadoc) + * @see net.sourceforge.jnlp.ParseException(String, Throwable) + */ + public RequiredElementException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties index cd72cf7..587e6ae 100644 --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -106,9 +106,10 @@ PExtensionHasJ2SE=j2se element cannot be specified in a component extension file PInnerJ2SE=j2se element cannot be specified within a j2se element.
PTwoMains=Duplicate main JAR defined in a resources element (there can be only one)
PNativeHasMain=Cannot specify main attribute on native JARs.
-PNoInfoElement=No information section defined
-PNoTitleElement=The title section has not been defined in the JNLP file.
-PNoVendorElement=The vendor section has not been defined in the JNLP file.
+PNoInfoElement=No information section defined.
+PMissingTitle=title
+PMissingVendor=vendor
+PMissingElement=The {0} section has not been defined for your locale nor does a default value exist in the JNLP file.
PTwoDescriptions=Duplicate description of kind {0}
PSharing=Element "sharing-allowed" is illegal in a standard JNLP file
PTwoSecurity=Only one security element allowed per JNLPFile.
|