Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
   *
   * Use is subject to license terms.
   *
   * 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 static org.jboss.weld.context.conversation.ConversationIdGenerator.CONVERSATION_ID_GENERATOR_ATTRIBUTE_NAME;
 import static org.jboss.weld.util.reflection.Reflections.cast;
 
 import java.util.Map;
 
 
The base of the conversation context, which can use a variety of storage forms

Author(s):
Pete Muir
Jozef Hartinger
George Sapountzis
Marko Luksa
 
 public abstract class AbstractConversationContext<R, S> extends AbstractBoundContext<R> implements ConversationContext {
 
     private static final String CURRENT_CONVERSATION_ATTRIBUTE_NAME = ConversationContext.class.getName() + ".currentConversation";
     public static final String CONVERSATIONS_ATTRIBUTE_NAME = ConversationContext.class.getName() + ".conversations";
 
     private static final long DEFAULT_TIMEOUT = 10 * 60 * 1000L;
     private static final long CONCURRENT_ACCESS_TIMEOUT = 1000L;
     private static final String PARAMETER_NAME = "cid";
 
     private final AtomicReference<StringparameterName;
     private final AtomicLong defaultTimeout;
     private final AtomicLong concurrentAccessTimeout;
 
     private final ThreadLocal<R> associated;
 
     private final BeanManagerImpl manager;
 
     private final BeanIdentifierIndex beanIdentifierIndex;
         @Override
         protected FastEvent<StringcomputeValue() {
             return FastEvent.of(String.class.getGlobalLenientObserverNotifier(), .);
         }
     };
 
     public AbstractConversationContext(String contextIdBeanIdentifierIndex beanIdentifierIndex) {
         super(contextIdtrue);
         this. = new AtomicReference<String>();
         this. = new AtomicLong();
         this. = new ThreadLocal<R>();
         this. = Container.instance(contextId).deploymentManager();
         this. = beanIdentifierIndex;
     }
 
     @Override
    public String getParameterName() {
        return .get();
    }
    @Override
    public void setParameterName(String cid) {
        this..set(cid);
    }
    @Override
    public void setConcurrentAccessTimeout(long timeout) {
        this..set(timeout);
    }
    @Override
    public long getConcurrentAccessTimeout() {
        return .get();
    }
    @Override
    public void setDefaultTimeout(long timeout) {
        this..set(timeout);
    }
    @Override
    public long getDefaultTimeout() {
        return .get();
    }
    @Override
    public boolean associate(R request) {
            this..set(request);
            /*
            * We need to delay attaching the bean store until activate() is called
            * so that we can attach the correct conversation id
            *
            * We may need access to the conversation id generator and
            * conversations. If the session already exists, we can load it from
            * there, otherwise we can create a new conversation id generator and
            * conversations collection. If the the session exists when the request
            * is dissociated, then we store them in the session then.
            *
            * We always store the generator and conversation map in the request
            * for temporary usage.
            */
            if (getSessionAttribute(requestfalse) == null) {
                ConversationIdGenerator generator = new ConversationIdGenerator();
                setRequestAttribute(requestgenerator);
                setSessionAttribute(requestgeneratorfalse);
            } else {
            }
            if (getSessionAttribute(requestfalse) == null) {
                Map<StringManagedConversationconversations = Collections.synchronizedMap(new HashMap<StringManagedConversation>());
                setRequestAttribute(requestconversations);
                setSessionAttribute(requestconversationsfalse);
            } else {
                setRequestAttribute(requestgetSessionAttribute(requesttrue));
            }
            return true;
    }
    @Override
    public boolean dissociate(R request) {
        if (isAssociated()) {
            try {
                return true;
            } finally {
                this..set(null);
                cleanup();
            }
        } else {
            return false;
        }
    }
        if (!isAssociated()) {
            return;
        }
        final R request = .get();
        /*
        * If the session is available, store the conversation id generator and
        * conversations if necessary.
        */
        if (getSessionAttribute(requestfalse) == null) {
        }
        if (getSessionAttribute(requestfalse) == null) {
        }
    }
    public void sessionCreated() {
    }
    protected void associateRequestWithNewConversation() {
        ManagedConversation conversation = new ConversationImpl();
        lock(conversation);
        // Set a temporary bean store, this will be attached at the end of the request if needed
        NamingScheme namingScheme = new ConversationNamingScheme(getNamingSchemePrefix(), "transient");
        setBeanStore(createRequestBeanStore(namingSchemegetRequest()));
    }
    protected void associateRequest(ManagedConversation conversation) {
        NamingScheme namingScheme = new ConversationNamingScheme(getNamingSchemePrefix(), conversation.getId(), );
        setBeanStore(createRequestBeanStore(namingSchemegetRequest()));
        getBeanStore().attach();
    }
    @Override
    public void activate() {
        this.activate(null);
    }
    @Override
    public void activate(String cid) {
        if (!isAssociated()) {
        }
        if (!isActive()) {
            super.setActive(true);
        } else {
        }
        initialize(cid);
    }
    protected void initialize(String cid) {
        // Attach the conversation
        // WELD-1315 Don't try to restore the long-running conversation if cid param is empty
        if (cid != null && !cid.isEmpty()) {
            ManagedConversation conversation = getConversation(cid);
            if (conversation != null && !isExpired(conversation)) {
                boolean lock = lock(conversation);
                if (lock) {
                    // WELD-1690 Don't associate a conversation which was ended (race condition)
                    if(conversation.isTransient()) {
                        associateRequestWithNewConversation();
                        throw ..noConversationFoundToRestore(cid);
                    }
                    associateRequest(conversation);
                } else {
                    // CDI 6.7.4 we must activate a new transient conversation before we throw the exception
                    associateRequestWithNewConversation();
                    throw ..conversationLockTimedout(cid);
                }
            } else {
                // CDI 6.7.4 we must activate a new transient conversation before we throw the exception
                associateRequestWithNewConversation();
                throw ..noConversationFoundToRestore(cid);
            }
        } else {
            associateRequestWithNewConversation();
        }
    }
    private boolean lock(ManagedConversation conversation) {
        return conversation.lock(getConcurrentAccessTimeout());
    }
    @Override
    public void deactivate() {
        // Disassociate from the current conversation
        if (isActive()) {
            if (!isAssociated()) {
                throw ..mustCallAssociateBeforeDeactivate();
            }
            try {
                if (getCurrentConversation().isTransient() && getRequestAttribute(getRequest(), .) != null) {
                    // WELD-1746 Don't destroy ended conversations - these must be destroyed in a synchronized block - see also cleanUpConversationMap()
                    destroy();
                } else {
                    // Update the conversation timestamp
                    getCurrentConversation().touch();
                    if (!getBeanStore().isAttached()) {
                        /*
                         * This was a transient conversation at the beginning of the request, so we need to update the CID it uses, and attach it. We also add
                         * it to the conversations the session knows about.
                         */
                        if (!(getRequestAttribute(getRequest(), .instanceof ConversationNamingScheme)) {
                            throw ..conversationNamingSchemeNotFound();
                        }
                                .getId());
                        getBeanStore().attach();
                        getConversationMap().put(getCurrentConversation().getId(), getCurrentConversation());
                    }
                }
            } finally {
                // WELD-1690 always try to unlock the current conversation
                getCurrentConversation().unlock();
                // WELD-1802
                setBeanStore(null);
                // Clean up any expired/ended conversations
                cleanUpConversationMap();
                // deactivate the context
                super.setActive(false);
            }
        } else {
            throw ..contextNotActive();
        }
    }
    private void cleanUpConversationMap() {
        Map<StringManagedConversationconversations = getConversationMap();
        synchronized (conversations) {
            Iterator<Entry<StringManagedConversation>> entryIterator = conversations.entrySet().iterator();
            while (entryIterator.hasNext()) {
                Entry<StringManagedConversationentry = entryIterator.next();
                if (entry.getValue().isTransient()) {
                    destroyConversation(getSessionFromRequest(getRequest(), false), entry.getKey());
                    entryIterator.remove();
                }
            }
        }
    }
    public void conversationPromotedToLongRunning(ConversationImpl conversation) {
        getConversationMap().put(conversation.getId(), conversation);
    }
    @Override
    public void invalidate() {
        ManagedConversation currentConversation = getCurrentConversation();
        Map<StringManagedConversationconversations = getConversationMap();
        synchronized (conversations) {
            for (Entry<StringManagedConversationstringManagedConversationEntry : conversations.entrySet()) {
                ManagedConversation conversation = stringManagedConversationEntry.getValue();
                if (!currentConversation.equals(conversation) && !conversation.isTransient() && isExpired(conversation)) {
                    // Try to lock the conversation and log warning if not successful - unlocking should not be necessary
                    if (!conversation.lock(0)) {
                        ..endLockedConversation(conversation.getId());
                    }
                    conversation.end();
                }
            }
        }
    }
    public boolean destroy(S session) {
        // the context may be active
        // if it is, we need to re-attach the bean store once the other conversations are destroyed
        BoundBeanStore beanStore = getBeanStore();
        final boolean active = isActive();
        if (beanStore != null) {
            beanStore.detach();
        }
        try {
            if (getSessionAttributeFromSession(sessioninstanceof Map<?, ?>) {
                // if there are conversations to destroy
                Map<StringManagedConversationconversations = cast(getSessionAttributeFromSession(session));
                // if the context is not active, let's activate it
                setActive(true);
                for (ManagedConversation conversation : conversations.values()) {
                    String id = conversation.getId();
                    if (!conversation.isTransient()) {
                        // the currently associated conversation will be destroyed at the end of the current request
                        conversation.end();
                    }
                    if (!isCurrentConversation(id)) {
                        // a conversation that is not currently associated is destroyed immediately
                        destroyConversation(sessionid);
                    }
                }
            }
            return true;
        } finally {
            setBeanStore(beanStore);
            setActive(active);
            if (beanStore != null) {
                getBeanStore().attach();
            } else if (!isActive()){
                cleanup();
            }
        }
    }
    private boolean isCurrentConversation(String id) {
        if (!isAssociated()) {
            return false;
        }
        return id !=null && id.equals(getCurrentConversation().getId());
    }
    protected void destroyConversation(S sessionString id) {
        if (session != null) {
            // session can be null as we may have nothing in the session
            getBeanStore().attach();
            destroy();
            getBeanStore().detach();
            setBeanStore(null);
            .get().fire(id);
        }
    }
    @Override
    public String generateConversationId() {
        if (!isAssociated()) {
        }
        }
        checkContextInitialized();
        return generator.call();
    }
    private static boolean isExpired(ManagedConversation conversation) {
        return System.currentTimeMillis() > (conversation.getLastUsed() + conversation.getTimeout());
    }
    @Override
        return getConversationMap().get(id);
    }
    @Override
        // Don't return the map view to avoid concurrency issues
        Map<StringManagedConversationconversations = getConversationMap();
        synchronized (conversations) {
            return new HashSet<ManagedConversation>(conversations.values());
        }
    }
    private void checkIsAssociated() {
        if (!isAssociated()) {
        }
    }
        checkIsAssociated();
        checkContextInitialized();
        R request = getRequest();
        Object attribute = getRequestAttribute(request);
        if (attribute == null || !(attribute instanceof Map)) {
            throw ..unableToLoadConversations(attributerequest);
        }
        return cast(attribute);
    }
    @Override
        checkIsAssociated();
        checkContextInitialized();
        R request = getRequest();
        Object attribute = getRequestAttribute(request);
        if (attribute == null || !(attribute instanceof ManagedConversation)) {
        }
        return (ManagedConversationattribute;
    }
    @Override
    public Class<? extends AnnotationgetScope() {
        return ConversationScoped.class;
    }

    
