1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.incubator.http;
27
28import java.net.URI;
29import jdk.incubator.http.HttpRequest.BodyProcessor;
30import java.time.Duration;
31import java.util.Optional;
32import static java.util.Objects.requireNonNull;
33import jdk.incubator.http.internal.common.HttpHeadersImpl;
34import static jdk.incubator.http.internal.common.Utils.isValidName;
35import static jdk.incubator.http.internal.common.Utils.isValidValue;
36
37class HttpRequestBuilderImpl extends HttpRequest.Builder {
38
39    private HttpHeadersImpl userHeaders;
40    private URI uri;
41    private String method;
42    //private HttpClient.Redirect followRedirects;
43    private boolean expectContinue;
44    private HttpRequest.BodyProcessor body;
45    private volatile Optional<HttpClient.Version> version;
46    //private final HttpClientImpl client;
47    //private ProxySelector proxy;
48    private Duration duration;
49
50    public HttpRequestBuilderImpl(URI uri) {
51        //this.client = client;
52        checkURI(uri);
53        this.uri = uri;
54        this.userHeaders = new HttpHeadersImpl();
55        this.method = "GET"; // default, as per spec
56        this.version = Optional.empty();
57    }
58
59    public HttpRequestBuilderImpl() {
60        this.userHeaders = new HttpHeadersImpl();
61        this.version = Optional.empty();
62    }
63
64    @Override
65    public HttpRequestBuilderImpl uri(URI uri) {
66        requireNonNull(uri);
67        checkURI(uri);
68        this.uri = uri;
69        return this;
70    }
71
72    private static void checkURI(URI uri) {
73        String scheme = uri.getScheme().toLowerCase();
74        if (!scheme.equals("https") && !scheme.equals("http")) {
75            throw new IllegalArgumentException("invalid URI scheme");
76        }
77    }
78/*
79    @Override
80    public HttpRequestBuilderImpl followRedirects(HttpClient.Redirect follow) {
81        requireNonNull(follow);
82        this.followRedirects = follow;
83        return this;
84    }
85*/
86    @Override
87    public HttpRequestBuilderImpl header(String name, String value) {
88        checkNameAndValue(name, value);
89        userHeaders.addHeader(name, value);
90        return this;
91    }
92
93    @Override
94    public HttpRequestBuilderImpl headers(String... params) {
95        requireNonNull(params);
96        if (params.length % 2 != 0) {
97            throw new IllegalArgumentException("wrong number of parameters");
98        }
99        for (int i = 0; i < params.length; i += 2) {
100            String name  = params[i];
101            String value = params[i + 1];
102            header(name, value);
103        }
104        return this;
105    }
106
107    /*
108    @Override
109    public HttpRequestBuilderImpl proxy(ProxySelector proxy) {
110        requireNonNull(proxy);
111        this.proxy = proxy;
112        return this;
113    }
114*/
115    @Override
116    public HttpRequestBuilderImpl copy() {
117        HttpRequestBuilderImpl b = new HttpRequestBuilderImpl(this.uri);
118        b.userHeaders = this.userHeaders.deepCopy();
119        b.method = this.method;
120        //b.followRedirects = this.followRedirects;
121        b.expectContinue = this.expectContinue;
122        b.body = body;
123        b.uri = uri;
124        //b.proxy = proxy;
125        return b;
126    }
127
128    @Override
129    public HttpRequestBuilderImpl setHeader(String name, String value) {
130        checkNameAndValue(name, value);
131        userHeaders.setHeader(name, value);
132        return this;
133    }
134
135    private void checkNameAndValue(String name, String value) {
136        requireNonNull(name, "name");
137        requireNonNull(value, "value");
138        if (!isValidName(name)) {
139            throw new IllegalArgumentException("invalid header name");
140        }
141        if (!isValidValue(value)) {
142            throw new IllegalArgumentException("invalid header value");
143        }
144    }
145
146    @Override
147    public HttpRequestBuilderImpl expectContinue(boolean enable) {
148        expectContinue = enable;
149        return this;
150    }
151
152    @Override
153    public HttpRequestBuilderImpl version(HttpClient.Version version) {
154        requireNonNull(version);
155        this.version = Optional.of(version);
156        return this;
157    }
158
159    HttpHeadersImpl headers() {  return userHeaders; }
160
161    //HttpClientImpl client() {return client;}
162
163    URI uri() { return uri; }
164
165    String method() { return method; }
166
167    //HttpClient.Redirect followRedirects() { return followRedirects; }
168
169    //ProxySelector proxy() { return proxy; }
170
171    boolean expectContinue() { return expectContinue; }
172
173    public HttpRequest.BodyProcessor body() { return body; }
174
175    Optional<HttpClient.Version> version() { return version; }
176
177    @Override
178    public HttpRequest.Builder GET() { return method("GET", null); }
179
180    @Override
181    public HttpRequest.Builder POST(BodyProcessor body) {
182        return method("POST", body);
183    }
184
185    @Override
186    public HttpRequest.Builder DELETE(BodyProcessor body) {
187        return method("DELETE", body);
188    }
189
190    @Override
191    public HttpRequest.Builder PUT(BodyProcessor body) {
192        return method("PUT", body);
193    }
194
195    @Override
196    public HttpRequest.Builder method(String method, BodyProcessor body) {
197        this.method = requireNonNull(method);
198        this.body = body;
199        return this;
200    }
201
202    @Override
203    public HttpRequest build() {
204        return new HttpRequestImpl(this);
205    }
206
207    @Override
208    public HttpRequest.Builder timeout(Duration duration) {
209        requireNonNull(duration);
210        if (duration.isNegative() || Duration.ZERO.equals(duration))
211            throw new IllegalArgumentException("Invalid duration: " + duration);
212        this.duration = duration;
213        return this;
214    }
215
216    Duration duration() { return duration; }
217
218}
219