// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.tools;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URL;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.tools.LanguageInfo.LocaleType;
/**
* Read a trac-wiki page.
*
* @author imi
*/
public class WikiReader {
private final String baseurl;
/**
* Constructs a new {@code WikiReader} for the given base URL.
* @param baseurl The wiki base URL
*/
public WikiReader(String baseurl) {
this.baseurl = baseurl;
}
/**
* Constructs a new {@code WikiReader}.
*/
public WikiReader() {
this(Main.pref.get("help.baseurl", Main.getJOSMWebsite()));
}
/**
* Returns the base URL of wiki.
* @return the base URL of wiki
* @since 7434
*/
public final String getBaseUrlWiki() {
return baseurl + "/wiki/";
}
/**
* Read the page specified by the url and return the content.
*
* If the url is within the baseurl path, parse it as an trac wikipage and replace relative paths etc..
* @param url the URL to read
* @return The page as string
*
* @throws IOException Throws, if the page could not be loaded.
*/
public String read(String url) throws IOException {
URL u = new URL(url);
try (BufferedReader in = HttpClient.create(u).connect().getContentReader()) {
boolean txt = url.endsWith("?format=txt");
if (url.startsWith(getBaseUrlWiki()) && !txt)
return readFromTrac(in, u);
return readNormal(in, !txt);
}
}
/**
* Reads the localized version of the given wiki page.
* @param text The page title, without locale prefix
* @return the localized version of the given wiki page
* @throws IOException if any I/O error occurs
*/
public String readLang(String text) throws IOException {
String languageCode;
String res = "";
languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.DEFAULTNOTENGLISH);
if (languageCode != null) {
res = readLang(new URL(getBaseUrlWiki() + languageCode + text));
}
if (res.isEmpty()) {
languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.BASELANGUAGE);
if (languageCode != null) {
res = readLang(new URL(getBaseUrlWiki() + languageCode + text));
}
}
if (res.isEmpty()) {
languageCode = LanguageInfo.getWikiLanguagePrefix(LocaleType.ENGLISH);
if (languageCode != null) {
res = readLang(new URL(getBaseUrlWiki() + languageCode + text));
}
}
if (res.isEmpty()) {
throw new IOException(text + " does not exist");
} else {
return res;
}
}
private String readLang(URL url) throws IOException {
try (BufferedReader in = HttpClient.create(url).connect().getContentReader()) {
return readFromTrac(in, url);
}
}
private static String readNormal(BufferedReader in, boolean html) throws IOException {
StringBuilder b = new StringBuilder();
for (String line = in.readLine(); line != null; line = in.readLine()) {
if (!line.contains("[[TranslatedPages]]")) {
b.append(line.replaceAll(" />", ">")).append('\n');
}
}
return html ? "<html>" + b + "</html>" : b.toString();
}
protected String readFromTrac(BufferedReader in, URL url) throws IOException {
boolean inside = false;
boolean transl = false;
boolean skip = false;
StringBuilder b = new StringBuilder();
StringBuilder full = new StringBuilder();
for (String line = in.readLine(); line != null; line = in.readLine()) {
full.append(line);
if (line.contains("<div id=\"searchable\">")) {
inside = true;
} else if (line.contains("<div class=\"wiki-toc trac-nav\"")) {
transl = true;
} else if (line.contains("<div class=\"wikipage searchable\">")) {
inside = true;
} else if (line.contains("<div class=\"buttons\">")) {
inside = false;
} else if (line.contains("<h3>Attachments</h3>")) {
inside = false;
} else if (line.contains("<div id=\"attachments\">")) {
inside = false;
} else if (line.contains("<div class=\"trac-modifiedby\">")) {
skip = true;
}
if (inside && !transl && !skip) {
// add a border="0" attribute to images, otherwise the internal help browser
// will render a thick border around images inside an <a> element
// remove width information to avoid distorded images (fix #11262)
b.append(line.replaceAll("<img ", "<img border=\"0\" ")
.replaceAll("width=\"(\\d+)\"", "")
.replaceAll("<span class=\"icon\">.</span>", "")
.replaceAll("href=\"/", "href=\"" + baseurl + '/')
.replaceAll(" />", ">"))
.append('\n');
} else if (transl && line.contains("</div>")) {
transl = false;
}
if (line.contains("</div>")) {
skip = false;
}
}
if (b.indexOf(" Describe ") >= 0
|| b.indexOf(" does not exist. You can create it here.</p>") >= 0)
return "";
if (b.length() == 0)
b = full;
return "<html><base href=\""+url.toExternalForm() +"\"> " + b + "</html>";
}
}