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

org.jboss.weld.context.AbstractContext 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 javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.spi.AlterableContext;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;

import org.jboss.weld.Container;
import org.jboss.weld.bootstrap.api.ServiceRegistry;
import org.jboss.weld.context.api.ContextualInstance;
import org.jboss.weld.context.beanstore.BeanStore;
import org.jboss.weld.context.beanstore.LockedBean;
import org.jboss.weld.context.cache.RequestScopedBeanCache;
import org.jboss.weld.logging.ContextLogger;
import org.jboss.weld.serialization.spi.BeanIdentifier;
import org.jboss.weld.serialization.spi.ContextualStore;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;

/**
 * Base for the Context implementations. Delegates calls to the abstract
 * getBeanStore and getActive to allow for different implementations (storage
 * types and ThreadLocal vs. shared)
 *
 * @author Nicklas Karlsson
 * @author Pete Muir
 * @see org.jboss.weld.contexts.SharedContext
 * @see org.jboss.weld.context.BasicContext
 */
public abstract class AbstractContext implements AlterableContext {

    private final boolean multithreaded;

    private final ServiceRegistry serviceRegistry;

    /**
     * Constructor
     *
     */
    public AbstractContext(String contextId, boolean multithreaded) {
        this.multithreaded = multithreaded;
        this.serviceRegistry = Container.instance(contextId).services();
    }

    /**
     * Get the bean if it exists in the contexts.
     *
     * @return An instance of the bean
     * @throws ContextNotActiveException if the context is not active
     * @see javax.enterprise.context.spi.Context#get(BaseBean, boolean)
     */
    @Override
    @SuppressWarnings(value = "UL_UNRELEASED_LOCK", justification = "False positive from FindBugs")
    public  T get(Contextual contextual, CreationalContext creationalContext) {
        if (!isActive()) {
            throw new ContextNotActiveException();
        }
        checkContextInitialized();
        BeanStore beanStore = getBeanStore();
        if (beanStore == null) {
            return null;
        }
        if (contextual == null) {
            throw ContextLogger.LOG.contextualIsNull();
        }
        BeanIdentifier id = getId(contextual);
        ContextualInstance beanInstance = beanStore.get(id);
        if (beanInstance != null) {
            return beanInstance.getInstance();
        } else if (creationalContext != null) {
            LockedBean lock = null;
            try {
                if (multithreaded) {
                    lock = beanStore.lock(id);
                    beanInstance = beanStore.get(id);
                    if (beanInstance != null) {
                        return beanInstance.getInstance();
                    }
                }
                T instance = contextual.create(creationalContext);
                if (instance != null) {
                    beanInstance = new SerializableContextualInstanceImpl, T>(contextual, instance, creationalContext, serviceRegistry.get(ContextualStore.class));
                    getBeanStore().put(id, beanInstance);
                }
                return instance;
            } finally {
                if (lock != null) {
                    lock.unlock();
                }
            }
        } else {
            return null;
        }
    }

    @Override
    public  T get(Contextual contextual) {
        return get(contextual, null);
    }

    @Override
    public void destroy(Contextual contextual) {
        if (!isActive()) {
            throw new ContextNotActiveException();
        }
        checkContextInitialized();
        if (contextual == null) {
            throw ContextLogger.LOG.contextualIsNull();
        }
        if (getBeanStore() == null) {
            throw ContextLogger.LOG.noBeanStoreAvailable(this);
        }
        BeanIdentifier id = getId(contextual);
        ContextualInstance beanInstance = getBeanStore().remove(id);
        if (beanInstance != null) {
            RequestScopedBeanCache.invalidate();
            destroyContextualInstance(beanInstance);
        }
    }

    private  ContextualInstance getContextualInstance(BeanIdentifier id) {
        if (getBeanStore() == null) {
            throw ContextLogger.LOG.noBeanStoreAvailable(this);
        }
        return getBeanStore().get(id);
    }

    private  void destroyContextualInstance(ContextualInstance instance) {
        instance.getContextual().destroy(instance.getInstance(), instance.getCreationalContext());
        ContextLogger.LOG.contextualInstanceRemoved(instance, this);
    }

    /**
     * Destroys the context
     */
    protected void destroy() {
        ContextLogger.LOG.contextCleared(this);
        if (getBeanStore() == null) {
            throw ContextLogger.LOG.noBeanStoreAvailable(this);
        }
        for (BeanIdentifier id : getBeanStore()) {
            destroyContextualInstance(getContextualInstance(id));
        }
        getBeanStore().clear();
    }

    /**
     * A method that returns the actual bean store implementation
     *
     * @return The bean store
     */
    protected abstract BeanStore getBeanStore();

    public void cleanup() {
        if (getBeanStore() != null) {
            getBeanStore().clear();
        }
    }

    protected static  Contextual getContextual(String contextId, String id) {
        return Container.instance(contextId).services().get(ContextualStore.class)., T>getContextual(id);
    }

    protected BeanIdentifier getId(Contextual contextual) {
        return serviceRegistry.get(ContextualStore.class).putIfAbsent(contextual);
    }

    protected ServiceRegistry getServiceRegistry() {
        return serviceRegistry;
    }

    /**
     * Allows contexts that are initialized lazily to plug in additional logic.
     */
    protected void checkContextInitialized() {
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy