<commit_before>
/*
 * Copyright (C) 2011 <NAME>. All rights reserved.
 *
 * $Id$
 */

package org.dellroad.stuff.vaadin;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.SmartApplicationListener;

/**
 * A Spring {@link org.springframework.context.ApplicationListener} support superclass customized for use by
 * listeners that are part of a Vaadin application when listening to non-Vaadin application event sources.
 *
 * <p>
 * Listeners that are part of a Vaadin application should use this superclass if they are going to be registered
 * with non-Vaadin event sources. This will ensure that events are delivered {@linkplain ContextApplication#invoke
 * in the proper Vaadin application context}.
 * </p>
 *
 * <p>
 * Note: to avoid memory leaks, listeners must be explicitly unregistered when the associated Vaadin application closes.
 * This can be done by invoking {@link #unregisterOnApplicationCloseFrom unregisterOnApplicationCloseFrom()} and providing
 * the object on which this listener is registered, or by explicitly unregistering the listener in the Spring
 * {@linkplain org.springframework.beans.factory.DisposableBean#destroy destroy-method} associated with a
 * bean that has {@link VaadinApplicationScope scope="vaadinApplication"} or lives in a {@link SpringContextApplication}
 * application context (so that the bean's destroy method will be invoked when the Vaadin application closes), etc.
 * However, Spring does not provide any {@code removeApplicationListener()} method in the
 * {@link org.springframework.context.ConfigurableApplicationContext} class itself, so an explicitly-defined
 * {@link ApplicationEventMulticaster} must be used for this to work.
 * </p>
 *
 * <p>
 * Note: when listening to event sources that are scoped to specific Vaadin application instances and originate events
 * within the proper Vaadin application context, then the use of this listener superclass is not necessary.
 * </p>
 *
 * @see ContextApplication#invoke
 * @see VaadinApplicationScope
 * @see SpringContextApplication
 */
public abstract class VaadinApplicationListener<E extends ApplicationEvent> implements SmartApplicationListener {

    private final Class<E> eventType;
    private final ContextApplication application;

    /**
     * Convenience constructor. Equivalent to:
     * <blockquote>
     *  {@link #VaadinApplicationListener(Class, ContextApplication) VaadinApplicationListener(eventType, ContextApplication.get())}
     * </blockquote>
     *
     * @throws IllegalArgumentException if {@code eventType} is null
     * @throws IllegalStateException if there is no {@link ContextApplication} associated with the current thread
     */
    public VaadinApplicationListener(Class<E> eventType) {
        this(eventType, ContextApplication.get());
    }

    /**
     * Primary constructor.
     *
     * @param eventType type of events this instance should receive (others will be ignored)
     * @param application the associated Vaadin application
     * @throws IllegalArgumentException if either parameter is null
     */
    public VaadinApplicationListener(Class<E> eventType, ContextApplication application) {
        if (eventType == null)
            throw new IllegalArgumentException("null eventType");
        if (application == null)
            throw new IllegalArgumentException("null application");
        this.eventType = eventType;
        this.application = application;
    }

