/* * Grapht, an open source dependency injector. * Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt) * Copyright 2010-2014 Regents of the University of Minnesota * * 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 2.1 of the * License, or (at your option) any later version. * * 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.grouplens.grapht.util; import javax.annotation.Nullable; import java.io.InvalidObjectException; import java.io.ObjectStreamException; import java.io.Serializable; /** * InstanceProvider is a simple Provider that always provides the same instance. * * @author <a href="http://grouplens.org">GroupLens Research</a> * @param <T> */ public class InstanceProvider<T> implements TypedProvider<T>, Serializable { private static final long serialVersionUID = -1L; private final Class<?> providedType; private final transient T instance; // transient because serialization proxy takes care of it /** * Construct a new instance provider. * @param instance The instance. * @deprecated Use {@link Providers#of(Object)} instead. */ @SuppressWarnings("unused") @Deprecated public InstanceProvider(T instance) { this(instance, instance == null ? Object.class : instance.getClass()); } InstanceProvider(@Nullable T instance, Class<?> type) { if (instance != null && !type.isInstance(instance)) { throw new IllegalArgumentException("instance not of specified type"); } this.instance = instance; providedType = type; } @Override public Class<?> getProvidedType() { return providedType; } @Override public T get() { return instance; } @Override public String toString() { if (instance == null) { return "InstanceProvider{null<" + providedType.getName() + ">}"; } else { return "InstanceProvider{" + instance + "}"; } } private Object writeReplace() { return new SerialProxy(providedType, instance); } @SuppressWarnings("unused") private Object readObject() throws ObjectStreamException { throw new InvalidObjectException("must use serialization proxy"); } private static class SerialProxy implements Serializable { private static final long serialVersionUID = 1L; private ClassProxy type; @SuppressWarnings("squid:S1948") // serializable warning; node is serializable iff its label type is private Object instance; public SerialProxy(Class<?> t, Object i) { type = ClassProxy.of(t); instance = i; } @SuppressWarnings("unchecked") private Object readResolve() throws ObjectStreamException { Class<?> cls; try { cls = type.resolve(); } catch (ClassNotFoundException e) { InvalidObjectException ex = new InvalidObjectException("class not found"); ex.initCause(e); throw ex; } if (instance != null && !cls.isInstance(instance)) { throw new InvalidObjectException("instance is not of expected type"); } return new InstanceProvider(instance, cls); } } }