Skip to content

Commit 28c7b38

Browse files
committed
Добавлен модуль http
1 parent 89d48f7 commit 28c7b38

File tree

11 files changed

+241
-1
lines changed

11 files changed

+241
-1
lines changed

libs/commons-codec-1.6.jar

227 KB
Binary file not shown.

libs/commons-logging-1.1.3.jar

60.6 KB
Binary file not shown.

libs/httpclient-4.3.5.jar

577 KB
Binary file not shown.

libs/httpcore-4.3.2.jar

276 KB
Binary file not shown.

program.own

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,15 @@ nums = [1,2,3,4,5,6,7,8,9,10]
124124
nums = filter(nums, def(x) = x % 2 == 0)
125125
squares = map(nums, def(x) = x * x)
126126
foreach(squares, ::echo)
127-
println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
127+
println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
128+
129+
use "http"
130+
131+
http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) {
132+
println "Added: " + v
133+
http("http://jsonplaceholder.typicode.com/users/2", "PATCH", {"name": "Patched Name"}, ::http_get_demo)
134+
})
135+
def http_get_demo(v) {
136+
println "Updated: " + v
137+
http("http://jsonplaceholder.typicode.com/users", ::echo)
138+
}

src/com/annimon/ownlang/lib/FunctionValue.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* @author aNNiMON
88
*/
99
public final class FunctionValue implements Value {
10+
11+
public static final FunctionValue EMPTY = new FunctionValue(args -> NumberValue.ZERO);
1012

1113
private final Function value;
1214

src/com/annimon/ownlang/lib/MapValue.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
*/
1212
public class MapValue implements Value, Iterable<Map.Entry<Value, Value>> {
1313

14+
public static final MapValue EMPTY = new MapValue(1);
15+
1416
private final Map<Value, Value> map;
1517

1618
public MapValue(int size) {
@@ -29,6 +31,10 @@ public int type() {
2931
public int size() {
3032
return map.size();
3133
}
34+
35+
public boolean containsKey(Value key) {
36+
return map.containsKey(key);
37+
}
3238

3339
public Value get(Value key) {
3440
return map.get(key);

src/com/annimon/ownlang/lib/StringValue.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public StringValue(String value) {
1414
this.value = value;
1515
}
1616

17+
public int length() {
18+
return value.length();
19+
}
20+
1721
@Override
1822
public int type() {
1923
return Types.STRING;
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package com.annimon.ownlang.lib.modules.functions;
2+
3+
import com.annimon.ownlang.lib.*;
4+
import java.io.IOException;
5+
import java.io.UnsupportedEncodingException;
6+
import java.nio.charset.UnsupportedCharsetException;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Map;
10+
import org.apache.http.HttpEntity;
11+
import org.apache.http.HttpResponse;
12+
import org.apache.http.NameValuePair;
13+
import org.apache.http.client.entity.UrlEncodedFormEntity;
14+
import org.apache.http.client.methods.*;
15+
import org.apache.http.entity.StringEntity;
16+
import org.apache.http.impl.client.BasicResponseHandler;
17+
import org.apache.http.impl.client.CloseableHttpClient;
18+
import org.apache.http.impl.client.HttpClientBuilder;
19+
import org.apache.http.message.BasicNameValuePair;
20+
21+
public final class http_http implements Function {
22+
23+
private static final Value
24+
HEADER_KEY = new StringValue("header"),
25+
CHARSET_KEY = new StringValue("charset");
26+
27+
@Override
28+
public Value execute(Value... args) {
29+
String url, method;
30+
switch (args.length) {
31+
case 1: // http(url)
32+
url = args[0].asString();
33+
return process(url, "GET");
34+
35+
case 2: // http(url, method) || http(url, callback)
36+
url = args[0].asString();
37+
if (args[1].type() == Types.FUNCTION) {
38+
return process(url, "GET", (FunctionValue) args[1]);
39+
}
40+
return process(url, args[1].asString());
41+
42+
case 3: // http(url, method, params) || http(url, method, callback)
43+
url = args[0].asString();
44+
method = args[1].asString();
45+
if (args[2].type() == Types.FUNCTION) {
46+
return process(url, method, (FunctionValue) args[2]);
47+
}
48+
return process(url, method, args[2], FunctionValue.EMPTY);
49+
50+
case 4: // http(url, method, params, callback)
51+
if (args[3].type() != Types.FUNCTION) {
52+
throw new RuntimeException("Fourth arg must be a function callback");
53+
}
54+
url = args[0].asString();
55+
method = args[1].asString();
56+
return process(url, method, args[2], (FunctionValue) args[3]);
57+
58+
case 5: // http(url, method, params, headerParams, callback)
59+
if (args[3].type() != Types.MAP) {
60+
throw new RuntimeException("Third arg must be a map");
61+
}
62+
if (args[4].type() != Types.FUNCTION) {
63+
throw new RuntimeException("Fifth arg must be a function callback");
64+
}
65+
url = args[0].asString();
66+
method = args[1].asString();
67+
return process(url, method, args[2], (MapValue) args[3], (FunctionValue) args[4]);
68+
69+
default:
70+
throw new RuntimeException("Wrong number of arguments");
71+
}
72+
}
73+
74+
private Value process(String url, String method) {
75+
return process(url, method, FunctionValue.EMPTY);
76+
}
77+
78+
private Value process(String url, String method, FunctionValue function) {
79+
return process(url, method, MapValue.EMPTY, function);
80+
}
81+
82+
private Value process(String url, String method, Value params, FunctionValue function) {
83+
return process(url, method, params, MapValue.EMPTY, function);
84+
}
85+
86+
private Value process(String url, String method, Value requestParams, MapValue options, FunctionValue function) {
87+
final Function callback = function.getValue();
88+
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
89+
HttpRequestBase httpMethod;
90+
switch (method.toUpperCase()) {
91+
case "POST":
92+
httpMethod = new HttpPost(url);
93+
break;
94+
case "PUT":
95+
httpMethod = new HttpPut(url);
96+
break;
97+
case "DELETE":
98+
httpMethod = new HttpDelete(url);
99+
break;
100+
case "PATCH":
101+
httpMethod = new HttpPatch(url);
102+
break;
103+
case "HEAD":
104+
httpMethod = new HttpHead(url);
105+
break;
106+
case "OPTIONS":
107+
httpMethod = new HttpOptions(url);
108+
break;
109+
case "TRACE":
110+
httpMethod = new HttpTrace(url);
111+
break;
112+
case "GET":
113+
default:
114+
httpMethod = new HttpGet(url);
115+
break;
116+
}
117+
118+
if (options.containsKey(HEADER_KEY)) {
119+
applyHeaderParams((MapValue) options.get(HEADER_KEY), httpMethod);
120+
}
121+
122+
if (httpMethod instanceof HttpEntityEnclosingRequestBase) {
123+
final HttpEntityEnclosingRequestBase heerb = (HttpEntityEnclosingRequestBase) httpMethod;
124+
if (requestParams.type() == Types.MAP) {
125+
applyMapRequestParams(heerb, (MapValue) requestParams, options);
126+
} else {
127+
applyStringRequestParams(heerb, requestParams, options);
128+
}
129+
}
130+
131+
final HttpResponse httpResponse = httpClient.execute(httpMethod);
132+
final String response = new BasicResponseHandler().handleResponse(httpResponse);
133+
callback.execute(new StringValue(response));
134+
return NumberValue.fromBoolean(true);
135+
} catch (IOException ex) {
136+
return NumberValue.fromBoolean(false);
137+
}
138+
}
139+
140+
private void applyHeaderParams(MapValue headerParams, HttpRequestBase httpMethod) {
141+
for (Map.Entry<Value, Value> p : headerParams) {
142+
httpMethod.addHeader(p.getKey().asString(), p.getValue().asString());
143+
}
144+
}
145+
146+
private void applyMapRequestParams(HttpEntityEnclosingRequestBase h, MapValue params, MapValue options)
147+
throws UnsupportedEncodingException {
148+
final List<NameValuePair> entityParams = new ArrayList<>(params.size());
149+
for (Map.Entry<Value, Value> param : params) {
150+
final String name = param.getKey().asString();
151+
final String value = param.getValue().asString();
152+
entityParams.add(new BasicNameValuePair(name, value));
153+
}
154+
HttpEntity entity;
155+
if (options.containsKey(CHARSET_KEY)) {
156+
entity = new UrlEncodedFormEntity(entityParams, options.get(CHARSET_KEY).asString());
157+
} else {
158+
entity = new UrlEncodedFormEntity(entityParams);
159+
}
160+
h.setEntity(entity);
161+
}
162+
163+
private void applyStringRequestParams(final HttpEntityEnclosingRequestBase heerb, Value requestParams, MapValue options) throws UnsupportedEncodingException, UnsupportedCharsetException {
164+
HttpEntity entity;
165+
if (options.containsKey(CHARSET_KEY)) {
166+
entity = new StringEntity(requestParams.asString(), options.get(CHARSET_KEY).asString());
167+
} else {
168+
entity = new StringEntity(requestParams.asString());
169+
}
170+
heerb.setEntity(entity);
171+
}
172+
173+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.annimon.ownlang.lib.modules.functions;
2+
3+
import com.annimon.ownlang.lib.Function;
4+
import com.annimon.ownlang.lib.StringValue;
5+
import com.annimon.ownlang.lib.Value;
6+
import java.io.IOException;
7+
import java.net.URLEncoder;
8+
9+
public final class http_urlencode implements Function {
10+
11+
@Override
12+
public Value execute(Value... args) {
13+
if (args.length == 0) throw new RuntimeException("At least one arg expected");
14+
15+
String charset = "UTF-8";
16+
if (args.length >= 2) {
17+
charset = args[1].asString();
18+
}
19+
20+
try {
21+
final String result = URLEncoder.encode(args[0].asString(), charset);
22+
return new StringValue(result);
23+
} catch (IOException ex) {
24+
return args[0];
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)