diff --git a/src/org/openstreetmap/josm/plugins/PluginInformation.java b/src/org/openstreetmap/josm/plugins/PluginInformation.java
index b510cbd3b..dfae76790 100644
|
a
|
b
|
import java.util.List;
|
| 18 | 18 | import java.util.Locale; |
| 19 | 19 | import java.util.Map; |
| 20 | 20 | import java.util.Optional; |
| 21 | | import java.util.TreeMap; |
| 22 | 21 | import java.util.jar.Attributes; |
| 23 | 22 | import java.util.jar.JarInputStream; |
| 24 | 23 | import java.util.jar.Manifest; |
| … |
… |
public class PluginInformation {
|
| 93 | 92 | /** The libraries referenced in Class-Path manifest attribute. */ |
| 94 | 93 | public List<URL> libraries = new LinkedList<>(); |
| 95 | 94 | /** All manifest attributes. */ |
| 96 | | public final Map<String, String> attr = new TreeMap<>(); |
| | 95 | public Attributes attr; |
| 97 | 96 | /** Invalid manifest entries */ |
| 98 | 97 | final List<String> invalidManifestEntries = new ArrayList<>(); |
| 99 | 98 | /** Empty icon for these plugins which have none */ |
| … |
… |
public class PluginInformation {
|
| 133 | 132 | Manifest manifest = jar.getManifest(); |
| 134 | 133 | if (manifest == null) |
| 135 | 134 | throw new PluginException(tr("The plugin file ''{0}'' does not include a Manifest.", file.toString())); |
| 136 | | scanManifest(manifest, false); |
| | 135 | scanManifest(manifest.getMainAttributes(), false); |
| 137 | 136 | libraries.add(0, Utils.fileToURL(file)); |
| 138 | 137 | } catch (IOException | InvalidPathException e) { |
| 139 | 138 | throw new PluginException(name, e); |
| … |
… |
public class PluginInformation {
|
| 150 | 149 | * @throws PluginException if the plugin information can't be read from the input stream |
| 151 | 150 | */ |
| 152 | 151 | public PluginInformation(InputStream manifestStream, String name, String url) throws PluginException { |
| 153 | | this.name = name; |
| 154 | 152 | try { |
| 155 | 153 | Manifest manifest = new Manifest(); |
| 156 | 154 | manifest.read(manifestStream); |
| 157 | 155 | if (url != null) { |
| 158 | 156 | downloadlink = url; |
| 159 | 157 | } |
| 160 | | scanManifest(manifest, url != null); |
| | 158 | scanManifest(manifest.getMainAttributes(), url != null); |
| 161 | 159 | } catch (IOException e) { |
| 162 | 160 | throw new PluginException(name, e); |
| 163 | 161 | } |
| 164 | 162 | } |
| 165 | 163 | |
| | 164 | /** |
| | 165 | * Creates a plugin information object by reading plugin information in Manifest format |
| | 166 | * from the input stream {@code manifestStream}. |
| | 167 | * |
| | 168 | * @param attr the manifest attributes |
| | 169 | * @param name the plugin name |
| | 170 | * @param url the download URL for the plugin |
| | 171 | * @throws PluginException if the plugin information can't be read from the input stream |
| | 172 | */ |
| | 173 | public PluginInformation(Attributes attr, String name, String url) throws PluginException { |
| | 174 | this.name = name; |
| | 175 | if (url != null) { |
| | 176 | downloadlink = url; |
| | 177 | } |
| | 178 | scanManifest(attr, url != null); |
| | 179 | } |
| | 180 | |
| 166 | 181 | /** |
| 167 | 182 | * Updates the plugin information of this plugin information object with the |
| 168 | 183 | * plugin information in a plugin information object retrieved from a plugin |
| … |
… |
public class PluginInformation {
|
| 188 | 203 | this.iconPath = other.iconPath; |
| 189 | 204 | this.canloadatruntime = other.canloadatruntime; |
| 190 | 205 | this.libraries = other.libraries; |
| 191 | | this.attr.clear(); |
| 192 | | this.attr.putAll(other.attr); |
| | 206 | this.attr = new Attributes(other.attr); |
| 193 | 207 | this.invalidManifestEntries.clear(); |
| 194 | 208 | this.invalidManifestEntries.addAll(other.invalidManifestEntries); |
| 195 | 209 | } |
| … |
… |
public class PluginInformation {
|
| 214 | 228 | this.file = other.file; |
| 215 | 229 | } |
| 216 | 230 | |
| 217 | | private void scanManifest(Manifest manifest, boolean oldcheck) { |
| | 231 | private void scanManifest(Attributes attr, boolean oldcheck) { |
| 218 | 232 | String lang = LanguageInfo.getLanguageCodeManifest(); |
| 219 | | Attributes attr = manifest.getMainAttributes(); |
| 220 | 233 | className = attr.getValue("Plugin-Class"); |
| 221 | 234 | String s = Optional.ofNullable(attr.getValue(lang+"Plugin-Link")).orElseGet(() -> attr.getValue("Plugin-Link")); |
| 222 | 235 | if (s != null && !Utils.isValidUrl(s)) { |
| … |
… |
public class PluginInformation {
|
| 317 | 330 | libraries.add(Utils.fileToURL(entryFile)); |
| 318 | 331 | } |
| 319 | 332 | } |
| 320 | | for (Object o : attr.keySet()) { |
| 321 | | this.attr.put(o.toString(), attr.getValue(o.toString())); |
| 322 | | } |
| | 333 | this.attr = attr; |
| 323 | 334 | } |
| 324 | 335 | |
| 325 | 336 | /** |
diff --git a/src/org/openstreetmap/josm/plugins/PluginListParser.java b/src/org/openstreetmap/josm/plugins/PluginListParser.java
index 4009e0221..e7a050e92 100644
|
a
|
b
|
import java.io.InputStreamReader;
|
| 11 | 11 | import java.nio.charset.StandardCharsets; |
| 12 | 12 | import java.util.LinkedList; |
| 13 | 13 | import java.util.List; |
| | 14 | import java.util.jar.Attributes; |
| 14 | 15 | |
| 15 | 16 | import org.openstreetmap.josm.tools.Logging; |
| 16 | 17 | |
| … |
… |
public class PluginListParser {
|
| 29 | 30 | * |
| 30 | 31 | * @param name the plugin name |
| 31 | 32 | * @param url the plugin download url |
| 32 | | * @param manifest the plugin manifest |
| | 33 | * @param manifest the plugin manifest attributes |
| 33 | 34 | * @return a plugin information object |
| 34 | 35 | * @throws PluginListParseException if plugin manifest cannot be parsed |
| 35 | 36 | */ |
| 36 | | public static PluginInformation createInfo(String name, String url, String manifest) throws PluginListParseException { |
| | 37 | public static PluginInformation createInfo(String name, String url, Attributes manifest) throws PluginListParseException { |
| 37 | 38 | try { |
| 38 | 39 | return new PluginInformation( |
| 39 | | new ByteArrayInputStream(manifest.getBytes(StandardCharsets.UTF_8)), |
| | 40 | manifest, |
| 40 | 41 | name.substring(0, name.length() - 4), |
| 41 | 42 | url |
| 42 | 43 | ); |
| … |
… |
public class PluginListParser {
|
| 61 | 62 | try (BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) { |
| 62 | 63 | String name = null; |
| 63 | 64 | String url = null; |
| 64 | | StringBuilder manifest = new StringBuilder(); |
| | 65 | Attributes manifest = new Attributes(); |
| 65 | 66 | for (String line = r.readLine(); line != null; line = r.readLine()) { |
| 66 | 67 | if (line.startsWith("\t")) { |
| 67 | | line = line.substring(1); |
| 68 | | /* NOTE: Although manifest specification says line should not be longer than 72 bytes it |
| 69 | | supports more than 500 bytes and thus even the longest possible 72 character UTF-8, so |
| 70 | | this code correctly splits the text at 70 characters, not bytes. */ |
| 71 | | while (line.length() > 70) { |
| 72 | | manifest.append(line.substring(0, 70)).append('\n'); |
| 73 | | line = ' ' + line.substring(70); |
| 74 | | } |
| 75 | | manifest.append(line).append('\n'); |
| | 68 | final String[] keyValue = line.split("\\s*:\\s*", 2); |
| | 69 | manifest.put(new Attributes.Name(keyValue[0].substring(1)), keyValue[1]); |
| 76 | 70 | continue; |
| 77 | 71 | } |
| 78 | | addPluginInformation(ret, name, url, manifest.toString()); |
| | 72 | addPluginInformation(ret, name, url, manifest); |
| 79 | 73 | String[] x = line.split(";", -1); |
| 80 | 74 | if (x.length != 2) |
| 81 | 75 | throw new IOException(tr("Illegal entry in plugin list.") + " " + line); |
| 82 | 76 | name = x[0]; |
| 83 | 77 | url = x[1]; |
| 84 | | manifest = new StringBuilder(); |
| | 78 | manifest = new Attributes(); |
| 85 | 79 | } |
| 86 | | addPluginInformation(ret, name, url, manifest.toString()); |
| | 80 | addPluginInformation(ret, name, url, manifest); |
| 87 | 81 | return ret; |
| 88 | 82 | } catch (IOException e) { |
| 89 | 83 | throw new PluginListParseException(e); |
| 90 | 84 | } |
| 91 | 85 | } |
| 92 | 86 | |
| 93 | | private static void addPluginInformation(List<PluginInformation> ret, String name, String url, String manifest) { |
| | 87 | private static void addPluginInformation(List<PluginInformation> ret, String name, String url, Attributes manifest) { |
| 94 | 88 | try { |
| 95 | 89 | if (name != null) { |
| 96 | 90 | PluginInformation info = createInfo(name, url, manifest); |
diff --git a/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java b/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java
index 14a922b3b..51fdfb44b 100644
|
a
|
b
|
import java.util.Collection;
|
| 21 | 21 | import java.util.List; |
| 22 | 22 | import java.util.concurrent.ExecutionException; |
| 23 | 23 | import java.util.concurrent.Future; |
| | 24 | import java.util.jar.Attributes; |
| 24 | 25 | |
| 25 | 26 | import javax.swing.JComponent; |
| 26 | 27 | import javax.swing.JPanel; |
| … |
… |
public class MainApplicationTest {
|
| 204 | 205 | |
| 205 | 206 | private static PluginInformation newPluginInformation(String plugin) throws PluginListParseException { |
| 206 | 207 | return PluginListParser.createInfo(plugin+".jar", "https://josm.openstreetmap.de/osmsvn/applications/editors/josm/dist/"+plugin+".jar", |
| 207 | | ""); |
| | 208 | new Attributes()); |
| 208 | 209 | } |
| 209 | 210 | |
| 210 | 211 | /** |