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

org.jboss.weld.context.SerializableContextualImpl Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat, Inc., and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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 org.jboss.weld.context;

import java.io.Serializable;

import javax.enterprise.context.spi.Contextual;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import org.jboss.weld.Container;
import org.jboss.weld.serialization.spi.ContextualStore;
import org.jboss.weld.serialization.spi.helpers.SerializableContextual;

/**
 * A serializable version of contextual that knows how to restore the
 * original bean if necessary
 *
 * @author pmuir
 */
public class SerializableContextualImpl, I> extends ForwardingContextual implements SerializableContextual {

    @Override
    protected Contextual delegate() {
        return get();
    }

    private static final long serialVersionUID = 9161034819867283482L;

    // A directly serializable contextual
    private C serialiazable;
    @SuppressWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "A cache which is lazily loaded")
    // A cached, transient version of the contextual
    private transient C cached;

    // the id of a non-serializable, passivation capable contextual
    private String id;

    private transient ContextualStore cachedContextualStore;

    @java.lang.SuppressWarnings("unused")
    private SerializableContextualImpl() {
    }

    public SerializableContextualImpl(C contextual, ContextualStore contextualStore) {
        this.cachedContextualStore = contextualStore;
        if (contextual instanceof Serializable) {
            // the contextual is serializable, so we can just use it
            this.serialiazable = contextual;
        } else {
            // otherwise, generate an id (may not be portable between container instances)
            this.id = contextualStore.putIfAbsent(contextual);
        }
        // cache the contextual
        this.cached = contextual;
    }

    private ContextualStore getContextualStore() {
        if (cachedContextualStore == null) {
            this.cachedContextualStore = Container.instance().services().get(ContextualStore.class);
        }
        return this.cachedContextualStore;
    }

    public C get() {
        if (cached == null) {
            loadContextual();
        }
        return cached;
    }

    private void loadContextual() {
        if (serialiazable != null) {
            this.cached = serialiazable;
        } else if (id != null) {
            this.cached = getContextualStore().getContextual(id);
        }
        if (this.cached == null) {
            throw new IllegalStateException("Error restoring serialized contextual with id " + id);
        }
    }

    @Override
    public boolean equals(Object obj) {
        // if the arriving object is also a SerializableContextual, then unwrap it
        if (obj instanceof SerializableContextualImpl) {
            return delegate().equals(((SerializableContextualImpl) obj).get());
        } else {
            return delegate().equals(obj);
        }
    }

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

}