All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.fastjson2.util.ApacheLang3Support Maven / Gradle / Ivy

Go to download

Fastjson is a JSON processor (JSON parser + JSON generator) written in Java

There is a newer version: 2.0.53.android8
Show newest version
package com.alibaba.fastjson2.util;

import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.annotation.JSONCreator;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.support.LambdaMiscCodec;
import com.alibaba.fastjson2.writer.ObjectWriter;

import java.lang.reflect.Type;
import java.util.function.BiFunction;
import java.util.function.Function;

import static com.alibaba.fastjson2.JSONB.Constants.BC_TYPED_ANY;

public interface ApacheLang3Support {
    interface TripleMixIn {
        @JSONCreator
        static  Object of(L left, M middle, R right) {
            return null;
        }
    }

    class PairReader
            implements ObjectReader {
        static final long LEFT = Fnv.hashCode64("left");
        static final long RIGHT = Fnv.hashCode64("right");

        final Class objectClass;
        final Type leftType;
        final Type rightType;

        final BiFunction of;

        public PairReader(Class objectClass, Type leftType, Type rightType) {
            this.objectClass = objectClass;
            this.leftType = leftType;
            this.rightType = rightType;

            try {
                of = LambdaMiscCodec.createBiFunction(
                        objectClass.getMethod("of", Object.class, Object.class)
                );
            } catch (NoSuchMethodException e) {
                throw new JSONException("Pair.of method not found", e);
            }
        }

        @Override
        public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
            if (jsonReader.nextIfNull()) {
                return null;
            }

            if (jsonReader.nextIfMatch(BC_TYPED_ANY)) {
                long typeHash = jsonReader.readTypeHashCode();

                final long PAIR = 4645080105124911238L; // Fnv.hashCode64("org.apache.commons.lang3.tuple.Pair");
                final long MUTABLE_PAIR = 8310287657375596772L; // Fnv.hashCode64("org.apache.commons.lang3.tuple.MutablePair");
                final long IMMUTABLE_PAIR = -2802985644706367574L; // Fnv.hashCode64("org.apache.commons.lang3.tuple.ImmutablePair");

                if (typeHash != PAIR && typeHash != IMMUTABLE_PAIR && typeHash != MUTABLE_PAIR) {
                    throw new JSONException("not support inputType : " + jsonReader.getString());
                }
            }

            Object left = null, right = null;
            if (jsonReader.nextIfObjectStart()) {
                for (int i = 0; i < 100; i++) {
                    if (jsonReader.nextIfObjectEnd()) {
                        break;
                    }
                    if (jsonReader.isString()) {
                        long hashCode = jsonReader.readFieldNameHashCode();
                        if (hashCode == LEFT) {
                            left = jsonReader.read(leftType);
                        } else if (hashCode == RIGHT) {
                            right = jsonReader.read(rightType);
                        } else if (i == 0) {
                            left = jsonReader.getFieldName();
                            right = jsonReader.read(rightType);
                        } else {
                            jsonReader.skipValue();
                        }
                    } else if (i == 0) {
                        left = jsonReader.read(leftType);
                        right = jsonReader.read(rightType);
                    } else {
                        throw new JSONException(jsonReader.info("not support input"));
                    }
                }
            } else if (jsonReader.isArray()) {
                int len = jsonReader.startArray();
                if (len != 2) {
                    throw new JSONException(jsonReader.info("not support input"));
                }
                left = jsonReader.read(leftType);
                right = jsonReader.read(rightType);
            } else {
                throw new JSONException(jsonReader.info("not support input"));
            }

            return of.apply(left, right);
        }

        @Override
        public Object readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
            if (jsonReader.nextIfNull()) {
                return null;
            }

            Object left = null, right = null;
            if (jsonReader.nextIfObjectStart()) {
                for (int i = 0; i < 100; i++) {
                    if (jsonReader.nextIfObjectEnd()) {
                        break;
                    }
                    if (jsonReader.isString()) {
                        long hashCode = jsonReader.readFieldNameHashCode();
                        if (hashCode == LEFT) {
                            left = jsonReader.read(leftType);
                        } else if (hashCode == RIGHT) {
                            right = jsonReader.read(rightType);
                        } else if (i == 0) {
                            left = jsonReader.getFieldName();
                            jsonReader.nextIfMatch(':');
                            right = jsonReader.read(rightType);
                        } else {
                            jsonReader.skipValue();
                        }
                    } else if (i == 0) {
                        left = jsonReader.read(leftType);
                        jsonReader.nextIfMatch(':');
                        right = jsonReader.read(rightType);
                    } else {
                        throw new JSONException(jsonReader.info("not support input"));
                    }
                }
            } else if (jsonReader.nextIfArrayStart()) {
                left = jsonReader.read(leftType);
                right = jsonReader.read(rightType);
                if (!jsonReader.nextIfArrayEnd()) {
                    throw new JSONException(jsonReader.info("not support input"));
                }
            } else {
                throw new JSONException(jsonReader.info("not support input"));
            }

            return of.apply(left, right);
        }
    }

    class PairWriter
            implements ObjectWriter {
        final Class objectClass;
        final String typeName;
        final long typeNameHash;
        Function left;
        Function right;

        byte[] typeNameJSONB;

        static final byte[] leftName = JSONB.toBytes("left");
        static final byte[] rightName = JSONB.toBytes("right");

        public PairWriter(Class objectClass) {
            this.objectClass = objectClass;
            this.typeName = objectClass.getName();
            this.typeNameHash = Fnv.hashCode64(typeName);
        }

        @Override
        public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
            if (object == null) {
                jsonWriter.writeNull();
                return;
            }

            if ((jsonWriter.getFeatures(features) & JSONWriter.Feature.WriteClassName.mask) != 0) {
                if (typeNameJSONB == null) {
                    typeNameJSONB = JSONB.toBytes(typeName);
                }
                jsonWriter.writeTypeName(typeNameJSONB, typeNameHash);
            }

            jsonWriter.startObject();

            Object left = getLeft(object);
            Object right = getRight(object);

            jsonWriter.writeNameRaw(leftName, PairReader.LEFT);
            jsonWriter.writeAny(left);

            jsonWriter.writeNameRaw(rightName, PairReader.RIGHT);
            jsonWriter.writeAny(right);
            jsonWriter.endObject();
        }

        @Override
        public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
            if (object == null) {
                jsonWriter.writeNull();
                return;
            }

            Object left = getLeft(object);
            Object right = getRight(object);

            jsonWriter.startObject();
            if ((jsonWriter.getFeatures(features) & JSONWriter.Feature.WritePairAsJavaBean.mask) != 0) {
                jsonWriter.writeName("left");
                jsonWriter.writeColon();
                jsonWriter.writeAny(left);

                jsonWriter.writeName("right");
            } else {
                jsonWriter.writeNameAny(left);
            }
            jsonWriter.writeColon();
            jsonWriter.writeAny(right);

            jsonWriter.endObject();
        }

        Object getLeft(Object object) {
            Class objectClass = object.getClass();
            if (left == null) {
                try {
                    left = LambdaMiscCodec.createFunction(
                            objectClass.getMethod("getLeft")
                    );
                } catch (NoSuchMethodException e) {
                    throw new JSONException("getLeft method not found", e);
                }
            }

            return left.apply(object);
        }

        Object getRight(Object object) {
            Class objectClass = object.getClass();
            if (right == null) {
                try {
                    right = LambdaMiscCodec.createFunction(
                            objectClass.getMethod("getRight")
                    );
                } catch (NoSuchMethodException e) {
                    throw new JSONException("getRight method not found", e);
                }
            }

            return right.apply(object);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy