<commit_before>/*
 * 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.webbeans.ejb.common.component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.SessionBeanType;

import org.apache.webbeans.component.AbstractInjectionTargetBean;
import org.apache.webbeans.component.EnterpriseBeanMarker;
import org.apache.webbeans.component.WebBeansType;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.util.ClassUtil;

/**
 * Defines bean contract for the session beans.
 * 
 * @version $Rev$ $Date$
 */
public abstract class BaseEjbBean<T> extends AbstractInjectionTargetBean<T> implements EnterpriseBeanMarker
{
    /**Session bean type*/
    protected final SessionBeanType ejbType;
    
    /** Map of proxy instances to the dependent SFSB they've acquired but not yet removed */
    private Map<Object, Object> dependentSFSBToBeRemoved = new ConcurrentHashMap<Object, Object>();

    /**
     * Creates a new instance of the session bean.
     * @param ejbClassType ebj class type
     */
    public BaseEjbBean(Class<T> ejbClassType, SessionBeanType type)
    {
        super(WebBeansType.ENTERPRISE,ejbClassType);
        
        //type of the ejb
        this.ejbType = type;
        
        //Setting inherited meta data instance
        setInheritedMetaData();
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void injectFields(T instance, CreationalContext<T> creationalContext)
    {
        //No-operations
    }
    
    /* (non-Javadoc)
     * @see org.apache.webbeans.component.AbstractBean#isPassivationCapable()
     */
    @Override
    public boolean isPassivationCapable()
    {
        if(getEjbType().equals(SessionBeanType.STATEFUL))
        {
            return true;
        }
        
        return false;
    }

    /**
     * Inject session bean injected fields. It is called from
     * interceptor.
     * @param instance bean instance
     * @param creationalContext creational context instance
     */
    @SuppressWarnings("unchecked")
    public void injectFieldInInterceptor(Object instance, CreationalContext<?> creationalContext)
    {
        super.injectFields((T)instance, (CreationalContext<T>)creationalContext);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected T createComponentInstance(CreationalContext<T> creationalContext)
    {
        return getInstance(creationalContext);
    }
    
    /**
     * Sublclasses must return instance.
     * @param creationalContext creational context
     * @return instance
     */
    protected abstract T getInstance(CreationalContext<T> creationalContext);

    /**
     * {@inheritDoc}
     */
    @Override
    protected void destroyComponentInstance(T instance, CreationalContext<T> creational)
    {
        if (getEjbType().equals(SessionBeanType.STATEFUL))
        {
            if ((this.getScope() == Dependent.class))
            {
                try
                {
                    Object ejbInstance = getDependentSFSBForProxy(instance);
                    if (ejbInstance != null)
                    {
                        List<Method> methods = getRemoveMethods();
                        if (methods.size() > 0)
                        {
                            // FIXME: This needs to call an API from the EJB
                            // container to remove the EJB instance directly,
                            // not via a remove method.  For now, just call 1 
                            // remove method directly on the EJB
                            ClassUtil.callInstanceMethod(methods.get(0), ejbInstance, ClassUtil.OBJECT_EMPTY);
                        }
                    }
                }
                finally
                {
                    removeDependentSFSB(instance);
                }
            }
            else // normal scope  
            { 
                // The EjbBeanProxyHandler may not have actually obtained an EJB for this normal-scope Bean.
                Context webbeansContext = BeanManagerImpl.getManager().getContext(this.getScope());
                Object ejbInstance = webbeansContext.get(this);
                if (ejbInstance != null)
                {
                    List<Method> methods = getRemoveMethods();
                    if (methods.size() > 0) 
                    {   
                        // FIXME: This needs to call an API from the EJB
                        // container to remove the EJB instance directly,
                        // not via a remove method.  For now, just call 1 
                        // remove method directly on the EJB
                        ClassUtil.callInstanceMethod(methods.get(0), ejbInstance, ClassUtil.OBJECT_EMPTY);
                    }
                }
            }
        }
    }

    
    /**
     * Subclasses can override this.
     * @return remove methods
     */
    public List<Method> getRemoveMethods()
    {<commit_msg>[OWB-443] factor out the mechanism for removing the underlying EJB instance so it  can be easily overriden from a subclass of BaseEJBBean.<commit_after>/*
 * 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.webbeans.ejb.common.component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.SessionBeanType;

import org.apache.webbeans.component.AbstractInjectionTargetBean;
import org.apache.webbeans.component.EnterpriseBeanMarker;
import org.apache.webbeans.component.WebBeansType;
import org.apache.webbeans.container.BeanManagerImpl;
import org.apache.webbeans.util.ClassUtil;

/**
 * Defines bean contract for the session beans.
 * 
 * @version $Rev$ $Date$
 */
public abstract class BaseEjbBean<T> extends AbstractInjectionTargetBean<T> implements EnterpriseBeanMarker
{
    /**Session bean type*/
    protected final SessionBeanType ejbType;
    
    /** Map of proxy instances to the dependent SFSB they've acquired but not yet removed */
    private Map<Object, Object> dependentSFSBToBeRemoved = new ConcurrentHashMap<Object, Object>();

    /**
     * Creates a new instance of the session bean.
     * @param ejbClassType ebj class type
     */
    public BaseEjbBean(Class<T> ejbClassType, SessionBeanType type)
    {
        super(WebBeansType.ENTERPRISE,ejbClassType);
        
        //type of the ejb
        this.ejbType = type;
        
        //Setting inherited meta data instance
        setInheritedMetaData();
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void injectFields(T instance, CreationalContext<T> creationalContext)
    {
        //No-operations
    }
    
    /* (non-Javadoc)
     * @see org.apache.webbeans.component.AbstractBean#isPassivationCapable()
     */
    @Override
    public boolean isPassivationCapable()
    {
        if(getEjbType().equals(SessionBeanType.STATEFUL))
        {
            return true;
        }
        
        return false;
    }

    /**
     * Inject session bean injected fields. It is called from
     * interceptor.
     * @param instance bean instance
     * @param creationalContext creational context instance
     */
    @SuppressWarnings("unchecked")
    public void injectFieldInInterceptor(Object instance, CreationalContext<?> creationalContext)
    {
        super.injectFields((T)instance, (CreationalContext<T>)creationalContext);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected T createComponentInstance(CreationalContext<T> creationalContext)
    {
        return getInstance(creationalContext);
    }
    
    /**
     * Sublclasses must return instance.
     * @param creationalContext creational context
     * @return instance
     */
    protected abstract T getInstance(CreationalContext<T> creationalContext);

    /**
     * {@inheritDoc}
     */
    @Override
    protected void destroyComponentInstance(T instance, CreationalContext<T> creational)
    {
        if (getEjbType().equals(SessionBeanType.STATEFUL))
        {
            if ((this.getScope() == Dependent.class))
            {
                try
                {
                    Object ejbInstance = getDependentSFSBForProxy(instance);
                    if (ejbInstance != null)
                    {
                        destroyStatefulSessionBeanInstance(instance, ejbInstance);
                    }
                }
                finally
                {
                    removeDependentSFSB(instance);
                }
            }
            else // normal scope  
            { 
                // The EjbBeanProxyHandler may not have actually obtained an EJB for this normal-scope Bean.
                Context webbeansContext = BeanManagerImpl.getManager().getContext(this.getScope());
                Object ejbInstance = webbeansContext.get(this);
                if (ejbInstance != null)
                {
                    destroyStatefulSessionBeanInstance(instance, ejbInstance);
                }
            }
        }
    }

    /**
     * Called when we must ask the container to remove a specific
     * @param proxyInstance The contextual reference 
     * @param ejbInstance The underlying EJB instance to be removed
     */
    
    protected void destroyStatefulSessionBeanInstance(T proxyInstance, Object ejbInstance)
    {
        List<Method> methods = getRemoveMethods();
        if (methods.size() > 0) 
        {   
            // FIXME: This needs to call an API from the EJB
            // container to remove the EJB instance directly,
            // not via a remove method.  For now, just call 1 
            // remove method directly on the EJB
            ClassUtil.callInstanceMethod(methods.get(0), ejbInstance, ClassUtil.OBJECT_EMPTY);
        }
    }
    /**
     * Subclasses can override this.
     * @return remove methods
     */
    public List<Method> getRemoveMethods()
    {
{'fraction_non_alphanumeric': 0.08094876340001689, 'fraction_numerical': 0.001688191103232886, 'mean_word_length': 2.1978407557354926, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2896996', 'n_tokens_mistral': 3094, 'n_tokens_neox': 2981, 'n_words': 876}