Добавлен модуль json

This commit is contained in:
Victor 2016-01-12 23:14:56 +02:00
parent ca2462dff8
commit f8854759ff
9 changed files with 235 additions and 9 deletions

View File

@ -0,0 +1,68 @@
use "std"
use "http"
use "json"
use "functional"
header = "* Prints current GitHub timeline *"
println "*" * length(header)
println header
println "*" * length(header)
// Executes in main thread
//http("https://api.github.com/events", def(r) {
// foreach(jsondecode(r), ::show_github_events)
//})
// Executes in new thread
thread(::http, "https://api.github.com/events", def(r) {
foreach(jsondecode(r), ::show_github_events)
})
def show_github_events(event) {
println event["created_at"]
actor = event["actor"]
println "User: https://github.com/" + actor["login"]
println github_event_type(event)
println "-" * 50
}
def github_event_type(event) {
type = event["type"]
repo = event["repo"]
repo = "https://github.com/" + repo["name"]
payload = event["payload"]
if (type == "CommitCommentEvent") {
comment = payload["comment"]
return "commented commit in " + repo + "\n" + comment["body"]
}
if (type == "CreateEvent") {
return "created " + payload["ref_type"] + " on " + repo
}
if (type == "DeleteEvent") {
return "deleted " + payload["ref_type"] + " on " + repo
}
if (type == "ForkEvent") {
return "forked repository " + repo
}
if (type == "IssueCommentEvent") {
comment = payload["comment"]
issue = payload["issue"]
return "commented issue " + issue["title"] + " on " + repo + "\n" + comment["body"]
}
if (type == "IssuesEvent") {
issue = payload["issue"]
return payload["action"] + " issue '" + issue["title"] + "' on " + repo
}
if (type == "PullRequestEvent") {
pr = payload["pull_request"]
return payload["action"] + " pull request #" + payload["number"] + " '" + pr["title"] + "' on " + repo
}
if (type == "PushEvent") {
return "pushed " + length(payload["commits"]) + " commits to " + repo
}
if (type == "WatchEvent") {
return "start watching repository " + repo
}
return type + " on " + repo
}

BIN
libs/json-20151123.jar Normal file

Binary file not shown.

View File

@ -222,6 +222,7 @@ is divided into following sections:
<condition else="" property="testng.debug.mode" value="-mixed"> <condition else="" property="testng.debug.mode" value="-mixed">
<istrue value="${junit+testng.available}"/> <istrue value="${junit+testng.available}"/>
</condition> </condition>
<property name="java.failonerror" value="true"/>
</target> </target>
<target name="-post-init"> <target name="-post-init">
<!-- Empty placeholder for easier customization. --> <!-- Empty placeholder for easier customization. -->
@ -698,7 +699,7 @@ is divided into following sections:
<sequential> <sequential>
<property environment="env"/> <property environment="env"/>
<resolve name="profiler.current.path" value="${profiler.info.pathvar}"/> <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
<java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}"> <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/> <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg value="${profiler.info.jvmargs.agent}"/> <jvmarg value="${profiler.info.jvmargs.agent}"/>
<jvmarg line="${profiler.info.jvmargs}"/> <jvmarg line="${profiler.info.jvmargs}"/>
@ -773,7 +774,7 @@ is divided into following sections:
<attribute default="${debug.classpath}" name="classpath"/> <attribute default="${debug.classpath}" name="classpath"/>
<element name="customize" optional="true"/> <element name="customize" optional="true"/>
<sequential> <sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true"> <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/> <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg line="${debug-args-line}"/> <jvmarg line="${debug-args-line}"/>
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/> <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
@ -800,7 +801,7 @@ is divided into following sections:
<attribute default="jvm" name="jvm"/> <attribute default="jvm" name="jvm"/>
<element name="customize" optional="true"/> <element name="customize" optional="true"/>
<sequential> <sequential>
<java classname="@{classname}" dir="${work.dir}" fork="true"> <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
<jvmarg line="${endorsed.classpath.cmd.line.arg}"/> <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
<jvmarg value="-Dfile.encoding=${runtime.encoding}"/> <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
<redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/> <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>

View File

@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.78.0.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=48c1b1a1 nbproject/build-impl.xml.data.CRC32=48c1b1a1
nbproject/build-impl.xml.script.CRC32=e3eeb3f1 nbproject/build-impl.xml.script.CRC32=b8cd7788
nbproject/build-impl.xml.stylesheet.CRC32=2d327b5d@1.78.0.48 nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.0.48

View File

