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

com.github.richardballard.arbeeutils.execution.SerialisableOptional Maven / Gradle / Ivy

There is a newer version: 2.0
Show newest version
/*
 * (C) Copyright 2016 Richard Ballard.
 *
 * 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 com.github.richardballard.arbeeutils.execution;

import com.google.common.base.Preconditions;
import net.jcip.annotations.Immutable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Objects;
import java.util.Optional;

/**
 * NOTE - This code is taken almost verbatim from a CodeFx
 * blog here.  The original source has the unlicensed licence.  For a description
 * of the motivation for this class see  optional;

    // CONSTRUCTION AND TRANSFORMATION

    private SerialisableOptional(@NotNull final Optional optional) {
        Preconditions.checkNotNull(optional,
                                   "The argument 'optional' must not be null.");

        this.optional = optional;
    }

    /**
     * Creates a serialisable optional from the specified optional.
     *
     * @param 
     *            the type of the wrapped value
     * @param optional
     *            the {@link Optional} from which the serialisable wrapper will be created
     * @return an instance which wraps the specified optional
     */
    @NotNull
    public static  SerialisableOptional fromOptional(@NotNull final Optional optional) {
        assert optional != null;

        return new SerialisableOptional<>(optional);
    }

    /**
     * Creates a serialisable optional which wraps an empty optional.
     *
     * @param 
     *            the type of the non-existent value
     * @return an instance which wraps an {@link Optional#empty() empty} {@link Optional}
     * @see Optional#of(Object)
     */
    @NotNull
    public static  SerialisableOptional empty() {
        return new SerialisableOptional<>(Optional.empty());
    }

    /**
     * Creates a serialisable optional for the specified, non-null value by wrapping it in an {@link Optional}.
     *
     * @param 
     *            the type of the wrapped value
     * @param value
     *            the value which will be contained in the wrapped {@link Optional}; must not be null
     * @return an instance which wraps the an optional for the specified value
     * @throws NullPointerException
     *             if value is null
     * @see Optional#of(Object)
     */
    @SuppressWarnings("ProhibitedExceptionDeclared")
    @NotNull
    public static  SerialisableOptional of(@NotNull final T value) throws NullPointerException {
        Objects.requireNonNull(value);

        return new SerialisableOptional<>(Optional.of(value));
    }

    /**
     * Creates a serialisable optional for the specified, possibly null value by wrapping it in an {@link Optional}.
     *
     * @param 
     *            the type of the wrapped value
     * @param value
     *            the value which will be contained in the wrapped {@link Optional}; may be null
     * @return an instance which wraps the an optional for the specified value
     * @see Optional#ofNullable(Object)
     */
    @NotNull
    public static  SerialisableOptional ofNullable(@Nullable final T value) {
        return new SerialisableOptional<>(Optional.ofNullable(value));
    }

    /**
     * Returns the {@code Optional} instance with which this instance was created.
     *
     * @return this instance as an {@link Optional}
     */
    @NotNull
    public Optional asOptional() {
        return optional;
    }

    @Override
    public boolean equals(final Object o) {
        if(this == o) {
            return true;
        }
        if(o == null || getClass() != o.getClass()) {
            return false;
        }

        final SerialisableOptional that = (SerialisableOptional) o;

        return optional.equals(that.optional);
    }

    @Override
    public int hashCode() {
        return optional.hashCode();
    }

    @Override
    public String toString() {
        return "SerialisableOptional{" +
               "optional=" + optional +
               '}';
    }

    // SERIALIZATION

    @NotNull
    protected Object writeReplace() {
        return new SerialisationProxy<>(this);
    }

    @SuppressWarnings("OverlyBroadThrowsClause")
    private void readObject(@NotNull final ObjectInputStream in) throws IOException, ClassNotFoundException {
        throw new InvalidObjectException("Serialisation proxy expected.");
    }

    @Immutable
    private static class SerialisationProxy implements Serializable {

        private static final long serialVersionUID = -1326520485869949065L;

        @Nullable
        private final T value;

        public SerialisationProxy(@NotNull final SerialisableOptional serialisableOptional) {
            assert serialisableOptional != null;

            value = serialisableOptional.asOptional().orElse(null);
        }

        @Nullable
        private Object readResolve() {
            return ofNullable(value);
        }

    }

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy