1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.plugins;
|
---|
3 |
|
---|
4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
5 |
|
---|
6 | import java.io.BufferedReader;
|
---|
7 | import java.io.IOException;
|
---|
8 | import java.io.InputStream;
|
---|
9 | import java.io.InputStreamReader;
|
---|
10 | import java.nio.charset.StandardCharsets;
|
---|
11 | import java.util.LinkedList;
|
---|
12 | import java.util.List;
|
---|
13 | import java.util.jar.Attributes;
|
---|
14 | import java.util.regex.Matcher;
|
---|
15 | import java.util.regex.Pattern;
|
---|
16 |
|
---|
17 | import org.openstreetmap.josm.tools.Logging;
|
---|
18 |
|
---|
19 | /**
|
---|
20 | * A parser for the plugin list provided by a JOSM Plugin Download Site.
|
---|
21 | *
|
---|
22 | * See <a href="https://josm.openstreetmap.de/plugin">https://josm.openstreetmap.de/plugin</a>
|
---|
23 | * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style
|
---|
24 | * name/value-pairs.
|
---|
25 | *
|
---|
26 | */
|
---|
27 | public class PluginListParser {
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * Creates the plugin information object
|
---|
31 | *
|
---|
32 | * @param name the plugin name
|
---|
33 | * @param url the plugin download url
|
---|
34 | * @param manifest the plugin manifest attributes
|
---|
35 | * @return a plugin information object
|
---|
36 | * @throws PluginListParseException if plugin manifest cannot be parsed
|
---|
37 | */
|
---|
38 | public static PluginInformation createInfo(String name, String url, Attributes manifest) throws PluginListParseException {
|
---|
39 | try {
|
---|
40 | return new PluginInformation(
|
---|
41 | manifest,
|
---|
42 | name.substring(0, name.length() - 4),
|
---|
43 | url
|
---|
44 | );
|
---|
45 | } catch (PluginException e) {
|
---|
46 | throw new PluginListParseException(tr("Failed to create plugin information from manifest for plugin ''{0}''", name), e);
|
---|
47 | }
|
---|
48 | }
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * Parses a plugin information document and replies a list of plugin information objects.
|
---|
52 | *
|
---|
53 | * See <a href="https://josm.openstreetmap.de/plugin">https://josm.openstreetmap.de/plugin</a>
|
---|
54 | * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style
|
---|
55 | * name/value-pairs.
|
---|
56 | *
|
---|
57 | * @param in the input stream from which to parse
|
---|
58 | * @return the list of plugin information objects
|
---|
59 | * @throws PluginListParseException if something goes wrong while parsing
|
---|
60 | */
|
---|
61 | public List<PluginInformation> parse(InputStream in) throws PluginListParseException {
|
---|
62 | List<PluginInformation> ret = new LinkedList<>();
|
---|
63 | try (BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
|
---|
64 | String name = null;
|
---|
65 | String url = null;
|
---|
66 | Attributes manifest = new Attributes();
|
---|
67 | final Pattern spaceColonSpace = Pattern.compile("\\s*:\\s*", Pattern.UNICODE_CHARACTER_CLASS);
|
---|
68 | final Matcher matcher = spaceColonSpace.matcher("");
|
---|
69 | for (String line = r.readLine(); line != null; line = r.readLine()) {
|
---|
70 | if (line.startsWith("\t")) {
|
---|
71 | matcher.reset(line);
|
---|
72 | if (matcher.find() && matcher.start() > 0 && matcher.end() < line.length()) {
|
---|
73 | final String key = line.substring(1, matcher.start());
|
---|
74 | final String value = line.substring(matcher.end());
|
---|
75 | manifest.put(new Attributes.Name(key), value);
|
---|
76 | }
|
---|
77 | continue;
|
---|
78 | }
|
---|
79 | addPluginInformation(ret, name, url, manifest);
|
---|
80 | String[] x = line.split(";", -1);
|
---|
81 | if (x.length != 2)
|
---|
82 | throw new IOException(tr("Illegal entry in plugin list.") + " " + line);
|
---|
83 | name = x[0];
|
---|
84 | url = x[1];
|
---|
85 | manifest = new Attributes();
|
---|
86 | }
|
---|
87 | addPluginInformation(ret, name, url, manifest);
|
---|
88 | return ret;
|
---|
89 | } catch (IOException e) {
|
---|
90 | throw new PluginListParseException(e);
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | private static void addPluginInformation(List<PluginInformation> ret, String name, String url, Attributes manifest) {
|
---|
95 | try {
|
---|
96 | if (name != null) {
|
---|
97 | PluginInformation info = createInfo(name, url, manifest);
|
---|
98 | for (PluginProxy plugin : PluginHandler.pluginList) {
|
---|
99 | if (plugin.getPluginInformation().name.equals(info.getName())) {
|
---|
100 | info.localversion = plugin.getPluginInformation().localversion;
|
---|
101 | }
|
---|
102 | }
|
---|
103 | ret.add(info);
|
---|
104 | }
|
---|
105 | } catch (PluginListParseException ex) {
|
---|
106 | Logging.error(ex);
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | }
|
---|