@ -1,9 +1,10 @@
annotation.processing.enabled=true annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false annotation.processing.enabled.in.editor=false
annotation.processing.processor.options=
annotation.processing.processors.list= annotation.processing.processors.list=
annotation.processing.run.all.processors=true annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=OwnLang
application.vendor=aNNiMON
build.classes.dir=${build.dir}/classes build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned: # This directory is removed when the project is cleaned:
@ -26,10 +27,21 @@ dist.archive.excludes=
dist.dir=dist dist.dir=dist
dist.jar=${dist.dir}/OwnLang.jar dist.jar=${dist.dir}/OwnLang.jar
dist.javadoc.dir=${dist.dir}/javadoc dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes= excludes=
file.reference.commons-codec-1.6.jar=libs/commons-codec-1.6.jar
file.reference.commons-logging-1.1.3.jar=libs/commons-logging-1.1.3.jar
file.reference.httpclient-4.3.5.jar=libs/httpclient-4.3.5.jar
file.reference.httpcore-4.3.2.jar=libs/httpcore-4.3.2.jar
file.reference.json-20151123.jar=libs/json-20151123.jar
includes=** includes=**
jar.compress=false jar.compress=false
javac.classpath= javac.classpath=\
${file.reference.commons-codec-1.6.jar}:\
${file.reference.commons-logging-1.1.3.jar}:\
${file.reference.httpclient-4.3.5.jar}:\
${file.reference.httpcore-4.3.2.jar}:\
${file.reference.json-20151123.jar}
# Space-separated list of extra javac options # Space-separated list of extra javac options
javac.compilerargs= javac.compilerargs=
javac.deprecation=false javac.deprecation=false

View File

@ -128,11 +128,25 @@ println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
use "http" use "http"
http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) { /*http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) {
println "Added: " + v println "Added: " + v
http("http://jsonplaceholder.typicode.com/users/2", "PATCH", {"name": "Patched Name"}, ::http_get_demo) http("http://jsonplaceholder.typicode.com/users/2", "PATCH", {"name": "Patched Name"}, ::http_get_demo)
}) })
def http_get_demo(v) { def http_get_demo(v) {
println "Updated: " + v println "Updated: " + v
http("http://jsonplaceholder.typicode.com/users", ::echo) http("http://jsonplaceholder.typicode.com/users", ::echo)
}*/
use "json"
println "json"
println jsonencode({
"name": "JSON Example",
"version": 1,
"arrayData": [
1, 2, 3, 4
],
"objectData": {
"key": "value",
10: "1000"
} }
})

View File

@ -0,0 +1,61 @@
package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.lib.*;
import java.util.Iterator;
import org.json.*;
public final class json_decode implements Function {
@Override
public Value execute(Value... args) {
if (args.length != 1) throw new RuntimeException("One argument expected");
try {
final String jsonRaw = args[0].asString();
final Object root = new JSONTokener(jsonRaw).nextValue();
return process(root);
} catch (JSONException ex) {
throw new RuntimeException("Error while parsing json", ex);
}
}
private Value process(Object obj) {
if (obj instanceof JSONObject) {
return process((JSONObject) obj);
}
if (obj instanceof JSONArray) {
return process((JSONArray) obj);
}
if (obj instanceof String) {
return new StringValue((String) obj);
}
if (obj instanceof Number) {
return new NumberValue(((Number) obj).doubleValue());
}
if (obj instanceof Boolean) {
return NumberValue.fromBoolean((Boolean) obj);
}
// NULL or other
return NumberValue.ZERO;
}
private MapValue process(JSONObject json) {
final MapValue result = new MapValue(json.length());
final Iterator<String> it = json.keys();
while(it.hasNext()) {
final String key = it.next();
final Value value = process(json.get(key));
result.set(new StringValue(key), value);
}
return result;
}
private ArrayValue process(JSONArray json) {
final int length = json.length();
final ArrayValue result = new ArrayValue(length);
for (int i = 0; i < length; i++) {
final Value value = process(json.get(i));
result.set(i, value);
}
return result;
}
}

View File

@ -0,0 +1,53 @@
package com.annimon.ownlang.lib.modules.functions;
import com.annimon.ownlang.lib.*;
import java.util.Map;
import org.json.*;
public final class json_encode implements Function {
@Override
public Value execute(Value... args) {
if (args.length != 1) throw new RuntimeException("One argument expected");
try {
final Object root = process(args[0]);
final String jsonRaw = JSONObject.valueToString(root);
return new StringValue(jsonRaw);
} catch (JSONException ex) {
throw new RuntimeException("Error while creating json", ex);
}
}
private Object process(Value val) {
switch (val.type()) {
case Types.ARRAY:
return process((ArrayValue) val);
case Types.MAP:
return process((MapValue) val);
case Types.NUMBER:
return val.asNumber();
case Types.STRING:
return val.asString();
default:
return JSONObject.NULL;
}
}
private Object process(MapValue map) {
final JSONObject result = new JSONObject();
for (Map.Entry<Value, Value> entry : map) {
final String key = entry.getKey().asString();
final Object value = process(entry.getValue());
result.put(key, value);
}
return result;
}
private Object process(ArrayValue array) {
final JSONArray result = new JSONArray();
for (Value value : array) {
result.put(process(value));
}
return result;
}
}

View File

@ -0,0 +1,17 @@
package com.annimon.ownlang.lib.modules;
import com.annimon.ownlang.lib.*;
import com.annimon.ownlang.lib.modules.functions.*;
/**
*
* @author aNNiMON
*/
public final class json implements Module {
@Override
public void init() {
Functions.set("jsonencode", new json_encode());
Functions.set("jsondecode", new json_decode());
}
}