001/*
002 * (C) Copyright 2018 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bdelbosc
018 */
019package org.nuxeo.lib.stream.codec;
020
021import java.io.ByteArrayInputStream;
022import java.io.ByteArrayOutputStream;
023import java.io.IOException;
024import java.io.ObjectInput;
025import java.io.ObjectInputStream;
026import java.io.ObjectOutput;
027import java.io.ObjectOutputStream;
028import java.io.Serializable;
029
030/**
031 * Java {@link java.io.Serializable} encoding. It is highly recommended to use {@link java.io.Externalizable}, for
032 * performance reason.
033 *
034 * @since 10.2
035 */
036public class SerializableCodec<T extends Serializable> implements Codec<T> {
037
038    public static final String NAME = "java";
039
040    @Override
041    public String getName() {
042        return NAME;
043    }
044
045    @Override
046    public byte[] encode(T object) {
047        try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(bos)) {
048            out.writeObject(object);
049            out.flush();
050            return bos.toByteArray();
051        } catch (IOException e) {
052            throw new IllegalArgumentException(e);
053        }
054    }
055
056    @SuppressWarnings({ "unchecked", "squid:S2093" })
057    @Override
058    public T decode(byte[] data) {
059        // TODO: check if it worth to switch to commons-lang3 SerializationUtils
060        ByteArrayInputStream bis = new ByteArrayInputStream(data);
061        ObjectInput in = null;
062        try {
063            in = new ObjectInputStream(bis);
064            return (T) in.readObject();
065        } catch (IOException | ClassNotFoundException e) {
066            throw new IllegalArgumentException(e);
067        } finally {
068            try {
069                if (in != null) {
070                    in.close();
071                }
072                bis.close();
073            } catch (IOException ex) {
074                // we want to ignore close exception so no try-with-resources squid:S2093
075            }
076        }
077    }
078}