Package org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation

Source Code of org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.DefaultConversation

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation;

import org.apache.myfaces.extensions.cdi.core.impl.scope.conversation.spi.BeanEntry;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.config.ConversationConfig;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.event.CloseConversationEvent;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.event.RestartConversationEvent;
import org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi.ConversationKey;
import org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.spi.EditableConversation;
import org.apache.myfaces.extensions.cdi.jsf.impl.util.RequestCache;

import javax.enterprise.inject.Typed;
import javax.enterprise.inject.spi.BeanManager;
import java.io.Serializable;
import java.util.Set;

/**
* {@inheritDoc}
*/
@Typed()
public class DefaultConversation implements EditableConversation
{
    private static final long serialVersionUID = -2958548175169003298L;

    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
    private final ConversationKey conversationKey;
    private ConversationExpirationEvaluator expirationEvaluator;

    //all implementations will be serializable
    private BeanManager beanManager;

    private final BeanStorage beanStorage;

    private final boolean closeConversationEventEnable;
    private final boolean restartConversationEventEnable;

    /**
     * Constructor which creates a conversation for the given
     * {@link ConversationKey}, {@link ConversationExpirationEvaluator}, {@link ConversationConfig}
     * and {@link BeanManager}
     * @param conversationKey key of the current conversation
     * @param expirationEvaluator expiration strategy which decides if the current conversation is expired
     * @param conversationConfig current conversation-config
     * @param beanManager current bean-manager
     */
    public DefaultConversation(ConversationKey conversationKey,
                               ConversationExpirationEvaluator expirationEvaluator,
                               ConversationConfig conversationConfig,
                               BeanManager beanManager)
    {
        this.conversationKey = conversationKey;
        this.expirationEvaluator = expirationEvaluator;
        this.beanManager = beanManager;
        this.beanStorage = new BeanStorage(this.beanManager);

        this.closeConversationEventEnable = conversationConfig.isCloseConversationEventEnabled();
        this.restartConversationEventEnable = conversationConfig.isRestartConversationEventEnabled();

        if(this.expirationEvaluator instanceof ConversationAware)
        {
            ((ConversationAware)this.expirationEvaluator).setConversation(this);
        }
    }

    //just for a better performance to avoid frequent calls to the {@link #expirationEvaluator}
    private boolean active;

    /**
     * {@inheritDoc}
     */
    public boolean isActive()
    {
        return !isConversationExpired() && this.active;
    }

    /**
     * {@inheritDoc}
     */
    public boolean getActiveState()
    {
        return active;
    }

    /**
     * {@inheritDoc}
     */
    public void deactivate()
    {
        this.expirationEvaluator.expire();
        if (this.expirationEvaluator.isExpired())
        {
            endConversation();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void close()
    {
        fireCloseConversationEvent();

        if(this.active)
        {
            endConversation();
        }
    }

    private void endConversation()
    {
        this.active = false;
        this.beanStorage.resetStorage();
        RequestCache.resetConversationCache();
    }

    /**
     * {@inheritDoc}
     */
    public void restart()
    {
        fireRestartConversationEvent();
        touchConversation();
        this.beanStorage.resetStorage();
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings({"unchecked"})
    public <T> T getBean(Class<T> key)
    {
        if (!this.active)
        {
            return null;
        }

        BeanEntry scopedBean = this.beanStorage.getBean(key);

        if (scopedBean == null)
        {
            return null;
        }

        touchConversation();

        return (T) scopedBean.getBeanInstance();
    }

    public <T> Set<Class<T>> getBeanSubGroup(Class<T> key)
    {
        return this.beanStorage.getBeanSubGroup(key);
    }

    /**
     * {@inheritDoc}
     */
    public <T> void addBean(BeanEntry<T> beanEntry)
    {
        //TODO check if conversation is active
        touchConversation();

        //TODO
        //noinspection unchecked
        this.beanStorage.addBean((BeanEntry<Serializable>) beanEntry);
    }

    /**
     * {@inheritDoc}
     */
    public <T> BeanEntry<T> removeBeanEntry(Class<T> type)
    {
        return (BeanEntry<T>) this.beanStorage.removeBean((Class<Serializable>) type);
    }

    private boolean isConversationExpired()
    {
        return this.expirationEvaluator.isExpired();
    }

    private void touchConversation()
    {
        this.active = true;

        this.expirationEvaluator.touch();
    }

    /**
     * just for test-cases (to expire a conversation manually)
     * @return current conversation-expiration-evaluator
     */
    public ConversationExpirationEvaluator getExpirationEvaluator()
    {
        return expirationEvaluator;
    }

    private void fireCloseConversationEvent()
    {
        if(this.closeConversationEventEnable)
        {
            this.beanManager.fireEvent(new CloseConversationEvent(this));
        }
    }

    private void fireRestartConversationEvent()
    {
        if(this.restartConversationEventEnable)
        {
            this.beanManager.fireEvent(new RestartConversationEvent(this));
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString()
    {
        StringBuilder result = new StringBuilder();

        result.append("\n*** conversation - start ***\n");
        result.append(this.conversationKey);

        result.append("\n");
        result.append("active state: ");
        result.append(getActiveState());
        result.append("\n");

        result.append(this.beanStorage);

        result.append("\n");
        result.append("expiration-evaluator: ");
        result.append(this.expirationEvaluator.getClass().getName());
        result.append("\n*** conversation - end ***");

        return result.toString();
    }
}
TOP

Related Classes of org.apache.myfaces.extensions.cdi.jsf.impl.scope.conversation.DefaultConversation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.