001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.help;
003
004import java.io.BufferedReader;
005import java.io.IOException;
006import java.io.InputStreamReader;
007import java.net.HttpURLConnection;
008import java.net.MalformedURLException;
009import java.net.URL;
010import java.nio.charset.StandardCharsets;
011
012import org.openstreetmap.josm.tools.Utils;
013import org.openstreetmap.josm.tools.WikiReader;
014
015/**
016 * Reads help content from the JOSM Wiki and prepares it for rendering in the internal
017 * help browser.
018 *
019 * The help content has to be <strong>filtered</strong> because only the main content <tt>&lt;div&gt;</tt>
020 * of a Wiki help page is displayed in the internal help browser.
021 *
022 * It also has to be <strong>transformed</strong> because the internal help browser required slightly
023 * different HTML than what is provided by the Wiki.
024 */
025public class HelpContentReader extends WikiReader {
026
027    /**
028     * Constructs a new {@code HelpContentReader}.
029     *
030     * @param baseUrl the base url of the JOSM help wiki, i.e. https://josm.openstreetmap.org
031     */
032    public HelpContentReader(String baseUrl) {
033        super(baseUrl);
034    }
035
036    /**
037     * Fetches the content of a help topic from the JOSM wiki.
038     *
039     * @param helpTopicUrl  the absolute help topic URL
040     * @return the content, filtered and transformed for being displayed in the internal help browser
041     * @throws HelpContentReaderException thrown if problem occurs
042     * @throws MissingHelpContentException thrown if this helpTopicUrl doesn't point to an existing Wiki help page
043     */
044    public String fetchHelpTopicContent(String helpTopicUrl, boolean dotest) throws HelpContentReaderException {
045        if(helpTopicUrl == null)
046            throw new MissingHelpContentException(helpTopicUrl);
047        HttpURLConnection con = null;
048        try {
049            URL u = new URL(helpTopicUrl);
050            con = Utils.openHttpConnection(u);
051            con.connect();
052            try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
053                return prepareHelpContent(in, dotest, u);
054            }
055        } catch(MalformedURLException e) {
056            throw new HelpContentReaderException(e);
057        } catch(IOException e) {
058            HelpContentReaderException ex = new HelpContentReaderException(e);
059            if (con != null) {
060                try {
061                    ex.setResponseCode(con.getResponseCode());
062                } catch(IOException e1) {
063                    // ignore
064                }
065            }
066            throw ex;
067        }
068    }
069
070    /**
071     * Reads help content from the input stream and prepares it to be rendered later
072     * in the internal help browser.
073     *
074     * Throws a {@link MissingHelpContentException} if the content read from the stream
075     * most likely represents a stub help page.
076     *
077     * @param in the input stream
078     * @return the content
079     * @throws HelpContentReaderException thrown if an exception occurs
080     * @throws MissingHelpContentException thrown, if the content read isn't a help page
081     * @since 5936
082     */
083    protected String prepareHelpContent(BufferedReader in, boolean dotest, URL url) throws HelpContentReaderException {
084        String s = "";
085        try {
086            s = readFromTrac(in, url);
087        } catch(IOException e) {
088            throw new HelpContentReaderException(e);
089        }
090        if(dotest && s.isEmpty())
091            throw new MissingHelpContentException(s);
092        return s;
093    }
094}