001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.tools; 003 004import java.io.BufferedReader; 005import java.io.IOException; 006import java.net.URL; 007 008import org.openstreetmap.josm.Main; 009import org.openstreetmap.josm.tools.LanguageInfo.LocaleType; 010 011/** 012 * Read a trac-wiki page. 013 * 014 * @author imi 015 */ 016public class WikiReader { 017 018 private final String baseurl; 019 020 /** 021 * Constructs a new {@code WikiReader} for the given base URL. 022 * @param baseurl The wiki base URL 023 */ 024 public WikiReader(String baseurl) { 025 this.baseurl = baseurl; 026 } 027 028 /** 029 * Constructs a new {@code WikiReader}. 030 */ 031 public WikiReader() { 032 this.baseurl = Main.pref.get("help.baseurl", Main.getJOSMWebsite()); 033 } 034 035 /** 036 * Read the page specified by the url and return the content. 037 * 038 * If the url is within the baseurl path, parse it as an trac wikipage and replace relative 039 * pathes etc.. 040 * 041 * @throws IOException Throws, if the page could not be loaded. 042 */ 043 public String read(String url) throws IOException { 044 URL u = new URL(url); 045 try (BufferedReader in = Utils.openURLReader(u)) { 046 if (url.startsWith(baseurl) && !url.endsWith("?format=txt")) 047 return readFromTrac(in, u); 048 return readNormal(in); 049 } 050 } 051 052 public String readLang(String text) throws IOException { 053 String languageCode; 054 String res = ""; 055 056 languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.DEFAULTNOTENGLISH); 057 if(languageCode != null) { 058 res = readLang(new URL(baseurl + "/wiki/" + languageCode + text)); 059 } 060 061 if(res.isEmpty()) { 062 languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.BASELANGUAGE); 063 if(languageCode != null) { 064 res = readLang(new URL(baseurl + "/wiki/" + languageCode + text)); 065 } 066 } 067 068 if(res.isEmpty()) { 069 languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.ENGLISH); 070 if(languageCode != null) { 071 res = readLang(new URL(baseurl + "/wiki/" + languageCode + text)); 072 } 073 } 074 075 if(res.isEmpty()) { 076 throw new IOException(text + " does not exist"); 077 } else { 078 return res; 079 } 080 } 081 082 private String readLang(URL url) throws IOException { 083 try (BufferedReader in = Utils.openURLReader(url)) { 084 return readFromTrac(in, url); 085 } catch (IOException e) { 086 Main.addNetworkError(url, Utils.getRootCause(e)); 087 throw e; 088 } 089 } 090 091 private String readNormal(BufferedReader in) throws IOException { 092 StringBuilder b = new StringBuilder(); 093 for (String line = in.readLine(); line != null; line = in.readLine()) { 094 if (!line.contains("[[TranslatedPages]]")) { 095 b.append(line.replaceAll(" />", ">")).append("\n"); 096 } 097 } 098 return "<html>" + b + "</html>"; 099 } 100 101 protected String readFromTrac(BufferedReader in, URL url) throws IOException { 102 boolean inside = false; 103 boolean transl = false; 104 boolean skip = false; 105 String b = ""; 106 String full = ""; 107 for (String line = in.readLine(); line != null; line = in.readLine()) { 108 full += line; 109 if (line.contains("<div id=\"searchable\">")) { 110 inside = true; 111 } else if (line.contains("<div class=\"wiki-toc trac-nav\"")) { 112 transl = true; 113 } else if (line.contains("<div class=\"wikipage searchable\">")) { 114 inside = true; 115 } else if (line.contains("<div class=\"buttons\">")) { 116 inside = false; 117 } else if (line.contains("<h3>Attachments</h3>")) { 118 inside = false; 119 } else if (line.contains("<div id=\"attachments\">")) { 120 inside = false; 121 } else if (line.contains("<div class=\"trac-modifiedby\">")) { 122 skip = true; 123 } 124 if (inside && !transl && !skip) { 125 // add a border="0" attribute to images, otherwise the internal help browser 126 // will render a thick border around images inside an <a> element 127 b += line.replaceAll("<img ", "<img border=\"0\" ") 128 .replaceAll("<span class=\"icon\">.</span>", "") 129 .replaceAll("href=\"/", "href=\"" + baseurl + "/") 130 .replaceAll(" />", ">") 131 + "\n"; 132 } else if (transl && line.contains("</div>")) { 133 transl = false; 134 } 135 if (line.contains("</div>")) { 136 skip = false; 137 } 138 } 139 if (b.indexOf(" Describe ") >= 0 140 || b.indexOf(" does not exist. You can create it here.</p>") >= 0) 141 return ""; 142 if(b.isEmpty()) 143 b = full; 144 return "<html><base href=\""+url.toExternalForm() +"\"> " + b + "</html>"; 145 } 146}