001
002package io.vrap.rmf.base.client;
003
004import java.util.ArrayList;
005import java.util.Arrays;
006import java.util.List;
007import java.util.Map;
008import java.util.stream.Collectors;
009
010import javax.annotation.Nullable;
011
012import org.apache.commons.lang3.builder.EqualsBuilder;
013import org.apache.commons.lang3.builder.HashCodeBuilder;
014
015public class ApiHttpHeaders extends Base {
016
017    public static class StringHeaderEntry extends HeaderEntry<String, String> {
018        public StringHeaderEntry(final String key) {
019            super(key);
020        }
021
022        public StringHeaderEntry(final String key, final String value) {
023            super(key, value);
024        }
025    }
026
027    public static class HeaderEntry<K, V> extends Base implements Map.Entry<K, V> {
028        protected final K key;
029        protected V value;
030
031        public HeaderEntry(final K key) {
032            this.key = key;
033        }
034
035        public HeaderEntry(final K key, final V value) {
036            this.key = key;
037            this.value = value;
038        }
039
040        @Override
041        public K getKey() {
042            return key;
043        }
044
045        @Override
046        public V getValue() {
047            return value;
048        }
049
050        @Override
051        public V setValue(final V value) {
052            V oldValue = this.value;
053            this.value = value;
054            return oldValue;
055        }
056
057        @Override
058        public String toString() {
059            if (key.toString().equalsIgnoreCase(AUTHORIZATION)) {
060                return "{key=" + key + ", value=**removed from output**}";
061            }
062            return "{" + "key=" + key + ", value=" + value + '}';
063        }
064
065        @Override
066        public boolean equals(Object o) {
067            if (this == o)
068                return true;
069
070            if (o == null || getClass() != o.getClass())
071                return false;
072
073            HeaderEntry<?, ?> that = (HeaderEntry<?, ?>) o;
074
075            return new EqualsBuilder().append(key, that.key).append(value, that.value).isEquals();
076        }
077
078        @Override
079        public int hashCode() {
080            return new HashCodeBuilder(17, 37).append(key).append(value).toHashCode();
081        }
082    }
083
084    public static StringHeaderEntry headerEntry(final String key) {
085        return new StringHeaderEntry(key);
086    }
087
088    public static StringHeaderEntry headerEntry(final String key, final String value) {
089        return new StringHeaderEntry(key, value);
090    }
091
092    public static final String ACCEPT_ENCODING = "Accept-Encoding";
093    public static final String AUTHORIZATION = "Authorization";
094    public static final String USER_AGENT = "User-Agent";
095    public static final String CONTENT_ENCODING = "Content-Encoding";
096    public static final String CONTENT_TYPE = "Content-Type";
097    public static final String CONTENT_LENGTH = "Content-Length";
098    public static final String X_CORRELATION_ID = "X-Correlation-ID";
099    public static final String X_DEPRECATION_NOTICE = "X-Deprecation-Notice";
100    public static final String SERVER_TIMING = "Server-Timing";
101
102    private final List<StringHeaderEntry> headers;
103
104    public ApiHttpHeaders() {
105        this.headers = new ArrayList<>();
106    }
107
108    public ApiHttpHeaders(final StringHeaderEntry... headers) {
109        this.headers = new ArrayList<>(Arrays.asList(headers));
110    }
111
112    public ApiHttpHeaders(final List<Map.Entry<String, String>> headers) {
113        this.headers = mapToHeaderEntries(headers);
114    }
115
116    public ApiHttpHeaders(final ApiHttpHeaders t) {
117        this.headers = new ArrayList<>(t.headers);
118    }
119
120    public ApiHttpHeaders addHeader(final String key, final String value) {
121        ApiHttpHeaders headers = copy();
122        headers.headers.add(headerEntry(key, value));
123
124        return headers;
125    }
126
127    public ApiHttpHeaders withHeader(final String key, final String value) {
128        ApiHttpHeaders headers = withoutHeader(key);
129        headers.headers.add(headerEntry(key, value));
130        return headers;
131    }
132
133    public final ApiHttpHeaders withHeaders(final StringHeaderEntry... headers) {
134        return new ApiHttpHeaders(new ArrayList<>(Arrays.asList(headers)));
135    }
136
137    public ApiHttpHeaders withHeaders(final List<Map.Entry<String, String>> headers) {
138        return new ApiHttpHeaders(headers);
139    }
140
141    public ApiHttpHeaders withoutHeader(final String key) {
142        return withHeaders(
143            headers.stream().filter(e -> !e.getKey().equalsIgnoreCase(key)).collect(Collectors.toList()));
144    }
145
146    @Nullable
147    public String getFirst(final String key) {
148        return this.headers.stream()
149                .filter(e -> e.getKey().equalsIgnoreCase(key))
150                .map(Map.Entry::getValue)
151                .findFirst()
152                .orElse(null);
153    }
154
155    public List<String> getHeaderValue(final String key) {
156        return headers.stream()
157                .filter(e -> e.getKey().equalsIgnoreCase(key))
158                .map(Map.Entry::getValue)
159                .collect(Collectors.toList());
160    }
161
162    public List<Map.Entry<String, String>> getHeaders(final String key) {
163        return headers.stream().filter(e -> e.getKey().equalsIgnoreCase(key)).collect(Collectors.toList());
164    }
165
166    public List<Map.Entry<String, String>> getHeaders() {
167        return new ArrayList<>(headers);
168    }
169
170    @Override
171    public String toString() {
172        return headers.toString();
173    }
174
175    private ApiHttpHeaders copy() {
176        return new ApiHttpHeaders(this);
177    }
178
179    private static List<StringHeaderEntry> mapToHeaderEntries(final List<Map.Entry<String, String>> entries) {
180        return entries.stream().map(ApiHttpHeaders::mapToHeaderEntry).collect(Collectors.toList());
181    }
182
183    private static StringHeaderEntry mapToHeaderEntry(final Map.Entry<String, String> entry) {
184        if (entry instanceof StringHeaderEntry) {
185            return (StringHeaderEntry) entry;
186        }
187        return headerEntry(entry.getKey(), entry.getValue());
188    }
189
190    @Override
191    public boolean equals(Object o) {
192        if (this == o)
193            return true;
194
195        if (o == null || getClass() != o.getClass())
196            return false;
197
198        ApiHttpHeaders headers1 = (ApiHttpHeaders) o;
199
200        return new EqualsBuilder().append(headers, headers1.headers).isEquals();
201    }
202
203    @Override
204    public int hashCode() {
205        return new HashCodeBuilder(17, 37).append(headers).toHashCode();
206    }
207}