Ignore:
Timestamp:
2020-02-15T12:30:27+01:00 (5 years ago)
Author:
donvip
Message:

see #josm18440 - add new API key provider system

Location:
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java

    r35019 r35320  
    2222public final class FeatureAdapter {
    2323
     24    private static ApiKeyAdapter apiKeyAdapter = new DefaultApiKeyAdapter();
    2425    private static BrowserAdapter browserAdapter = new DefaultBrowserAdapter();
    2526    private static ImageAdapter imageAdapter = new DefaultImageAdapter();
     
    3233    }
    3334
     35    /**
     36     * Provider of confidential API keys.
     37     */
     38    @FunctionalInterface
     39    public interface ApiKeyAdapter {
     40        /**
     41         * Retrieves the API key for the given imagery id.
     42         * @param imageryId imagery id
     43         * @return the API key for the given imagery id
     44         */
     45        String retrieveApiKey(String imageryId);
     46    }
     47
     48    /**
     49     * Link browser.
     50     */
     51    @FunctionalInterface
    3452    public interface BrowserAdapter {
     53        /**
     54         * Browses to a given link.
     55         * @param url link
     56         */
    3557        void openLink(String url);
    3658    }
    3759
     60    /**
     61     * Translation support.
     62     */
    3863    public interface TranslationAdapter {
     64        /**
     65         * Translates some text for the current locale.
     66         * <br>
     67         * For example, <code>tr("JMapViewer''s default value is ''{0}''.", val)</code>.
     68         * <br>
     69         * @param text the text to translate.
     70         * Must be a string literal. (No constants or local vars.)
     71         * Can be broken over multiple lines.
     72         * An apostrophe ' must be quoted by another apostrophe.
     73         * @param objects the parameters for the string.
     74         * Mark occurrences in {@code text} with <code>{0}</code>, <code>{1}</code>, ...
     75         * @return the translated string.
     76         */
    3977        String tr(String text, Object... objects);
    4078        // TODO: more i18n functions
    4179    }
    4280
     81    /**
     82     * Logging support.
     83     */
     84    @FunctionalInterface
    4385    public interface LoggingAdapter {
     86        /**
     87         * Retrieves a logger for the given name.
     88         * @param name logger name
     89         * @return logger for the given name
     90         */
    4491        Logger getLogger(String name);
    4592    }
    4693
     94    /**
     95     * Image provider.
     96     */
     97    @FunctionalInterface
    4798    public interface ImageAdapter {
     99        /**
     100         * Returns a <code>BufferedImage</code> as the result of decoding a supplied <code>URL</code>.
     101         *
     102         * @param input a <code>URL</code> to read from.
     103         * @param readMetadata if {@code true}, makes sure to read image metadata to detect transparency color for non translucent images,
     104         * if any.
     105         * Always considered {@code true} if {@code enforceTransparency} is also {@code true}
     106         * @param enforceTransparency if {@code true}, makes sure to read image metadata and, if the image does not
     107         * provide an alpha channel but defines a {@code TransparentColor} metadata node, that the resulting image
     108         * has a transparency set to {@code TRANSLUCENT} and uses the correct transparent color.
     109         *
     110         * @return a <code>BufferedImage</code> containing the decoded contents of the input, or <code>null</code>.
     111         *
     112         * @throws IllegalArgumentException if <code>input</code> is <code>null</code>.
     113         * @throws IOException if an error occurs during reading.
     114         */
    48115        BufferedImage read(URL input, boolean readMetadata, boolean enforceTransparency) throws IOException;
    49116    }
     
    71138    }
    72139
     140    /**
     141     * Registers API key adapter.
     142     * @param apiKeyAdapter API key adapter
     143     */
     144    public static void registerApiKeyAdapter(ApiKeyAdapter apiKeyAdapter) {
     145        FeatureAdapter.apiKeyAdapter = Objects.requireNonNull(apiKeyAdapter);
     146    }
     147
     148    /**
     149     * Registers browser adapter.
     150     * @param browserAdapter browser adapter
     151     */
    73152    public static void registerBrowserAdapter(BrowserAdapter browserAdapter) {
    74153        FeatureAdapter.browserAdapter = Objects.requireNonNull(browserAdapter);
    75154    }
    76155
     156    /**
     157     * Registers image adapter.
     158     * @param imageAdapter image adapter
     159     */
    77160    public static void registerImageAdapter(ImageAdapter imageAdapter) {
    78161        FeatureAdapter.imageAdapter = Objects.requireNonNull(imageAdapter);
    79162    }
    80163
     164    /**
     165     * Registers translation adapter.
     166     * @param translationAdapter translation adapter
     167     */
    81168    public static void registerTranslationAdapter(TranslationAdapter translationAdapter) {
    82169        FeatureAdapter.translationAdapter = Objects.requireNonNull(translationAdapter);
    83170    }
    84171
     172    /**
     173     * Registers logging adapter.
     174     * @param loggingAdapter logging adapter
     175     */
    85176    public static void registerLoggingAdapter(LoggingAdapter loggingAdapter) {
    86177        FeatureAdapter.loggingAdapter = Objects.requireNonNull(loggingAdapter);
     
    96187    }
    97188
     189    /**
     190     * Retrieves the API key for the given imagery id using the current {@link ApiKeyAdapter}.
     191     * @param imageryId imagery id
     192     * @return the API key for the given imagery id
     193     */
     194    public static String retrieveApiKey(String imageryId) {
     195        return apiKeyAdapter.retrieveApiKey(imageryId);
     196    }
     197
     198    /**
     199     * Opens a link using the current {@link BrowserAdapter}.
     200     * @param url link to open
     201     */
    98202    public static void openLink(String url) {
    99203        browserAdapter.openLink(url);
    100204    }
    101205
     206    /**
     207     * Reads an image using the current {@link ImageAdapter}.
     208     * @param url image URL to read
     209     * @return a <code>BufferedImage</code> containing the decoded contents of the input, or <code>null</code>.
     210     * @throws IOException if an error occurs during reading.
     211     */
    102212    public static BufferedImage readImage(URL url) throws IOException {
    103213        return imageAdapter.read(url, false, false);
    104214    }
    105215
     216    /**
     217     * Translates a text using the current {@link TranslationAdapter}.
     218     * @param text the text to translate.
     219     * Must be a string literal. (No constants or local vars.)
     220     * Can be broken over multiple lines.
     221     * An apostrophe ' must be quoted by another apostrophe.
     222     * @param objects the parameters for the string.
     223     * Mark occurrences in {@code text} with <code>{0}</code>, <code>{1}</code>, ...
     224     * @return the translated string.
     225     */
    106226    public static String tr(String text, Object... objects) {
    107227        return translationAdapter.tr(text, objects);
    108228    }
    109229
     230    /**
     231     * Returns a logger for the given name using the current {@link LoggingAdapter}.
     232     * @param name logger name
     233     * @return logger for the given name
     234     */
    110235    public static Logger getLogger(String name) {
    111236        return loggingAdapter.getLogger(name);
    112237    }
    113238
     239    /**
     240     * Returns a logger for the given class using the current {@link LoggingAdapter}.
     241     * @param klass logger class
     242     * @return logger for the given class
     243     */
    114244    public static Logger getLogger(Class<?> klass) {
    115245        return loggingAdapter.getLogger(klass.getSimpleName());
     
    148278    }
    149279
     280    /**
     281     * Default API key support that relies on system property named {@code <imageryId>.api-key}.
     282     */
     283    public static class DefaultApiKeyAdapter implements ApiKeyAdapter {
     284        @Override
     285        public String retrieveApiKey(String imageryId) {
     286            return System.getProperty(imageryId + ".api-key");
     287        }
     288    }
     289
     290    /**
     291     * Default browser support that relies on Java Desktop API.
     292     */
    150293    public static class DefaultBrowserAdapter implements BrowserAdapter {
    151294        @Override
     
    165308    }
    166309
     310    /**
     311     * Default image support that relies on Java Image IO API.
     312     */
    167313    public static class DefaultImageAdapter implements ImageAdapter {
    168314        @Override
     
    172318    }
    173319
     320    /**
     321     * Default "translation" support that do not really translates strings, but only takes care of formatting arguments.
     322     */
    174323    public static class DefaultTranslationAdapter implements TranslationAdapter {
    175324        @Override
     
    179328    }
    180329
     330    /**
     331     * Default logging support that relies on Java Logging API.
     332     */
    181333    public static class DefaultLoggingAdapter implements LoggingAdapter {
    182334        @Override
  • applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java

    r34715 r35320  
    55import java.util.Map;
    66import java.util.Random;
     7import java.util.function.BiConsumer;
    78import java.util.regex.Matcher;
    89import java.util.regex.Pattern;
    910
     11import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
    1012import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
    1113
     
    2527 * {!y} - substituted with Yahoo Y tile number
    2628 * {-y} - substituted with reversed Y tile number
     29 * {apiKey} - substituted with API key retrieved for the imagery id
    2730 * {switch:VAL_A,VAL_B,VAL_C,...} - substituted with one of VAL_A, VAL_B, VAL_C. Usually
    2831 *                                  used to specify many tile servers
     
    4649    private static final Pattern PATTERN_SWITCH  = Pattern.compile("\\{switch:([^}]+)\\}");
    4750    private static final Pattern PATTERN_HEADER  = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)\\}");
     51    private static final Pattern PATTERN_API_KEY = Pattern.compile("\\{apiKey\\}");
    4852    private static final Pattern PATTERN_PARAM  = Pattern.compile("\\{((?:\\d+-)?z(?:oom)?(:?[+-]\\d+)?|x|y|!y|-y|switch:([^}]+))\\}");
    4953    // CHECKSTYLE.ON: SingleSpaceSeparator
    5054
    5155    private static final Pattern[] ALL_PATTERNS = {
    52         PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH
     56        PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH, PATTERN_API_KEY
    5357    };
    5458
     
    6367            headers.put(COOKIE_HEADER, cookies);
    6468        }
    65         handleTemplate();
     69        handleTemplate(info.getId());
    6670    }
    6771
    68     private void handleTemplate() {
     72    private void replacePattern(Pattern p, BiConsumer<Matcher, StringBuffer> replaceAction) {
     73        StringBuffer output = new StringBuffer();
     74        Matcher m = p.matcher(baseUrl);
     75        while (m.find()) {
     76            replaceAction.accept(m, output);
     77        }
     78        m.appendTail(output);
     79        baseUrl = output.toString();
     80    }
     81
     82    private void handleTemplate(String imageryId) {
    6983        // Capturing group pattern on switch values
    7084        Matcher m = PATTERN_SWITCH.matcher(baseUrl);
     
    7387            randomParts = m.group(1).split(",");
    7488        }
    75         StringBuffer output = new StringBuffer();
    76         Matcher matcher = PATTERN_HEADER.matcher(baseUrl);
    77         while (matcher.find()) {
     89        // Capturing group pattern on header values
     90        replacePattern(PATTERN_HEADER, (matcher, output) -> {
    7891            headers.put(matcher.group(1), matcher.group(2));
    7992            matcher.appendReplacement(output, "");
    80         }
    81         matcher.appendTail(output);
    82         baseUrl = output.toString();
    83         m = PATTERN_ZOOM.matcher(this.baseUrl);
     93        });
     94        // Capturing group pattern on API key values
     95        replacePattern(PATTERN_API_KEY, (matcher, output) ->
     96            matcher.appendReplacement(output, FeatureAdapter.retrieveApiKey(imageryId))
     97        );
     98        // Capturing group pattern on zoom values
     99        m = PATTERN_ZOOM.matcher(baseUrl);
    84100        if (m.find()) {
    85101            if (m.group(1) != null) {
     
    94110            }
    95111        }
    96 
    97112    }
    98113
Note: See TracChangeset for help on using the changeset viewer.