    /**
     * Register a {@link ContextApplication.CloseListener} on the {@linkplain #getApplication configured Vaadin application}
     * so that upon close notification we can unregister this instance from the provided event multicaster.
     *
     * <p>
     * This method (or some other means) must be used to avoid a memory leak when the Vaadin application closes.
     *
     * @param eventMulticaster the context from which to unregister this instance when the Vaadin application closes
     */
    public void unregisterOnApplicationCloseFrom(final ApplicationEventMulticaster eventMulticaster) {
        this.getApplication().addListener(new ContextApplication.CloseListener() {
            @Override
            public void applicationClosed(ContextApplication.CloseEvent closeEvent) {
                eventMulticaster.removeApplicationListener(VaadinApplicationListener.this);
            }
        });
    }<commit_msg>Check for null argument in unregisterOnApplicationCloseFrom().<commit_after>
/*
 * Copyright (C) 2011 <NAME>. All rights reserved.
 *
 * $Id$
 */

package org.dellroad.stuff.vaadin;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.SmartApplicationListener;

/**
 * A Spring {@link org.springframework.context.ApplicationListener} support superclass customized for use by
 * listeners that are part of a Vaadin application when listening to non-Vaadin application event sources.
 *
 * <p>
 * Listeners that are part of a Vaadin application should use this superclass if they are going to be registered
 * with non-Vaadin event sources. This will ensure that events are delivered {@linkplain ContextApplication#invoke
 * in the proper Vaadin application context}.
 * </p>
 *
 * <p>
 * Note: to avoid memory leaks, listeners must be explicitly unregistered when the associated Vaadin application closes.
 * This can be done by invoking {@link #unregisterOnApplicationCloseFrom unregisterOnApplicationCloseFrom()} and providing
 * the object on which this listener is registered, or by explicitly unregistering the listener in the Spring
 * {@linkplain org.springframework.beans.factory.DisposableBean#destroy destroy-method} associated with a
 * bean that has {@link VaadinApplicationScope scope="vaadinApplication"} or lives in a {@link SpringContextApplication}
 * application context (so that the bean's destroy method will be invoked when the Vaadin application closes), etc.
 * However, Spring does not provide any {@code removeApplicationListener()} method in the
 * {@link org.springframework.context.ConfigurableApplicationContext} class itself, so an explicitly-defined
 * {@link ApplicationEventMulticaster} must be used for this to work.
 * </p>
 *
 * <p>
 * Note: when listening to event sources that are scoped to specific Vaadin application instances and originate events
 * within the proper Vaadin application context, then the use of this listener superclass is not necessary.
 * </p>
 *
 * @see ContextApplication#invoke
 * @see VaadinApplicationScope
 * @see SpringContextApplication
 */
public abstract class VaadinApplicationListener<E extends ApplicationEvent> implements SmartApplicationListener {

    private final Class<E> eventType;
    private final ContextApplication application;

    /**
     * Convenience constructor. Equivalent to:
     * <blockquote>
     *  {@link #VaadinApplicationListener(Class, ContextApplication) VaadinApplicationListener(eventType, ContextApplication.get())}
     * </blockquote>
     *
     * @throws IllegalArgumentException if {@code eventType} is null
     * @throws IllegalStateException if there is no {@link ContextApplication} associated with the current thread
     */
    public VaadinApplicationListener(Class<E> eventType) {
        this(eventType, ContextApplication.get());
    }

    /**
     * Primary constructor.
     *
     * @param eventType type of events this instance should receive (others will be ignored)
     * @param application the associated Vaadin application
     * @throws IllegalArgumentException if either parameter is null
     */
    public VaadinApplicationListener(Class<E> eventType, ContextApplication application) {
        if (eventType == null)
            throw new IllegalArgumentException("null eventType");
        if (application == null)
            throw new IllegalArgumentException("null application");
        this.eventType = eventType;
        this.application = application;
    }

    /**
     * Register a {@link ContextApplication.CloseListener} on the {@linkplain #getApplication configured Vaadin application}
     * so that upon close notification we can unregister this instance from the provided event multicaster.
     *
     * <p>
     * This method (or some other means) must be used to avoid a memory leak when the Vaadin application closes.
     *
     * @param eventMulticaster the context from which to unregister this instance when the Vaadin application closes
     * @throws IllegalArgumentException if {@code eventMulticaster} is null
     */
    public void unregisterOnApplicationCloseFrom(final ApplicationEventMulticaster eventMulticaster) {
        if (eventMulticaster == null)
            throw new IllegalArgumentException("null eventMulticaster");
        this.getApplication().addListener(new ContextApplication.CloseListener() {
            @Override
            public void applicationClosed(ContextApplication.CloseEvent closeEvent) {
                eventMulticaster.removeApplicationListener(VaadinApplicationListener.this);
            }
        });
    }
{'fraction_non_alphanumeric': 0.07116471099521947, 'fraction_numerical': 0.000869187309865276, 'mean_word_length': 4.108213096559378, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, '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': '3019895', 'n_tokens_mistral': 2191, 'n_tokens_neox': 2095, 'n_words': 835}