mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Добавлен модуль okhttp
This commit is contained in:
parent
d72fad6de3
commit
23ed9e6d04
285
build.gradle
285
build.gradle
@ -1,143 +1,144 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'net.sf.proguard:proguard-gradle:6.0.1'
|
classpath 'net.sf.proguard:proguard-gradle:6.0.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "com.github.johnrengelman.shadow" version "2.0.2"
|
id "com.github.johnrengelman.shadow" version "2.0.2"
|
||||||
id "org.sonarqube" version "2.6.2"
|
id "org.sonarqube" version "2.6.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
import proguard.gradle.ProGuardTask
|
import proguard.gradle.ProGuardTask
|
||||||
|
|
||||||
|
|
||||||
sourceCompatibility = '1.8'
|
sourceCompatibility = '1.8'
|
||||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||||
|
|
||||||
if (!hasProperty('mainClass')) {
|
if (!hasProperty('mainClass')) {
|
||||||
ext.mainClass = 'com.annimon.ownlang.Main'
|
ext.mainClass = 'com.annimon.ownlang.Main'
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.generatedJavaDir = "${rootProject.projectDir}/src/main/generatedJava"
|
ext.generatedJavaDir = "${rootProject.projectDir}/src/main/generatedJava"
|
||||||
sourceSets.main.java.srcDirs += project.generatedJavaDir
|
sourceSets.main.java.srcDirs += project.generatedJavaDir
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
task generateJavaSources() {
|
task generateJavaSources() {
|
||||||
doLast {
|
doLast {
|
||||||
def source = """
|
def source = """
|
||||||
package com.annimon.ownlang;
|
package com.annimon.ownlang;
|
||||||
class Gen {
|
class Gen {
|
||||||
private Gen() {}
|
private Gen() {}
|
||||||
public static final String BUILD_DATE = "${new Date().format('YYMMdd')}";
|
public static final String BUILD_DATE = "${new Date().format('YYMMdd')}";
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
def genFile = new File("${project.generatedJavaDir}/com/annimon/ownlang/Gen.java")
|
def genFile = new File("${project.generatedJavaDir}/com/annimon/ownlang/Gen.java")
|
||||||
genFile.getParentFile().mkdirs()
|
genFile.getParentFile().mkdirs()
|
||||||
genFile.write(source)
|
genFile.write(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileJava.dependsOn(generateJavaSources)
|
compileJava.dependsOn(generateJavaSources)
|
||||||
|
|
||||||
task run(dependsOn: classes, type: JavaExec) {
|
task run(dependsOn: classes, type: JavaExec) {
|
||||||
main = project.mainClass
|
main = project.mainClass
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
standardInput = System.in
|
standardInput = System.in
|
||||||
ignoreExitValue = true
|
ignoreExitValue = true
|
||||||
}
|
}
|
||||||
|
|
||||||
task runOptimizing(dependsOn: classes, type: JavaExec) {
|
task runOptimizing(dependsOn: classes, type: JavaExec) {
|
||||||
main = project.mainClass
|
main = project.mainClass
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
ignoreExitValue = true
|
ignoreExitValue = true
|
||||||
// args '-o 9 -m -a -f examples/game/minesweeper.own'.split(' ')
|
// args '-o 9 -m -a -f examples/game/minesweeper.own'.split(' ')
|
||||||
args '-o 9 -m -a -f program.own'.split(' ')
|
args '-o 9 -m -a -f program.own'.split(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
task dist(type: ShadowJar) {
|
task dist(type: ShadowJar) {
|
||||||
from sourceSets.main.output
|
from sourceSets.main.output
|
||||||
configurations = [project.configurations.runtime]
|
configurations = [project.configurations.runtime]
|
||||||
destinationDir file("$rootProject.projectDir/dist")
|
destinationDir file("$rootProject.projectDir/dist")
|
||||||
|
|
||||||
exclude 'META-INF/*.DSA'
|
exclude 'META-INF/*.DSA'
|
||||||
exclude 'META-INF/*.RSA'
|
exclude 'META-INF/*.RSA'
|
||||||
exclude 'META-INF/maven/**'
|
exclude 'META-INF/maven/**'
|
||||||
exclude 'LICENSE*'
|
exclude 'LICENSE*'
|
||||||
|
|
||||||
manifest.attributes(
|
manifest.attributes(
|
||||||
'Main-Class': project.mainClass,
|
'Main-Class': project.mainClass,
|
||||||
'Build-Date': new Date().format('YYMMdd')
|
'Build-Date': new Date().format('YYMMdd')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
task proguard(dependsOn: dist, type: ProGuardTask) {
|
task proguard(dependsOn: dist, type: ProGuardTask) {
|
||||||
configuration "$rootProject.projectDir/proguard.properties"
|
configuration "$rootProject.projectDir/proguard.properties"
|
||||||
injars "$rootProject.projectDir/dist/OwnLang.jar"
|
injars "$rootProject.projectDir/dist/OwnLang.jar"
|
||||||
outjars "$rootProject.projectDir/store/OwnLang.jar"
|
outjars "$rootProject.projectDir/store/OwnLang.jar"
|
||||||
|
|
||||||
// Automatically handle the Java version of this build.
|
// Automatically handle the Java version of this build.
|
||||||
if (System.getProperty('java.version').startsWith('1.')) {
|
if (System.getProperty('java.version').startsWith('1.')) {
|
||||||
// Before Java 9, the runtime classes were packaged in a single jar file.
|
// Before Java 9, the runtime classes were packaged in a single jar file.
|
||||||
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
||||||
} else {
|
} else {
|
||||||
// As of Java 9, the runtime classes are packaged in modular jmod files.
|
// As of Java 9, the runtime classes are packaged in modular jmod files.
|
||||||
def jmods = files { file("${System.getProperty('java.home')}/jmods").listFiles() }
|
def jmods = files { file("${System.getProperty('java.home')}/jmods").listFiles() }
|
||||||
jmods.each {
|
jmods.each {
|
||||||
libraryjars it, jarfilter: '!**.jar', filter: '!module-info.class'
|
libraryjars it, jarfilter: '!**.jar', filter: '!module-info.class'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task sandbox(dependsOn: proguard, type: Jar) {
|
task sandbox(dependsOn: proguard, type: Jar) {
|
||||||
from zipTree("$rootProject.projectDir/store/OwnLang.jar")
|
from zipTree("$rootProject.projectDir/store/OwnLang.jar")
|
||||||
libsDirName = "$rootProject.projectDir/store"
|
libsDirName = "$rootProject.projectDir/store"
|
||||||
appendix = "Sandbox"
|
appendix = "Sandbox"
|
||||||
|
|
||||||
exclude "**/modules/canvas/**", "**/modules/canvasfx/**", "**/modules/forms/**",
|
exclude "**/modules/canvas/**", "**/modules/canvasfx/**", "**/modules/forms/**",
|
||||||
"**/modules/java/**", "**/modules/jdbc/**", "**/modules/robot/**",
|
"**/modules/java/**", "**/modules/jdbc/**", "**/modules/robot/**",
|
||||||
"**/modules/socket/**", "io/**",
|
"**/modules/okhttp/**",
|
||||||
"**/modules/aimp/**", "aimpremote/**",
|
"**/modules/socket/**", "io/**",
|
||||||
"**/modules/downloader/**",
|
"**/modules/aimp/**", "aimpremote/**",
|
||||||
"**/modules/zip/**", "**/modules/gzip/**",
|
"**/modules/downloader/**",
|
||||||
"jline/**", "org/fusesource/**", "META-INF/native/**"
|
"**/modules/zip/**", "**/modules/gzip/**",
|
||||||
|
"jline/**", "org/fusesource/**", "META-INF/native/**"
|
||||||
manifest {
|
|
||||||
attributes 'Main-Class': project.mainClass
|
manifest {
|
||||||
}
|
attributes 'Main-Class': project.mainClass
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dependencies {
|
|
||||||
compile ('io.socket:socket.io-client:1.0.0') {
|
dependencies {
|
||||||
exclude group: 'org.json', module: 'json'
|
compile ('io.socket:socket.io-client:1.0.0') {
|
||||||
}
|
exclude group: 'org.json', module: 'json'
|
||||||
compile 'org.json:json:20180130'
|
}
|
||||||
compile 'org.yaml:snakeyaml:1.20'
|
compile 'org.json:json:20180130'
|
||||||
compile 'jline:jline:2.14.5'
|
compile 'org.yaml:snakeyaml:1.20'
|
||||||
|
compile 'jline:jline:2.14.5'
|
||||||
testImplementation 'junit:junit:4.12'
|
|
||||||
testImplementation 'org.openjdk.jmh:jmh-core:1.13'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.13'
|
testImplementation 'org.openjdk.jmh:jmh-core:1.13'
|
||||||
}
|
testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.13'
|
||||||
|
}
|
||||||
sonarqube {
|
|
||||||
properties {
|
sonarqube {
|
||||||
property "sonar.projectName", "Own-Programming-Language-Tutorial"
|
properties {
|
||||||
property "sonar.projectKey", "aNNiMON_Own-Programming-Language-Tutorial"
|
property "sonar.projectName", "Own-Programming-Language-Tutorial"
|
||||||
property "sonar.host.url", "https://sonarcloud.io"
|
property "sonar.projectKey", "aNNiMON_Own-Programming-Language-Tutorial"
|
||||||
}
|
property "sonar.host.url", "https://sonarcloud.io"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
test {
|
|
||||||
testLogging {
|
test {
|
||||||
events "passed", "skipped", "failed"
|
testLogging {
|
||||||
exceptionFormat "full"
|
events "passed", "skipped", "failed"
|
||||||
}
|
exceptionFormat "full"
|
||||||
|
}
|
||||||
}
|
}
|
17
examples/network/okhttp_imgur_upload.own
Normal file
17
examples/network/okhttp_imgur_upload.own
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use ["std", "okhttp"]
|
||||||
|
|
||||||
|
// https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java
|
||||||
|
|
||||||
|
println okhttp.request()
|
||||||
|
.header("Authorization", "Client-ID 9199fdef135c122")
|
||||||
|
.url("https://api.imgur.com/3/image")
|
||||||
|
.post(MultipartBody.builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart("title", "Sample image")
|
||||||
|
.addFormDataPart("image", "image.png", RequestBody.file("image/png", "image.png"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.newCall(okhttp.client)
|
||||||
|
.execute()
|
||||||
|
.body()
|
||||||
|
.string()
|
20
examples/network/okhttp_telegram_sendvoice.own
Normal file
20
examples/network/okhttp_telegram_sendvoice.own
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use ["std", "okhttp"]
|
||||||
|
|
||||||
|
TOKEN = "your bot token"
|
||||||
|
|
||||||
|
println okhttp.request()
|
||||||
|
.url("https://api.telegram.org/bot" + TOKEN + "/sendVoice")
|
||||||
|
.post(MultipartBody.builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormData({
|
||||||
|
"chat_id": "-1001100000123",
|
||||||
|
"caption": "sample text"
|
||||||
|
})
|
||||||
|
.addFormDataPart("voice", "file.ogg",
|
||||||
|
RequestBody.file("audio/ogg", "voice.ogg"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.newCall(okhttp.client)
|
||||||
|
.execute()
|
||||||
|
.body()
|
||||||
|
.string()
|
20
examples/network/okhttp_websocket.own
Normal file
20
examples/network/okhttp_websocket.own
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use ["std", "okhttp"]
|
||||||
|
|
||||||
|
// https://github.com/square/okhttp/blob/b21ed68c08c2a5c1eb0bbe93a6f720d1aa2820da/samples/guide/src/main/java/okhttp3/recipes/WebSocketEcho.java
|
||||||
|
|
||||||
|
okhttp.client.newWebSocket(
|
||||||
|
okhttp.request().url("ws://echo.websocket.org"),
|
||||||
|
{
|
||||||
|
"onOpen": def(ws, resp) {
|
||||||
|
ws.send("Hello...")
|
||||||
|
ws.send("...World!")
|
||||||
|
ws.close(1000, "Goodbye, World!")
|
||||||
|
},
|
||||||
|
"onTextMessage": def(ws, text) = echo(text),
|
||||||
|
"onBytesMessage": def(ws, bytes) = echo(bytes),
|
||||||
|
"onClosing": def(ws, code, reason) {
|
||||||
|
ws.close(1000)
|
||||||
|
echo("CLOSE:", code, reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
@ -1,129 +1,133 @@
|
|||||||
package com.annimon.ownlang.lib;
|
package com.annimon.ownlang.lib;
|
||||||
|
|
||||||
import com.annimon.ownlang.exceptions.TypeException;
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public final class ValueUtils {
|
public final class ValueUtils {
|
||||||
|
|
||||||
private ValueUtils() { }
|
private ValueUtils() { }
|
||||||
|
|
||||||
public static Object toObject(Value val) {
|
public static Object toObject(Value val) {
|
||||||
switch (val.type()) {
|
switch (val.type()) {
|
||||||
case Types.ARRAY:
|
case Types.ARRAY:
|
||||||
return toObject((ArrayValue) val);
|
return toObject((ArrayValue) val);
|
||||||
case Types.MAP:
|
case Types.MAP:
|
||||||
return toObject((MapValue) val);
|
return toObject((MapValue) val);
|
||||||
case Types.NUMBER:
|
case Types.NUMBER:
|
||||||
return val.raw();
|
return val.raw();
|
||||||
case Types.STRING:
|
case Types.STRING:
|
||||||
return val.asString();
|
return val.asString();
|
||||||
default:
|
default:
|
||||||
return JSONObject.NULL;
|
return JSONObject.NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object toObject(MapValue map) {
|
public static Object toObject(MapValue map) {
|
||||||
final JSONObject result = new JSONObject();
|
final JSONObject result = new JSONObject();
|
||||||
for (Map.Entry<Value, Value> entry : map) {
|
for (Map.Entry<Value, Value> entry : map) {
|
||||||
final String key = entry.getKey().asString();
|
final String key = entry.getKey().asString();
|
||||||
final Object value = toObject(entry.getValue());
|
final Object value = toObject(entry.getValue());
|
||||||
result.put(key, value);
|
result.put(key, value);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object toObject(ArrayValue array) {
|
public static Object toObject(ArrayValue array) {
|
||||||
final JSONArray result = new JSONArray();
|
final JSONArray result = new JSONArray();
|
||||||
for (Value value : array) {
|
for (Value value : array) {
|
||||||
result.put(toObject(value));
|
result.put(toObject(value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Value toValue(Object obj) {
|
public static Value toValue(Object obj) {
|
||||||
if (obj instanceof JSONObject) {
|
if (obj instanceof JSONObject) {
|
||||||
return toValue((JSONObject) obj);
|
return toValue((JSONObject) obj);
|
||||||
}
|
}
|
||||||
if (obj instanceof JSONArray) {
|
if (obj instanceof JSONArray) {
|
||||||
return toValue((JSONArray) obj);
|
return toValue((JSONArray) obj);
|
||||||
}
|
}
|
||||||
if (obj instanceof String) {
|
if (obj instanceof String) {
|
||||||
return new StringValue((String) obj);
|
return new StringValue((String) obj);
|
||||||
}
|
}
|
||||||
if (obj instanceof Number) {
|
if (obj instanceof Number) {
|
||||||
return NumberValue.of(((Number) obj));
|
return NumberValue.of(((Number) obj));
|
||||||
}
|
}
|
||||||
if (obj instanceof Boolean) {
|
if (obj instanceof Boolean) {
|
||||||
return NumberValue.fromBoolean((Boolean) obj);
|
return NumberValue.fromBoolean((Boolean) obj);
|
||||||
}
|
}
|
||||||
// NULL or other
|
// NULL or other
|
||||||
return NumberValue.ZERO;
|
return NumberValue.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MapValue toValue(JSONObject json) {
|
public static MapValue toValue(JSONObject json) {
|
||||||
final MapValue result = new MapValue(json.length());
|
final MapValue result = new MapValue(json.length());
|
||||||
final Iterator<String> it = json.keys();
|
final Iterator<String> it = json.keys();
|
||||||
while(it.hasNext()) {
|
while(it.hasNext()) {
|
||||||
final String key = it.next();
|
final String key = it.next();
|
||||||
final Value value = toValue(json.get(key));
|
final Value value = toValue(json.get(key));
|
||||||
result.set(new StringValue(key), value);
|
result.set(new StringValue(key), value);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayValue toValue(JSONArray json) {
|
public static ArrayValue toValue(JSONArray json) {
|
||||||
final int length = json.length();
|
final int length = json.length();
|
||||||
final ArrayValue result = new ArrayValue(length);
|
final ArrayValue result = new ArrayValue(length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
final Value value = toValue(json.get(i));
|
final Value value = toValue(json.get(i));
|
||||||
result.set(i, value);
|
result.set(i, value);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Number getNumber(Value value) {
|
public static Number getNumber(Value value) {
|
||||||
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw();
|
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw();
|
||||||
return value.asInt();
|
return value.asInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float getFloatNumber(Value value) {
|
public static float getFloatNumber(Value value) {
|
||||||
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw().floatValue();
|
if (value.type() == Types.NUMBER) return ((NumberValue) value).raw().floatValue();
|
||||||
return (float) value.asNumber();
|
return (float) value.asNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] toByteArray(ArrayValue array) {
|
public static byte[] toByteArray(ArrayValue array) {
|
||||||
final int size = array.size();
|
final int size = array.size();
|
||||||
final byte[] result = new byte[size];
|
final byte[] result = new byte[size];
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
result[i] = (byte) array.get(i).asInt();
|
result[i] = (byte) array.get(i).asInt();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Function consumeFunction(Value value, int argumentNumber) {
|
public static Function consumeFunction(Value value, int argumentNumber) {
|
||||||
final int type = value.type();
|
return consumeFunction(value, " at argument " + (argumentNumber + 1));
|
||||||
if (type != Types.FUNCTION) {
|
}
|
||||||
throw new TypeException("Function expected at argument " + (argumentNumber + 1)
|
|
||||||
+ ", but found " + Types.typeToString(type));
|
public static Function consumeFunction(Value value, String errorMessage) {
|
||||||
}
|
final int type = value.type();
|
||||||
return ((FunctionValue) value).getValue();
|
if (type != Types.FUNCTION) {
|
||||||
}
|
throw new TypeException("Function expected" + errorMessage
|
||||||
|
+ ", but found " + Types.typeToString(type));
|
||||||
public static <T extends Number> MapValue collectNumberConstants(Class<?> clazz, Class<T> type) {
|
}
|
||||||
MapValue result = new MapValue(20);
|
return ((FunctionValue) value).getValue();
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
}
|
||||||
if (!Modifier.isStatic(field.getModifiers())) continue;
|
|
||||||
if (!field.getType().equals(type)) continue;
|
public static <T extends Number> MapValue collectNumberConstants(Class<?> clazz, Class<T> type) {
|
||||||
try {
|
MapValue result = new MapValue(20);
|
||||||
result.set(field.getName(), NumberValue.of((T) field.get(type)));
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
} catch (IllegalAccessException ignore) {
|
if (!Modifier.isStatic(field.getModifiers())) continue;
|
||||||
}
|
if (!field.getType().equals(type)) continue;
|
||||||
}
|
try {
|
||||||
return result;
|
result.set(field.getName(), NumberValue.of((T) field.get(type)));
|
||||||
}
|
} catch (IllegalAccessException ignore) {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import com.annimon.ownlang.lib.Function;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
import com.annimon.ownlang.lib.ValueUtils;
|
||||||
|
import java.io.IOException;
|
||||||
|
import okhttp3.Call;
|
||||||
|
import okhttp3.Callback;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class CallValue extends MapValue {
|
||||||
|
|
||||||
|
private final Call call;
|
||||||
|
|
||||||
|
public CallValue(Call call) {
|
||||||
|
super(6);
|
||||||
|
this.call = call;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("cancel", Converters.voidToVoid(call::cancel));
|
||||||
|
set("enqueue", this::enqueue);
|
||||||
|
set("execute", this::execute);
|
||||||
|
set("isCanceled", Converters.voidToBoolean(call::isCanceled));
|
||||||
|
set("isExecuted", Converters.voidToBoolean(call::isExecuted));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value enqueue(Value[] args) {
|
||||||
|
Arguments.checkOrOr(1, 2, args.length);
|
||||||
|
final Function onResponse = ValueUtils.consumeFunction(args[0], 0);
|
||||||
|
call.enqueue(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call call, Response response) throws IOException {
|
||||||
|
onResponse.execute(new CallValue(call), new ResponseValue(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, IOException e) {
|
||||||
|
if (args.length == 2) {
|
||||||
|
ValueUtils.consumeFunction(args[1], 1)
|
||||||
|
.execute(new CallValue(call), new StringValue(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return NumberValue.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value execute(Value[] args) {
|
||||||
|
Arguments.check(0, args.length);
|
||||||
|
try {
|
||||||
|
return new ResponseValue(call.execute());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.*;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.WebSocket;
|
||||||
|
import okhttp3.WebSocketListener;
|
||||||
|
import okio.ByteString;
|
||||||
|
|
||||||
|
public class HttpClientValue extends MapValue {
|
||||||
|
|
||||||
|
private final OkHttpClient client;
|
||||||
|
|
||||||
|
public HttpClientValue(OkHttpClient client) {
|
||||||
|
super(10);
|
||||||
|
this.client = client;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OkHttpClient getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("connectTimeoutMillis", Converters.voidToInt(client::connectTimeoutMillis));
|
||||||
|
set("followRedirects", Converters.voidToBoolean(client::followRedirects));
|
||||||
|
set("followSslRedirects", Converters.voidToBoolean(client::followSslRedirects));
|
||||||
|
set("newCall", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
final Request request = Values.getRequest(args[0], " at first argument");
|
||||||
|
return new CallValue(client.newCall(request));
|
||||||
|
});
|
||||||
|
set("newWebSocket", this::newWebSocket);
|
||||||
|
set("pingIntervalMillis", Converters.voidToInt(client::pingIntervalMillis));
|
||||||
|
set("readTimeoutMillis", Converters.voidToInt(client::readTimeoutMillis));
|
||||||
|
set("retryOnConnectionFailure", Converters.voidToBoolean(client::retryOnConnectionFailure));
|
||||||
|
set("writeTimeoutMillis", Converters.voidToInt(client::writeTimeoutMillis));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final StringValue onOpen = new StringValue("onOpen");
|
||||||
|
private static final StringValue onTextMessage = new StringValue("onTextMessage");
|
||||||
|
private static final StringValue onBytesMessage = new StringValue("onBytesMessage");
|
||||||
|
private static final StringValue onClosing = new StringValue("onClosing");
|
||||||
|
private static final StringValue onClosed = new StringValue("onClosed");
|
||||||
|
private static final StringValue onFailure = new StringValue("onFailure");
|
||||||
|
|
||||||
|
private Value newWebSocket(Value[] args) {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
final Request request = Values.getRequest(args[0], " at first argument");
|
||||||
|
if (args[1].type() != Types.MAP) {
|
||||||
|
throw new TypeException("Map expected at second argument");
|
||||||
|
}
|
||||||
|
final MapValue callbacks = (MapValue) args[1];
|
||||||
|
final WebSocket ws = client.newWebSocket(request, new WebSocketListener() {
|
||||||
|
@Override
|
||||||
|
public void onOpen(WebSocket webSocket, Response response) {
|
||||||
|
final Value func = callbacks.get(onOpen);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, " at onOpen").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
new ResponseValue(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(WebSocket webSocket, String text) {
|
||||||
|
final Value func = callbacks.get(onTextMessage);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, "at onTextMessage").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
new StringValue(text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(WebSocket webSocket, ByteString bytes) {
|
||||||
|
final Value func = callbacks.get(onBytesMessage);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, "at onBytesMessage").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
ArrayValue.of(bytes.toByteArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClosing(WebSocket webSocket, int code, String reason) {
|
||||||
|
final Value func = callbacks.get(onClosing);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, "at onClosing").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
NumberValue.of(code),
|
||||||
|
new StringValue(reason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClosed(WebSocket webSocket, int code, String reason) {
|
||||||
|
final Value func = callbacks.get(onClosed);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, "at onClosed").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
NumberValue.of(code),
|
||||||
|
new StringValue(reason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
||||||
|
final Value func = callbacks.get(onFailure);
|
||||||
|
if (func != null) {
|
||||||
|
ValueUtils.consumeFunction(func, "at onFailure").execute(
|
||||||
|
new WebSocketValue(webSocket),
|
||||||
|
new StringValue(t.getMessage()),
|
||||||
|
new ResponseValue(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new CallValue(client.newCall(request));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
import java.util.Map;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
|
||||||
|
public class MultipartBodyBuilderValue extends MapValue {
|
||||||
|
|
||||||
|
private final MultipartBody.Builder builder;
|
||||||
|
|
||||||
|
public MultipartBodyBuilderValue() {
|
||||||
|
super(5);
|
||||||
|
this.builder = new MultipartBody.Builder();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("addFormData", this::addFormData);
|
||||||
|
set("addFormDataPart", this::addFormDataPart);
|
||||||
|
set("addPart", this::addPart);
|
||||||
|
set("build", args -> new MultipartBodyValue(builder.build()));
|
||||||
|
set("setType", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
builder.setType(MediaType.parse(args[0].asString()));
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value addFormDataPart(Value[] args) {
|
||||||
|
Arguments.checkOrOr(2, 3, args.length);
|
||||||
|
if (args.length == 2) {
|
||||||
|
builder.addFormDataPart(args[0].asString(), args[1].asString());
|
||||||
|
} else {
|
||||||
|
builder.addFormDataPart(
|
||||||
|
args[0].asString(),
|
||||||
|
args[1].asString(),
|
||||||
|
Values.getRequestBody(args[2], " at third argument"));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value addFormData(Value[] args) {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
if (args[0].type() != Types.MAP) {
|
||||||
|
throw new TypeException("Map expected at first argument");
|
||||||
|
}
|
||||||
|
for (Map.Entry<Value, Value> entry : ((MapValue) args[0])) {
|
||||||
|
builder.addFormDataPart(entry.getKey().asString(), entry.getValue().asString());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value addPart(Value[] args) {
|
||||||
|
Arguments.checkOrOr(2, 3, args.length);
|
||||||
|
if (args.length == 1) {
|
||||||
|
builder.addPart(
|
||||||
|
Values.getRequestBody(args[0], " at first argument"));
|
||||||
|
} else {
|
||||||
|
builder.addPart(
|
||||||
|
Values.getHeaders(args[0], " at first argument"),
|
||||||
|
Values.getRequestBody(args[1], " at second argument"));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
|
||||||
|
public class MultipartBodyValue extends RequestBodyValue {
|
||||||
|
|
||||||
|
private final MultipartBody multipartBody;
|
||||||
|
|
||||||
|
public MultipartBodyValue(MultipartBody multipartBody) {
|
||||||
|
super(multipartBody, 5);
|
||||||
|
this.multipartBody = multipartBody;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartBody getMultipartBody() {
|
||||||
|
return multipartBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("boundary", Converters.voidToString(multipartBody::boundary));
|
||||||
|
set("size", Converters.voidToInt(multipartBody::size));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
|
||||||
|
public class RequestBodyValue extends MapValue {
|
||||||
|
|
||||||
|
private final RequestBody requestBody;
|
||||||
|
private final MediaType mediaType;
|
||||||
|
|
||||||
|
public RequestBodyValue(RequestBody requestBody) {
|
||||||
|
this(requestBody, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RequestBodyValue(RequestBody requestBody, int methodsCount) {
|
||||||
|
super(4 + methodsCount);
|
||||||
|
this.requestBody = requestBody;
|
||||||
|
this.mediaType = requestBody.contentType();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestBody getRequestBody() {
|
||||||
|
return requestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaType getMediaType() {
|
||||||
|
return mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("getContentLength", Converters.voidToLong(() -> {
|
||||||
|
try {
|
||||||
|
return requestBody.contentLength();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
set("getType", Converters.voidToString(mediaType::type));
|
||||||
|
set("getSubtype", Converters.voidToString(mediaType::subtype));
|
||||||
|
set("getCharset", args -> {
|
||||||
|
Arguments.checkOrOr(0, 1, args.length);
|
||||||
|
if (args.length == 0) {
|
||||||
|
return new StringValue(mediaType.charset().name());
|
||||||
|
} else {
|
||||||
|
return new StringValue(mediaType.charset(Charset.forName(args[0].asString())).name());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.Converters.VoidToVoidFunction;
|
||||||
|
import com.annimon.ownlang.lib.Function;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
|
||||||
|
public class RequestBuilderValue extends MapValue {
|
||||||
|
|
||||||
|
private final Request.Builder requestBuilder;
|
||||||
|
|
||||||
|
public RequestBuilderValue() {
|
||||||
|
super(15);
|
||||||
|
requestBuilder = new Request.Builder();
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Request getRequest() {
|
||||||
|
return requestBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("addHeader", args -> {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
requestBuilder.addHeader(args[0].asString(), args[1].asString());
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("cacheControl", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
// TODO
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("delete", httpMethod(requestBuilder::delete, requestBuilder::delete));
|
||||||
|
set("get", args -> {
|
||||||
|
requestBuilder.get();
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("head", args -> {
|
||||||
|
requestBuilder.head();
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("header", args -> {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
requestBuilder.header(args[0].asString(), args[1].asString());
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("headers", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
requestBuilder.headers(Values.getHeaders(args[0], " at first argument"));
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("method", args -> {
|
||||||
|
Arguments.checkOrOr(1, 2, args.length);
|
||||||
|
final RequestBody body;
|
||||||
|
if (args.length == 1) {
|
||||||
|
body = null;
|
||||||
|
} else {
|
||||||
|
body = Values.getRequestBody(args[1], " at second argument");
|
||||||
|
}
|
||||||
|
requestBuilder.method(args[0].asString(), body);
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("newCall", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
final OkHttpClient client = Values.getHttpClient(args[0], " at first argument");
|
||||||
|
return new CallValue(client.newCall(getRequest()));
|
||||||
|
});
|
||||||
|
set("patch", httpMethod(requestBuilder::patch));
|
||||||
|
set("post", httpMethod(requestBuilder::post));
|
||||||
|
set("put", httpMethod(requestBuilder::put));
|
||||||
|
set("removeHeader", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
requestBuilder.removeHeader(args[0].asString());
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
set("url", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
requestBuilder.url(args[0].asString());
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Function httpMethod(VoidToVoidFunction voidFunc, RequestBodyToVoidFunction bodyFunc) {
|
||||||
|
return (args) -> {
|
||||||
|
Arguments.checkOrOr(0, 1, args.length);
|
||||||
|
if (args.length == 0) {
|
||||||
|
voidFunc.apply();
|
||||||
|
} else {
|
||||||
|
bodyFunc.apply(Values.getRequestBody(args[0], " at first argument"));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Function httpMethod(RequestBodyToVoidFunction bodyFunc) {
|
||||||
|
return (args) -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
bodyFunc.apply(Values.getRequestBody(args[0], " at first argument"));
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface RequestBodyToVoidFunction {
|
||||||
|
void apply(RequestBody value);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.Console;
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import java.io.IOException;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
import okio.BufferedSink;
|
||||||
|
import okio.Okio;
|
||||||
|
|
||||||
|
public class ResponseBodyValue extends MapValue {
|
||||||
|
|
||||||
|
private final ResponseBody responseBody;
|
||||||
|
|
||||||
|
public ResponseBodyValue(ResponseBody response) {
|
||||||
|
super(8);
|
||||||
|
this.responseBody = response;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("bytes", args -> {
|
||||||
|
try {
|
||||||
|
return ArrayValue.of(responseBody.bytes());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
set("close", Converters.voidToVoid(responseBody::close));
|
||||||
|
set("contentLength", Converters.voidToLong(responseBody::contentLength));
|
||||||
|
set("contentType", args -> new StringValue(responseBody.contentType().toString()));
|
||||||
|
set("string", args -> {
|
||||||
|
try {
|
||||||
|
return new StringValue(responseBody.string());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
set("file", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
try {
|
||||||
|
BufferedSink sink = Okio.buffer(Okio.sink(Console.fileInstance(args[0].asString())));
|
||||||
|
sink.writeAll(responseBody.source());
|
||||||
|
sink.close();
|
||||||
|
return NumberValue.ONE;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class ResponseValue extends MapValue {
|
||||||
|
|
||||||
|
private final Response response;
|
||||||
|
|
||||||
|
public ResponseValue(Response response) {
|
||||||
|
super(15);
|
||||||
|
this.response = response;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("body", args -> new ResponseBodyValue(response.body()));
|
||||||
|
set("cacheResponse", args -> new ResponseValue(response.cacheResponse()));
|
||||||
|
set("code", Converters.voidToInt(response::code));
|
||||||
|
set("close", Converters.voidToVoid(response::close));
|
||||||
|
set("header", args -> {
|
||||||
|
Arguments.checkOrOr(1, 2, args.length);
|
||||||
|
final String defaultValue = (args.length == 1) ? null : args[1].asString();
|
||||||
|
return new StringValue(response.header(args[0].asString(), defaultValue));
|
||||||
|
});
|
||||||
|
set("headers", args -> {
|
||||||
|
Arguments.checkOrOr(0, 1, args.length);
|
||||||
|
if (args.length == 0) {
|
||||||
|
final Map<String, List<String>> headers = response.headers().toMultimap();
|
||||||
|
final MapValue result = new MapValue(headers.size());
|
||||||
|
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
|
||||||
|
result.set(entry.getKey(), ArrayValue.of(entry.getValue().toArray(new String[0])));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return ArrayValue.of(response.headers(args[0].asString()).toArray(new String[0]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
set("message", Converters.voidToString(response::message));
|
||||||
|
set("networkResponse", args -> new ResponseValue(response.networkResponse()));
|
||||||
|
set("priorResponse", args -> new ResponseValue(response.priorResponse()));
|
||||||
|
set("receivedResponseAtMillis", Converters.voidToLong(response::receivedResponseAtMillis));
|
||||||
|
set("sentRequestAtMillis", Converters.voidToLong(response::sentRequestAtMillis));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
src/main/java/com/annimon/ownlang/modules/okhttp/Values.java
Normal file
47
src/main/java/com/annimon/ownlang/modules/okhttp/Values.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import okhttp3.Headers;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
|
||||||
|
public class Values {
|
||||||
|
|
||||||
|
public static RequestBody getRequestBody(Value arg, String msg) {
|
||||||
|
if (arg.type() == Types.MAP && (arg instanceof RequestBodyValue)) {
|
||||||
|
return ((RequestBodyValue) arg).getRequestBody();
|
||||||
|
}
|
||||||
|
throw new TypeException("RequestBody value expected" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Request getRequest(Value arg, String msg) {
|
||||||
|
if (arg.type() == Types.MAP && (arg instanceof RequestBuilderValue)) {
|
||||||
|
return ((RequestBuilderValue) arg).getRequest();
|
||||||
|
}
|
||||||
|
throw new TypeException("Request value expected" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OkHttpClient getHttpClient(Value arg, String msg) {
|
||||||
|
if (arg.type() == Types.MAP && (arg instanceof HttpClientValue)) {
|
||||||
|
return ((HttpClientValue) arg).getClient();
|
||||||
|
}
|
||||||
|
throw new TypeException("HttpClient value expected" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Headers getHeaders(Value arg, String msg) {
|
||||||
|
if (arg.type() != Types.MAP) {
|
||||||
|
throw new TypeException("Map expected" + msg);
|
||||||
|
}
|
||||||
|
final Map<String, String> headers = new LinkedHashMap<>();
|
||||||
|
for (Map.Entry<Value, Value> entry : ((MapValue) arg)) {
|
||||||
|
headers.put(entry.getKey().asString(), entry.getValue().asString());
|
||||||
|
}
|
||||||
|
return Headers.of(headers);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
|
import com.annimon.ownlang.lib.Converters;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.NumberValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.ValueUtils;
|
||||||
|
import okhttp3.WebSocket;
|
||||||
|
import okio.ByteString;
|
||||||
|
|
||||||
|
public class WebSocketValue extends MapValue {
|
||||||
|
|
||||||
|
private final WebSocket ws;
|
||||||
|
|
||||||
|
protected WebSocketValue(WebSocket ws) {
|
||||||
|
super(4);
|
||||||
|
this.ws = ws;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WebSocket getWebSocket() {
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
set("cancel", Converters.voidToVoid(ws::cancel));
|
||||||
|
set("close", args -> {
|
||||||
|
Arguments.checkOrOr(1, 2, args.length);
|
||||||
|
final String reason = (args.length == 2) ? args[1].asString() : null;
|
||||||
|
return NumberValue.fromBoolean(ws.close(args[0].asInt(), reason));
|
||||||
|
});
|
||||||
|
set("queueSize", Converters.voidToLong(ws::queueSize));
|
||||||
|
set("send", args -> {
|
||||||
|
Arguments.check(1, args.length);
|
||||||
|
final boolean result;
|
||||||
|
if (args[0].type() == Types.ARRAY) {
|
||||||
|
result = ws.send(ByteString.of( ValueUtils.toByteArray(((ArrayValue) args[0])) ));
|
||||||
|
} else {
|
||||||
|
result = ws.send(args[0].asString());
|
||||||
|
}
|
||||||
|
return NumberValue.fromBoolean(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
81
src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java
Normal file
81
src/main/java/com/annimon/ownlang/modules/okhttp/okhttp.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package com.annimon.ownlang.modules.okhttp;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.Console;
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.Arguments;
|
||||||
|
import com.annimon.ownlang.lib.ArrayValue;
|
||||||
|
import com.annimon.ownlang.lib.MapValue;
|
||||||
|
import com.annimon.ownlang.lib.StringValue;
|
||||||
|
import com.annimon.ownlang.lib.Types;
|
||||||
|
import com.annimon.ownlang.lib.ValueUtils;
|
||||||
|
import com.annimon.ownlang.lib.Variables;
|
||||||
|
import com.annimon.ownlang.modules.Module;
|
||||||
|
import okhttp3.MediaType;
|
||||||
|
import okhttp3.MultipartBody;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.RequestBody;
|
||||||
|
|
||||||
|
public final class okhttp implements Module {
|
||||||
|
|
||||||
|
private static final HttpClientValue defaultClient = new HttpClientValue(new OkHttpClient());
|
||||||
|
|
||||||
|
public static void initConstants() {
|
||||||
|
MapValue requestBody = new MapValue(5);
|
||||||
|
requestBody.set("bytes", args -> {
|
||||||
|
Arguments.checkOrOr(2, 4, args.length);
|
||||||
|
if (args[1].type() != Types.ARRAY) {
|
||||||
|
throw new TypeException("Array of bytes expected at second argument");
|
||||||
|
}
|
||||||
|
final byte[] bytes = ValueUtils.toByteArray((ArrayValue) args[1]);
|
||||||
|
final int offset;
|
||||||
|
final int bytesCount;
|
||||||
|
if (args.length == 2) {
|
||||||
|
offset = 0;
|
||||||
|
bytesCount = bytes.length;
|
||||||
|
} else {
|
||||||
|
offset = args[2].asInt();
|
||||||
|
bytesCount = args[3].asInt();
|
||||||
|
}
|
||||||
|
return new RequestBodyValue(RequestBody.create(
|
||||||
|
MediaType.parse(args[0].asString()),
|
||||||
|
bytes, offset, bytesCount
|
||||||
|
));
|
||||||
|
});
|
||||||
|
requestBody.set("file", args -> {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
return new RequestBodyValue(RequestBody.create(
|
||||||
|
MediaType.parse(args[0].asString()),
|
||||||
|
Console.fileInstance(args[1].asString())
|
||||||
|
));
|
||||||
|
});
|
||||||
|
requestBody.set("string", args -> {
|
||||||
|
Arguments.check(2, args.length);
|
||||||
|
return new RequestBodyValue(RequestBody.create(
|
||||||
|
MediaType.parse(args[0].asString()),
|
||||||
|
args[1].asString()
|
||||||
|
));
|
||||||
|
});
|
||||||
|
Variables.define("RequestBody", requestBody);
|
||||||
|
|
||||||
|
|
||||||
|
MapValue multipartBody = new MapValue(10);
|
||||||
|
multipartBody.set("ALTERNATIVE", new StringValue(MultipartBody.ALTERNATIVE.toString()));
|
||||||
|
multipartBody.set("DIGEST", new StringValue(MultipartBody.DIGEST.toString()));
|
||||||
|
multipartBody.set("FORM", new StringValue(MultipartBody.FORM.toString()));
|
||||||
|
multipartBody.set("MIXED", new StringValue(MultipartBody.MIXED.toString()));
|
||||||
|
multipartBody.set("PARALLEL", new StringValue(MultipartBody.PARALLEL.toString()));
|
||||||
|
multipartBody.set("builder", args -> new MultipartBodyBuilderValue());
|
||||||
|
Variables.define("MultipartBody", multipartBody);
|
||||||
|
|
||||||
|
|
||||||
|
MapValue okhttp = new MapValue(5);
|
||||||
|
okhttp.set("client", defaultClient);
|
||||||
|
okhttp.set("request", args -> new RequestBuilderValue());
|
||||||
|
Variables.define("okhttp", okhttp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
initConstants();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user