All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.davidmoten.odata.client.Path Maven / Gradle / Ivy

package com.github.davidmoten.odata.client;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.github.davidmoten.guavamini.Preconditions;

/**
 * Immutable!
 */
public class Path {

    private final String url;
    private final Map queries; // unencoded
    private final PathStyle style;

    // TODO support repeated query keys?
    public Path(String url, Map queries, PathStyle style) {
        this.url = url;
        this.queries = queries;
        this.style = style;
    }

    public Path(String url, PathStyle style) {
        this(url, Collections.emptyMap(), style);
    }

    public PathStyle style() {
        return style;
    }

    private String append(String url, String s) {
        return url + encode(s);
    }

    public Path addSegment(String segment) {
        String u = url;
        u = addSegmentDelimiter(u);
        u = append(u, segment);
        return new Path(u, queries, style);
    }

    private static String addSegmentDelimiter(String url) {
        if (url.charAt(url.length() - 1) != '/') {
            return url + '/';
        } else {
            return url;
        }
    }

    public Path addKeys(NameValue... keys) {
        String u = url;
        if (style == PathStyle.IDENTIFIERS_IN_ROUND_BRACKETS) {
            if (keys.length > 0) {
                u = append(u, "(");
                boolean first = true;
                for (NameValue key : keys) {
                    Preconditions.checkNotNull(key);
                    if (!first) {
                        u = append(u, ",");
                        first = false;
                    }
                    if (keys.length == 1) {
                        u = append(u, key.value());
                    } else {
                        u = append(u, key.name().map(x -> x + "=").orElse("") + key.value());
                    }
                }
                u = append(u, ")");
            }
        } else {
            if (keys.length > 0) {
                for (NameValue key : keys) {
                    Preconditions.checkNotNull(key);
                    u = addSegmentDelimiter(u);
                    u = append(u, key.value());
                }
            }
        }
        return new Path(u, queries, style);
    }

    public Path addQuery(String key, String value) {
        Map map = new LinkedHashMap(queries);
        map.put(key, value);
        return new Path(url, map, style);
    }

    public Path clearQueries() {
        return new Path(url, Collections.emptyMap(), style);
    }

    public String toUrl() {
        StringBuilder b = new StringBuilder();
        b.append(url);
        if (!queries.isEmpty()) {
            b.append("?");
            boolean first = true;
            for (Entry entry : queries.entrySet()) {
                if (!first) {
                    b.append("&");
                }
                first = false;
                b.append(encodeQuery(entry.getKey()));
                b.append("=");
                b.append(encodeQuery(entry.getValue()));
            }
        }
        return b.toString();
    }

    @Override
    public String toString() {
        return toUrl();
    }

    private Object encodeQuery(String query) {
        // can include = legally in query parameters
        return encode(query).replaceAll("\\%3D", "=").replaceAll("\\%24", "\\$");
    }

    private static String encode(String s) {
        try {
            return URLEncoder.encode(s, "UTF-8") //
                    .replaceAll("\\+", "%20") //
                    .replaceAll("\\%21", "!") //
                    .replaceAll("\\%27", "'") //
                    .replaceAll("\\%28", "(") //
                    .replaceAll("\\%29", ")") //
                    .replaceAll("\\%7E", "~");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy