// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.help;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.openstreetmap.josm.tools.WikiReader;
/**
* Reads help content from the JOSM Wiki and prepares it for rendering in the internal
* help browser.
*
* The help content has to be <strong>filtered</strong> because only the main content <tt><div></tt>
* of a Wiki help page is displayed in the internal help browser.
*
* It also has to be <strong>transformed</strong> because the internal help browser required slightly
* different HTML than what is provided by the Wiki.
*
* @see WikiReader
*/
public class HelpContentReader {
/** the base url */
private String baseUrl;
/**
* constructor
*
* @param baseUrl the base url of the JOSM help wiki, i.e. http://josm.openstreetmap.org
*/
public HelpContentReader(String baseUrl) {
this.baseUrl = baseUrl;
}
/**
* Fetches the content of a help topic from the JOSM wiki.
*
* @param helpTopicUrl the absolute help topic URL
* @return the content, filtered and transformed for being displayed in the internal help browser
* @throws HelpContentReaderException thrown if problem occurs
* @throws MissingHelpContentException thrown if this helpTopicUrl doesn't point to an existing Wiki help page
*/
public String fetchHelpTopicContent(String helpTopicUrl, boolean dotest) throws HelpContentReaderException {
URL url = null;
HttpURLConnection con = null;
BufferedReader in = null;
try {
url = new URL(helpTopicUrl);
con = (HttpURLConnection)url.openConnection();
con.connect();
in = new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8"));
return prepareHelpContent(in, dotest);
} catch(MalformedURLException e) {
throw new HelpContentReaderException(e);
} catch(IOException e) {
HelpContentReaderException ex = new HelpContentReaderException(e);
if (con != null) {
try {
ex.setResponseCode(con.getResponseCode());
} catch(IOException e1) {
// ignore
}
}
throw ex;
} finally {
if (in != null) {
try {
in.close();
} catch(IOException e) {
// ignore
}
}
}
}
/**
* Reads help content from the input stream and prepares it to be rendered later
* in the internal help browser.
*
* Throws a {@see MissingHelpContentException} if the content read from the stream
* most likely represents a stub help page.
*
* @param in the input stream
* @return the content
* @throws HelpContentReaderException thrown if an exception occurs
* @throws MissingHelpContentException thrown, if the content read isn't a help page
*/
protected String prepareHelpContent(BufferedReader in, boolean dotest) throws HelpContentReaderException {
boolean isInContent = false;
boolean isInTranslationsSideBar = false;
boolean isExistingHelpPage = false;
StringBuffer sball = new StringBuffer();
StringBuffer sb = new StringBuffer();
try {
for (String line = in.readLine(); line != null; line = in.readLine()) {
sball.append(line);
sball.append("\n");
if (line.contains("<div id=\"searchable\">")) {
isInContent = true;
} else if (line.contains("<div class=\"wiki-toc trac-nav\"")) {
isInTranslationsSideBar = true;
} else if (line.contains("<div class=\"wikipage searchable\">")) {
isInContent = true;
} else if (line.contains("<div class=\"buttons\">")) {
isInContent = false;
} else if (line.contains("<h3>Attachments</h3>")) {
isInContent = false;
} else if (line.contains("<input type=\"submit\" name=\"attachfilebutton\"")) {
// heuristic: if we find a button for uploading images we are in an
// existing pages. Otherwise this is probably the stub page for a not yet
// existing help page
isExistingHelpPage = true;
}
if (isInContent && !isInTranslationsSideBar) {
// add a border="0" attribute to images, otherwise the internal help browser
// will render a thick border around images inside an <a> element
//
// Also make sure image URLs are absolute
//
line = line.replaceAll("<img src=\"/", "<img border=\"0\" src=\"" + baseUrl + "/").replaceAll("href=\"/",
"href=\"" + baseUrl + "/").replaceAll(" />", ">");
sb.append(line);
sb.append("\n");
} else if (isInTranslationsSideBar && line.contains("</div>")) {
isInTranslationsSideBar = false;
}
}
} catch(IOException e) {
throw new HelpContentReaderException(e);
}
if(!dotest && sb.length() == 0)
sb = sball;
else if (dotest && !isExistingHelpPage)
throw new MissingHelpContentException();
sb.insert(0, "<html>");
sb.append("<html>");
return sb.toString();
}
}