// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.core.modules; import static org.openstreetmap.josm.tools.I18n.tr; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.LinkedList; import java.util.List; /** * A parser for the module list provided by an opendata Module Download Site. * * See <a href="http://svn.openstreetmap.org/applications/editors/josm/plugins/opendata/modules.txt">OSM SVN</a> * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style * name/value-pairs. * */ public class ModuleListParser { /** * Creates the module information object * * @param name the module name * @param url the module download url * @param manifest the module manifest * @return a module information object * @throws ModuleListParseException if the list cannot be parsed */ protected ModuleInformation createInfo(String name, String url, String manifest) throws ModuleListParseException { try { return new ModuleInformation( new ByteArrayInputStream(manifest.getBytes("utf-8")), name.substring(0, name.length() - 4), url ); } catch (UnsupportedEncodingException e) { throw new ModuleListParseException(tr("Failed to create module information from manifest for module ''{0}''", name), e); } catch (ModuleException e) { throw new ModuleListParseException(tr("Failed to create module information from manifest for module ''{0}''", name), e); } } /** * Parses a module information document and replies a list of module information objects. * * See <a href="http://svn.openstreetmap.org/applications/editors/josm/plugins/opendata/modules.txt">OSM SVN</a> * for a sample of the document. The format is a custom format, kind of mix of CSV and RFC822 style * name/value-pairs. * * @param in the input stream from which to parse * @return the list of module information objects * @throws ModuleListParseException thrown if something goes wrong while parsing */ public List<ModuleInformation> parse(InputStream in) throws ModuleListParseException { List<ModuleInformation> ret = new LinkedList<>(); BufferedReader r = null; try { r = new BufferedReader(new InputStreamReader(in, "utf-8")); String name = null; String url = null; StringBuilder manifest = new StringBuilder(); /* code structure: for () { A; B; C; } B; */ for (String line = r.readLine(); line != null; line = r.readLine()) { if (line.startsWith("\t")) { line = line.substring(1); if (line.length() > 70) { manifest.append(line.substring(0, 70)).append("\n"); line = " " + line.substring(70); } manifest.append(line).append("\n"); continue; } if (name != null) { ModuleInformation info = createInfo(name, url, manifest.toString()); if (info != null) { for (Module module : ModuleHandler.moduleList) { if (module.getModuleInformation().name.equals(info.getName())) { info.localversion = module.getModuleInformation().localversion; } } ret.add(info); } } String[] x = line.split(";"); if (x.length != 2) throw new IOException(tr("Illegal entry in module list.")); name = x[0]; url = x[1]; manifest = new StringBuilder(); } if (name != null) { ModuleInformation info = createInfo(name, url, manifest.toString()); if (info != null) { for (Module module : ModuleHandler.moduleList) { if (module.getModuleInformation().name.equals(info.getName())) { info.localversion = module.getModuleInformation().localversion; } } ret.add(info); } } return ret; } catch (IOException e) { throw new ModuleListParseException(e); } } }