<commit_before>package groovy.lang;

import org.codehaus.groovy.runtime.InvokerHelper;

import java.beans.IntrospectionException;

/**
 * As subclass of MetaClass, ProxyMetaClass manages calls from Groovy Objects to POJOs.
 * It enriches MetaClass with the feature of making method invokations interceptable by
 * an Interceptor. To this end, it acts as a decorator (decorator pattern) allowing
 * to add or withdraw this feature at runtime.
 * See groovy/lang/InterceptorTest.groovy for details.
 * @author <NAME>
 */
public class ProxyMetaClass extends MetaClassImpl {

    protected MetaClass adaptee = null;
    protected Interceptor interceptor = null;

    /**
     * convenience factory method for the most usual case.
     */
    public static ProxyMetaClass getInstance(Class theClass) throws IntrospectionException {
        MetaClassRegistry metaRegistry = InvokerHelper.getInstance().getMetaRegistry();
        MetaClass meta = metaRegistry.getMetaClass(theClass);
        return new ProxyMetaClass(metaRegistry, theClass, meta);
    }
    /**
     * @param adaptee   the MetaClass to decorate with interceptability
     */
    public ProxyMetaClass(MetaClassRegistry registry, Class theClass, MetaClass adaptee) throws IntrospectionException {
        super(registry, theClass);
        this.adaptee = adaptee;
        if (null == adaptee) throw new IllegalArgumentException("adaptee must not be null");
    }

    /**
     * Use the ProxyMetaClass for the given Closure.
     * Cares for balanced register/unregister.
     * @param closure piece of code to be executed with registered ProxyMetaClass
     */
    public void use(Closure closure){
        registry.setMetaClass(theClass, this);
        closure.call();
        registry.setMetaClass(theClass, adaptee);
    }

     /**
     * Use the ProxyMetaClass for the given Closure.
     * Cares for balanced setting/unsetting ProxyMetaClass.
     * @param closure piece of code to be executed with ProxyMetaClass
     */
    public void use(GroovyObject object, Closure closure){
        object.setMetaClass(this);
        closure.call();
        object.setMetaClass(adaptee);
    }

    /**
     * @return the interceptor in use or null if no interceptor is used
     */
    public Interceptor getInterceptor() {
        return interceptor;
    }

    /**
     * @param interceptor may be null to reset any interception
     */
    public void setInterceptor(Interceptor interceptor) {
        this.interceptor = interceptor;
    }

    /**
     * Call invokeMethod on adaptee with logic like in MetaClass unless we have an Interceptor.
     * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods.<commit_msg>Fix a problem with use(0 when the closure throws an exception<commit_after>package groovy.lang;

import org.codehaus.groovy.runtime.InvokerHelper;

import java.beans.IntrospectionException;

/**
 * As subclass of MetaClass, ProxyMetaClass manages calls from Groovy Objects to POJOs.
 * It enriches MetaClass with the feature of making method invokations interceptable by
 * an Interceptor. To this end, it acts as a decorator (decorator pattern) allowing
 * to add or withdraw this feature at runtime.
 * See groovy/lang/InterceptorTest.groovy for details.
 * @author <NAME>
 */
public class ProxyMetaClass extends MetaClassImpl {

    protected MetaClass adaptee = null;
    protected Interceptor interceptor = null;

    /**
     * convenience factory method for the most usual case.
     */
    public static ProxyMetaClass getInstance(Class theClass) throws IntrospectionException {
        MetaClassRegistry metaRegistry = InvokerHelper.getInstance().getMetaRegistry();
        MetaClass meta = metaRegistry.getMetaClass(theClass);
        return new ProxyMetaClass(metaRegistry, theClass, meta);
    }
    /**
     * @param adaptee   the MetaClass to decorate with interceptability
     */
    public ProxyMetaClass(MetaClassRegistry registry, Class theClass, MetaClass adaptee) throws IntrospectionException {
        super(registry, theClass);
        this.adaptee = adaptee;
        if (null == adaptee) throw new IllegalArgumentException("adaptee must not be null");
    }

    /**
     * Use the ProxyMetaClass for the given Closure.
     * Cares for balanced register/unregister.
     * @param closure piece of code to be executed with registered ProxyMetaClass
     */
    public void use(Closure closure){
        registry.setMetaClass(theClass, this);
        
        try {
            closure.call();
        } finally {
            registry.setMetaClass(theClass, adaptee);
        }
    }

     /**
     * Use the ProxyMetaClass for the given Closure.
     * Cares for balanced setting/unsetting ProxyMetaClass.
     * @param closure piece of code to be executed with ProxyMetaClass
     */
    public void use(GroovyObject object, Closure closure){
        object.setMetaClass(this);
        
        try {
            closure.call();
        } finally {
            object.setMetaClass(adaptee);
        }
    }

    /**
     * @return the interceptor in use or null if no interceptor is used
     */
    public Interceptor getInterceptor() {
        return interceptor;
    }

    /**
     * @param interceptor may be null to reset any interception
     */
    public void setInterceptor(Interceptor interceptor) {
        this.interceptor = interceptor;
    }

    /**
     * Call invokeMethod on adaptee with logic like in MetaClass unless we have an Interceptor.
     * With Interceptor the call is nested in its beforeInvoke and afterInvoke methods.
{'fraction_non_alphanumeric': 0.07078853046594982, 'fraction_numerical': 0.00017921146953405018, 'mean_word_length': 2.9609652235628103, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6633654', 'n_tokens_mistral': 1500, 'n_tokens_neox': 1435, 'n_words': 507}