package de.renew.expression;

import java.io.IOException;
import java.io.Serial;

import de.renew.util.ReflectionSerializer;


/**
 * Superclass for all expression classes which need to remember
 * a targetType.
 * <p>
 * The targetType field is of the type {@code java.lang.Class}
 * and needs special treatment on serialization.
 * The common (de-)serialization code is the only reason for the
 * existence of this class.
 * <p>
 * Created: Wed Feb  2  2000
 * <p>
 * See also: {@link de.renew.util.ReflectionSerializer}
 *
 * @author Michael Duvigneau
 */
abstract class ExpressionWithTypeField implements Expression {
    @Serial
    private static final long serialVersionUID = 8460090091849454249L;

    /**
     * This field is not really transient, but as {@code java.lang.Class}
     * is not always serializable, we have to store it by ourselves.
     */
    private transient Class<?> _targetType;

    public ExpressionWithTypeField(Class<?> targetType) {
        _targetType = targetType;
    }

    @Override
    public Class<?> getType() {
        return _targetType;
    }

    /**
     * Serialization method, behaves like default writeObject
     * method. Stores the not-really-transient targetType field.
     *
     * @param out the {@code ObjectOutputStream} to serialize this {@code ExpressionWithTypeField} to
     * @throws IOException if writing to the output stream fails
     */
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        ReflectionSerializer.writeClass(out, _targetType);
    }

    /**
     * Deserialization method, behaves like default readObject
     * method. Restores the not-really-transient targetType field.
     *
     * @param in the {@code ObjectInputStream} to deserialize an {@code ExpressionWithTypeField} from
     * @throws IOException if reading from the input stream fails
     * @throws ClassNotFoundException if an object whose class is unknown is read from the input stream
     */
    private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        _targetType = ReflectionSerializer.readClass(in);
    }
}