/*
* Copyright (C) 2012, 2016 higherfrequencytrading.com
* Copyright (C) 2016 Roman Leventov
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.chronicle.hash.serialization;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.set.ChronicleSet;
/**
* {@link Cloneable}-like interface used by Chronicle Map to populate stateful serializer
* implementations for each isolated site (thread + Chronicle Map instance + objects domain).
* Stateful implementations of serialization interfaces ({@link SizedReader}, {@link SizedWriter},
* {@link BytesReader}, {@link BytesWriter} or {@link DataAccess}), configured for {@link
* ChronicleMap} or {@link ChronicleSet} in builder, should implement the {@code StatefulCopyable}
* interface.
*
* <p>See <a href="https://github.com/OpenHFT/Chronicle-Map#understanding-statefulcopyable">
* Understanding {@code StatefulCopyable}</a> section in the Chronicle Map tutorial for more info
* on how to implement and use this interface properly, and for examples.
*
* @param <T> the type of marshaller, implementing this interface
*/
public interface StatefulCopyable<T extends StatefulCopyable<T>> {
/**
* Creates a copy of this marshaller, with independent state. The current state itself shouldn't
* be copied (it could be "clear" in the copy), only "configuration" of the instance, on which
* {@code copy()} is called, should be inherited in the copy (e. g. the class of objects
* serialized). So, {@code copy()} should be transitive, i. e. {@code marshaller.copy()} and
* {@code marshaller.copy().copy()} should result to identical instances.
*
* <p>The state of the instance on which {@code copy()} is called shouldn't be changed.
*
* <p>If some marshaller is ought to implement {@code StatefulCopyable} interface (e. g.
* {@link DataAccess}) but is stateless actually, it could return {@code this} from this method.
*
* @return the copy if this marshaller with the same configuration, but independent state
*/
T copy();
/**
* Checks if {@code possiblyStatefulCopyable} implements {@code StatefulCopyable}, then returns
* {@link #copy()} of it, otherwise returns the {@code possiblyStatefulCopyable} itself.
*
* @param possiblyStatefulCopyable the instance to {@code copy()} if it implements {@code
* StatefulCopyable}, or to return without modification
* @param <T> the type of the passed instance
* @return the copy of the passed instance with independent state, of the instance back, if it
* doesn't implement {@code StatefulCopyable}
*/
static <T> T copyIfNeeded(T possiblyStatefulCopyable) {
if (possiblyStatefulCopyable instanceof StatefulCopyable) {
//noinspection unchecked
return (T) ((StatefulCopyable) possiblyStatefulCopyable).copy();
}
return possiblyStatefulCopyable;
}
}