Add JS Value package source

This commit is contained in:
pengfei.zhou 2021-11-05 17:49:08 +08:00 committed by osborn
parent 2175c44338
commit cbcbc21737
18 changed files with 858 additions and 6 deletions

View File

@ -35,11 +35,11 @@ import java.util.Iterator;
* @Author: pengfei.zhou
* @CreateDate: 2021/11/5
*/
public class JavaJSDecoder extends JSDecoder {
public class DoricJSDecoder extends JSDecoder {
private final Object value;
private static final JSNull JS_NULL = new JSNull();
public JavaJSDecoder(Object object) {
public DoricJSDecoder(Object object) {
super(null);
this.value = object;
}
@ -109,7 +109,7 @@ public class JavaJSDecoder extends JSDecoder {
while (it.hasNext()) {
String key = it.next();
Object o = jsonObject.opt(key);
JavaJSDecoder jsDecoder = new JavaJSDecoder(o);
DoricJSDecoder jsDecoder = new DoricJSDecoder(o);
JSValue jsValue = jsDecoder.decode();
jsObject.setProperty(key, jsValue);
}
@ -121,7 +121,7 @@ public class JavaJSDecoder extends JSDecoder {
JSArray jsArray = new JSArray(length);
for (int i = 0; i < length; i++) {
Object o = jsonArray.opt(i);
JavaJSDecoder jsDecoder = new JavaJSDecoder(o);
DoricJSDecoder jsDecoder = new DoricJSDecoder(o);
JSValue jsValue = jsDecoder.decode();
jsArray.put(i, jsValue);
}

View File

@ -150,7 +150,7 @@ public class DoricWebViewJSExecutor implements IDoricJSE {
for (int i = 0; i < length; i++) {
JSONObject jsonObject = jsonArray.optJSONObject(i);
Object object = unwrapJSObject(jsonObject);
decoders[i] = new JavaJSDecoder(object);
decoders[i] = new DoricJSDecoder(object);
}
JavaValue javaValue = javaFunction.exec(decoders);
return wrapJavaValue(javaValue).toString();
@ -249,7 +249,7 @@ public class DoricWebViewJSExecutor implements IDoricJSE {
try {
JSONObject jsonObject = new JSONObject(result);
Object object = unwrapJSObject(jsonObject);
return new JavaJSDecoder(object);
return new DoricJSDecoder(object);
} catch (JSONException e) {
e.printStackTrace();
}

View File

@ -0,0 +1,22 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class ArchiveException extends Exception {
public ArchiveException(String str) {
super(str);
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public interface Decoding {
void decode(JSDecoder u) throws ArchiveException;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public interface DecodingFactory<T> {
T createInstance();
T[] createArray(int length);
}

View File

@ -0,0 +1,28 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
import org.json.JSONObject;
public interface Encoding {
JSONObject encode();
String[] getFunctionNames();
JavaFunction[] getFunctions();
}

View File

@ -0,0 +1,98 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class JSArray extends JSValue {
private final JSValue[] mVal;
public JSArray(int size) {
mVal = new JSValue[size];
}
public void put(int index, JSValue val) {
mVal[index] = val;
}
public JSValue get(int index) {
return mVal[index];
}
public int size() {
return mVal.length;
}
@Override
public JSType getJSType() {
return JSType.Array;
}
@Override
public JSType value() {
return JSType.Array;
}
public JSValue[] toArray() {
return mVal;
}
public String[] toStringArray() {
String[] ret = new String[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asString().value();
}
return ret;
}
public boolean[] toBooleanArray() {
boolean[] ret = new boolean[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asBoolean().value();
}
return ret;
}
public int[] toIntArray() {
int[] ret = new int[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asNumber().toInt();
}
return ret;
}
public float[] toFloatArray() {
float[] ret = new float[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asNumber().toFloat();
}
return ret;
}
public double[] toDoubleArray() {
double[] ret = new double[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asNumber().toDouble();
}
return ret;
}
public long[] toLongArray() {
long[] ret = new long[mVal.length];
for (int i = 0; i < ret.length; i++) {
ret[i] = mVal[i].asNumber().toLong();
}
return ret;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class JSBoolean extends JSValue {
private final boolean mVal;
public JSBoolean(boolean b) {
this.mVal = b;
}
@Override
public JSType getJSType() {
return JSType.Boolean;
}
@Override
public Boolean value() {
return mVal;
}
}

View File

@ -0,0 +1,199 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class JSDecoder {
private static final JSNull JS_NULL = new JSNull();
private ByteBuffer byteBuffer;
private byte[] __strBuf;
public JSDecoder(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
bytes = new byte[1];
bytes[0] = 'N';
}
this.byteBuffer = ByteBuffer.wrap(bytes);
byteBuffer.order(ByteOrder.BIG_ENDIAN);
}
public boolean bool() throws ArchiveException {
if (!isBool()) {
throw new ArchiveException("unable to decode bool");
}
return readBool();
}
public boolean readBool() throws ArchiveException {
return byteBuffer.get() == 1;
}
public String string() throws ArchiveException {
if (!isString()) {
throw new ArchiveException("unable to decode string");
}
return readString();
}
public String readString() throws ArchiveException {
int len = byteBuffer.getInt();
{
// ceil to 4k
int a = len / 0x1000;
int l = (a + 1) * 0x1000;
if (__strBuf == null || __strBuf.length < l) {
__strBuf = new byte[l];
}
}
byteBuffer.get(__strBuf, 0, len);
try {
return new String(__strBuf, 0, len, "utf-8");
} catch (UnsupportedEncodingException e) {
throw new ArchiveException("unable to decode string");
}
}
public Double number() throws com.github.pengfeizhou.jscore.ArchiveException {
if (!isNumber()) {
throw new com.github.pengfeizhou.jscore.ArchiveException("unable to decode number");
}
return readNumber();
}
public Double readNumber() {
return byteBuffer.getDouble();
}
public <T> T object(DecodingFactory<T> factory) throws ArchiveException {
byteBuffer.rewind();
return readObject(factory);
}
public <T> T readObject(DecodingFactory<T> factory) throws ArchiveException {
byte b = byteBuffer.get();
if (b == 'N') {
return factory.createInstance();
} else if (b == 'O') {
T obj = factory.createInstance();
if (obj == null) {
throw new ArchiveException("unable to create instance");
} else if (obj instanceof Decoding) {
((Decoding) obj).decode(this);
return obj;
} else {
throw new ArchiveException("unable to decode class: "
+ obj.getClass().getSimpleName());
}
} else {
throw new ArchiveException("unable to read object: " + this);
}
}
public <T> T[] array(DecodingFactory<T> factory) throws ArchiveException {
byteBuffer.rewind();
return readArray(factory);
}
public <T> T[] readArray(DecodingFactory<T> factory) throws ArchiveException {
byte b = byteBuffer.get();
if (b == 'N') {
return factory.createArray(0);
}
if (b == 'A') {
int len = byteBuffer.getInt();
T[] array = factory.createArray(len);
for (int i = 0; i < len; i++) {
array[i] = readObject(factory);
}
return array;
} else {
throw new ArchiveException("unable to read array (object): " + this);
}
}
public int readKeyHash() throws ArchiveException {
String name = readString();
return name.hashCode() & 0xffff;
}
public boolean isBool() {
byteBuffer.rewind();
return byteBuffer.get() == 'B';
}
public boolean isNULL() {
byteBuffer.rewind();
return byteBuffer.get() == 'N';
}
public boolean isString() {
byteBuffer.rewind();
return byteBuffer.get() == 'S';
}
public boolean isNumber() {
byteBuffer.rewind();
return byteBuffer.get() == 'D';
}
public boolean isArray() {
byteBuffer.rewind();
return byteBuffer.get() == 'A';
}
public boolean isObject() {
byteBuffer.rewind();
return byteBuffer.get() == 'O';
}
public JSValue decode() throws ArchiveException {
byte b = byteBuffer.get();
switch (b) {
case 'A': {
int len = byteBuffer.getInt();
JSArray ret = new JSArray(len);
for (int i = 0; i < len; i++) {
ret.put(i, decode());
}
return ret;
}
case 'S': {
return new JSString(readString());
}
case 'D': {
return new JSNumber(readNumber());
}
case 'B': {
return new JSBoolean(readBool());
}
case 'O': {
JSObject jsObject = new JSObject();
JSValue propertyName;
while ((propertyName = decode()) instanceof JSString) {
jsObject.setProperty(((JSString) propertyName).value(), decode());
}
return jsObject;
}
case 'N':
default:
return JS_NULL;
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
/**
* Define undefined or null
* Created by pengfei.zhou on 2018/12/12.
*/
public class JSNull extends JSValue {
@Override
public JSType getJSType() {
return JSType.Null;
}
@Override
public Object value() {
return null;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class JSNumber extends JSValue {
private final double mVal;
public JSNumber(double b) {
this.mVal = b;
}
@Override
public JSType getJSType() {
return JSType.Number;
}
@Override
public Double value() {
return mVal;
}
public int toInt() {
return (int) mVal;
}
public float toFloat() {
return (float) mVal;
}
public long toLong() {
return (long) mVal;
}
public double toDouble() {
return mVal;
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class JSONBuilder {
private final JSONObject jsonObject;
public JSONBuilder() {
this.jsonObject = new JSONObject();
}
public JSONBuilder(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}
public JSONBuilder put(String key, Object val) {
try {
if (val == null) {
jsonObject.put(key, JSONObject.NULL);
} else if (val instanceof Encoding) {
jsonObject.put(key, ((Encoding) val).encode());
} else if (val instanceof Encoding[]) {
JSONArray jsonArray = new JSONArray();
for (Encoding object : (Encoding[]) val) {
jsonArray.put(object.encode());
}
jsonObject.put(key, jsonArray);
} else {
jsonObject.put(key, val);
}
} catch (JSONException e) {
e.printStackTrace();
}
return this;
}
@Override
public String toString() {
return jsonObject.toString();
}
public JSONObject toJSONObject() {
return jsonObject;
}
public JavaValue toValue() {
return new JavaValue(jsonObject);
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class JSObject extends JSValue {
private final Map<String, JSValue> mVal;
public JSObject() {
this.mVal = new HashMap<>();
}
public void setProperty(String name, JSValue val) {
this.mVal.put(name, val);
}
public JSValue getProperty(String name) {
JSValue jsValue = this.mVal.get(name);
if (jsValue == null) {
jsValue = new JSNull();
}
return jsValue;
}
@Override
public JSType getJSType() {
return JSType.Object;
}
@Override
public Map<String, JSValue> value() {
return mVal;
}
public Set<String> propertySet() {
return mVal.keySet();
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class JSRuntimeException extends RuntimeException {
public JSRuntimeException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public class JSString extends JSValue {
private final String mVal;
public JSString(String b) {
this.mVal = b;
}
@Override
public JSType getJSType() {
return JSType.String;
}
@Override
public String value() {
return mVal;
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public abstract class JSValue {
public enum JSType {
Null,
Number,
Boolean,
String,
Object,
Array,
}
public abstract JSType getJSType();
public abstract Object value();
public boolean isNull() {
return getJSType() == JSType.Null;
}
public boolean isNumber() {
return getJSType() == JSType.Number;
}
public boolean isBoolean() {
return getJSType() == JSType.Boolean;
}
public boolean isString() {
return getJSType() == JSType.String;
}
public boolean isObject() {
return getJSType() == JSType.Object;
}
public boolean isArray() {
return getJSType() == JSType.Array;
}
public JSNull asNull() {
return (JSNull) this;
}
public JSNumber asNumber() {
return (JSNumber) this;
}
public JSBoolean asBoolean() {
return (JSBoolean) this;
}
public JSString asString() {
return (JSString) this;
}
public JSObject asObject() {
return (JSObject) this;
}
public JSArray asArray() {
return (JSArray) this;
}
@Override
public String toString() {
return String.valueOf(value());
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
public abstract class JavaFunction {
public abstract JavaValue exec(JSDecoder[] args);
public boolean hashKey() {
return false;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright [2021] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pub.doric.engine.value;
import com.github.pengfeizhou.jscore.Encoding;
import org.json.JSONArray;
import org.json.JSONObject;
public class JavaValue extends com.github.pengfeizhou.jscore.JavaValue {
public JavaValue() {
super();
}
public JavaValue(double value) {
super(value);
}
public JavaValue(String value) {
super(value);
}
public JavaValue(boolean value) {
super(value);
}
public JavaValue(Encoding object) {
super(object);
}
public JavaValue(JSONObject json) {
super(json);
}
public JavaValue(JSONArray jsonArray) {
super(jsonArray);
}
public JavaValue(Encoding[] objects) {
super(objects);
}
}