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

com.jn.agileway.codec.serialization.fse.Fses Maven / Gradle / Ivy

Go to download

Provide an unified codec API for hession, kryo, protostuff, fst, fes, xson, cbor, jackson, json, etc....

There is a newer version: 3.1.12
Show newest version
package com.jn.agileway.codec.serialization.fse;

import com.jfireframework.fse.ByteArray;
import com.jfireframework.fse.Fse;
import com.jn.agileway.codec.serialization.fst.Fsts;
import com.jn.langx.Factory;
import com.jn.langx.annotation.NonNull;
import com.jn.langx.annotation.Nullable;
import com.jn.langx.codec.CodecException;
import com.jn.langx.text.StringTemplates;
import com.jn.langx.util.Throwables;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.collection.Pipeline;
import com.jn.langx.util.concurrent.threadlocal.ThreadLocalFactory;
import com.jn.langx.util.function.Consumer;
import com.jn.langx.util.function.Consumer2;
import com.jn.langx.util.io.IOs;
import com.jn.langx.util.logging.Loggers;
import com.jn.langx.util.reflect.Reflects;
import com.jn.langx.util.struct.Entry;
import com.jn.langx.util.struct.Pair;
import org.slf4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;

public class Fses {
    private Fses() {
    }

    private static final Logger logger = Loggers.getLogger(Fsts.class);

    private static final Map fseCustomizerRegistry = new ConcurrentHashMap();


    public static final ThreadLocalFactory> fseFactory = new ThreadLocalFactory>(new Factory>() {
        @Override
        public Pair get(Object o) {
            final Fse fse = new Fse();
            // 用于解决循环依赖
            Collects.forEach(fseCustomizerRegistry, new Consumer2() {
                @Override
                public void accept(String name, FseCustomizer customizer) {
                    try {
                        customizer.customize(fse);
                    } catch (Throwable ex) {
                        if (ex instanceof NoClassDefFoundError || ex instanceof ClassNotFoundException) {
                            logger.error("Error occur when register FSE serializers for {}, may be you should append de.javakaffee:kryo-serializers.jar to the classpath", name);
                        } else {
                            logger.error("Error occur when register FSE customizer  for {}", name);
                        }
                    }
                }
            });
            ByteArray byteArray = ByteArray.allocate(256);
            return new Entry(fse, byteArray);
        }
    });

    public static  byte[] serialize(@Nullable T o) throws IOException {
        Pair pair = fseFactory.get();
        Fse fse = pair.getKey();
        ByteArray buffer = pair.getValue();
        ByteArrayOutputStream bao = null;
        try {
            bao = new ByteArrayOutputStream();
            serialize(fse, buffer, o, bao);
            return bao.toByteArray();
        } finally {
            buffer.clear();
            IOs.close(bao);
        }
    }

    public static  void serialize(@Nullable T o, OutputStream outputStream) throws IOException {
        Pair pair = fseFactory.get();
        Fse fse = pair.getKey();
        ByteArray buffer = pair.getValue();
        serialize(fse, buffer, o, outputStream);
        buffer.clear();
    }

    public static  byte[] serialize(@NonNull Fse fse, @Nullable T o) throws IOException {
        if (o == null) {
            return null;
        }
        ByteArrayOutputStream bao = null;
        try {
            bao = new ByteArrayOutputStream();
            serialize(fse, ByteArray.allocate(256), o, bao);
            return bao.toByteArray();
        } finally {
            IOs.close(bao);
        }
    }

    public static  void serialize(@NonNull Fse fse, ByteArray buffer, @NonNull T o, @NonNull OutputStream outputStream) throws IOException {
        if (o != null) {
            fse.serialize(o, buffer);
            byte[] bytes = buffer.toArray();
            outputStream.write(bytes);
        }
    }

    public static  T deserialize(@Nullable byte[] bytes) {
        Pair pair = fseFactory.get();
        Fse fse = pair.getKey();
        return deserialize(fse, bytes);
    }

    public static  T deserialize(@Nullable byte[] bytes, @Nullable Class targetClass) {
        Pair pair = fseFactory.get();
        Fse fse = pair.getKey();
        ByteArray buffer = pair.getValue();
        try {
            return deserialize(fse, buffer, bytes, targetClass);
        }finally {
            buffer.clear();
        }
    }

    public static  T deserialize(@NonNull Fse fse, @Nullable byte[] bytes) {
        return deserialize(fse, null, bytes, null);
    }

    public static  T deserialize(@NonNull Fse fse, ByteArray buffer, @Nullable byte[] bytes, @Nullable Class targetClass) {
        if (bytes == null) {
            return null;
        }
        try {
            buffer = buffer == null ? ByteArray.allocate(bytes.length): buffer;
            buffer.clear();
            buffer.put(bytes);
            Object obj = fse.deSerialize(buffer);
            if (targetClass != null) {
                if (!Reflects.isInstance(obj, targetClass)) {
                    throw new CodecException(StringTemplates.formatWithPlaceholder("{} is not cast to {} when use FSE deserialize", Reflects.getFQNClassName(obj.getClass()), Reflects.getFQNClassName(targetClass)));
                }
                return (T) obj;
            } else {
                return (T) obj;
            }
        } catch (Exception ex) {
            throw Throwables.wrapAsRuntimeException(ex);
        }
    }

    static {
        ServiceLoader loader = ServiceLoader.load(FseCustomizer.class);
        Pipeline.of(loader).forEach(new Consumer() {
            @Override
            public void accept(FseCustomizer fstCustomizer) {
                fseCustomizerRegistry.put(fstCustomizer.getName(), fstCustomizer);
                logger.info("Load the FST serializers for {}", fstCustomizer.getName());
            }
        });
    }

    public static void registerCustomizer(String name, FseCustomizer customizer) {
        fseCustomizerRegistry.put(name, customizer);
    }

    public static FseCustomizer getCustomizer(String name) {
        return fseCustomizerRegistry.get(name);
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy