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