001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.imagery;
003
004import static org.openstreetmap.josm.tools.I18n.marktr;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.util.Arrays;
008import java.util.Map;
009import java.util.Objects;
010import java.util.regex.Matcher;
011import java.util.regex.Pattern;
012
013/**
014 * Patterns that can be replaced in imagery URLs.
015 * @since 17578
016 */
017public final class ImageryPatterns {
018
019    // CHECKSTYLE.OFF: SingleSpaceSeparator
020    static final Pattern PATTERN_HEADER = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)\\}");
021    static final Pattern PATTERN_PROJ   = Pattern.compile("\\{proj\\}");
022    static final Pattern PATTERN_WKID   = Pattern.compile("\\{wkid\\}");
023    static final Pattern PATTERN_BBOX   = Pattern.compile("\\{bbox\\}");
024    static final Pattern PATTERN_W      = Pattern.compile("\\{w\\}");
025    static final Pattern PATTERN_S      = Pattern.compile("\\{s\\}");
026    static final Pattern PATTERN_E      = Pattern.compile("\\{e\\}");
027    static final Pattern PATTERN_N      = Pattern.compile("\\{n\\}");
028    static final Pattern PATTERN_WIDTH  = Pattern.compile("\\{width\\}");
029    static final Pattern PATTERN_HEIGHT = Pattern.compile("\\{height\\}");
030    static final Pattern PATTERN_TIME   = Pattern.compile("\\{time\\}"); // Sentinel-2
031    static final Pattern PATTERN_PARAM  = Pattern.compile("\\{([^}]+)\\}");
032    // CHECKSTYLE.ON: SingleSpaceSeparator
033
034    private static final Pattern[] ALL_WMS_PATTERNS = {
035            PATTERN_HEADER, PATTERN_PROJ, PATTERN_WKID, PATTERN_BBOX,
036            PATTERN_W, PATTERN_S, PATTERN_E, PATTERN_N,
037            PATTERN_WIDTH, PATTERN_HEIGHT, PATTERN_TIME
038    };
039
040    private static final Pattern[] ALL_WMTS_PATTERNS = {
041            PATTERN_HEADER
042    };
043
044    private ImageryPatterns() {
045        // Hide public constructor
046    }
047
048    private static void checkUrlPatterns(String url, Pattern[] allPatterns, String errMessage) {
049        Matcher m = PATTERN_PARAM.matcher(Objects.requireNonNull(url, "url"));
050        while (m.find()) {
051            if (Arrays.stream(allPatterns).noneMatch(pattern -> pattern.matcher(m.group()).matches())) {
052                throw new IllegalArgumentException(tr(errMessage, m.group(), url));
053            }
054        }
055    }
056
057    static void checkWmsUrlPatterns(String url) {
058        checkUrlPatterns(url, ALL_WMS_PATTERNS,
059                marktr("{0} is not a valid WMS argument. Please check this server URL:\n{1}"));
060    }
061
062    static void checkWmtsUrlPatterns(String url) {
063        checkUrlPatterns(url, ALL_WMTS_PATTERNS,
064                marktr("{0} is not a valid WMTS argument. Please check this server URL:\n{1}"));
065    }
066
067    static String handleHeaderTemplate(String url, Map<String, String> headers) {
068        StringBuffer output = new StringBuffer();
069        Matcher matcher = PATTERN_HEADER.matcher(url);
070        while (matcher.find()) {
071            headers.put(matcher.group(1), matcher.group(2));
072            matcher.appendReplacement(output, "");
073        }
074        matcher.appendTail(output);
075        return output.toString();
076    }
077}