Set an attribute in the session.

Parameters:
request the request to set the session attribute in
name the name of the attribute
value the value of the attribute
create if false, the attribute will only be set if the session already exists, otherwise it will always be set
Throws:
java.lang.IllegalStateException if create is true, and the session can't be created
    protected abstract void setSessionAttribute(R requestString nameObject valueboolean create);

    
Get an attribute value from the session.

Parameters:
request the request to get the session attribute from
name the name of the attribute
create if false, the attribute will only be retrieved if the session already exists, other wise it will always be retrieved
Returns:
attribute
Throws:
java.lang.IllegalStateException if create is true, and the session can't be created
    protected abstract Object getSessionAttribute(R requestString nameboolean create);

    
Get an attribute value from the session.

Parameters:
session the session to get the session attribute from
name the name of the attribute
Returns:
attribute
Throws:
java.lang.IllegalStateException if create is true, and the session can't be created
    protected abstract Object getSessionAttributeFromSession(S sessionString name);

    
Remove an attribute from the request.

Parameters:
request the request to remove the attribute from
name the name of the attribute
    protected abstract void removeRequestAttribute(R requestString name);

    
Set an attribute in the request.

Parameters:
request the request to set the attribute from
name the name of the attribute
value the value of the attribute
    protected abstract void setRequestAttribute(R requestString nameObject value);

    
Retrieve an attribute value from the request

Parameters:
request the request to get the attribute from
name the name of the attribute to get
Returns:
the value of the attribute
    protected abstract Object getRequestAttribute(R requestString name);
    protected abstract BoundBeanStore createRequestBeanStore(NamingScheme namingScheme, R request);
    protected abstract BoundBeanStore createSessionBeanStore(NamingScheme namingScheme, S session);
    protected abstract S getSessionFromRequest(R requestboolean create);
    protected abstract String getNamingSchemePrefix();

    
Check if the context is currently associated

Returns:
true if the context is associated
    protected boolean isAssociated() {
        return .get() != null;
    }

    
Get the associated store

Returns:
the request
    protected R getRequest() {
        return .get();
    }
New to GrepCode? Check out our FAQ X