<commit_before>/**
 * Copyright 1998-2003 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL 
 * WARRANTIES.
 */
package com.sun.speech.engine;

import javax.speech.SpeechEvent;
import java.awt.*;
import java.security.AccessControlException;

/**
 * Utilities to help with dispatch JSAPI 1.0 events on the event dispatching thread of AWT/Swing.  This is needed to
 * help applications conform with the Swing Event Thread model.  If these utilities were not used, then a GUI
 * application would have to implement Runnables to handle JSAPI events that result in updates to the GUI.
 */
public class SpeechEventUtilities {

    /**
     * If true, the AWT EventQueue has been set up in the VM.  This flag is used to determine whether we should use the
     * AWT EventQueue for synchronizing SpeechEvents with the AWT EventQueue or not.
     */
    protected static boolean awtRunning;

    /**
     * The AWT EventQueue.  This is lazily created in postSpeechEvent to delay the need to initialize the Toolkit until
     * it is necessary.
     *
     * @see #postSpeechEvent
     */
    protected static EventQueue systemEventQueue;

    /**
     * A target used to process speechAWTEvent objects.  This target is a component that expresses interest in
     * SpeechAWTEvents.  It is lazily created along with systemEventQueue in postSpeechEvent.
     *
     * @see #postSpeechEvent
     */
    protected static SpeechAWTEventTarget speechAWTEventTarget;

    /**
     * If true, wait until an event has been dispatched before returning from the post method.  This is meant to be a
     * global debugging flag. If a class calling postSpeechEvent wants to wait until the SpeechEvent has been
     * dispatched, it should call the postSpeechEvent method that has the waitUntilDispatched parameter.
     *
     * @see #postSpeechEvent
     */
    public static boolean waitUntilDispatched;


    /**
     * Determine if the AWT event queue is running.  This method is one big hack, and we will be entering a bug against
     * AWT to provide us with a real method for determining if AWT is active or not.  The problem with asking AWT if it
     * is active right now is that it will activate it if it isn't already active.
     */
    static protected boolean isAWTRunning() {

        if (awtRunning) {
            return true;
        }

        try {
            ThreadGroup rootGroup;
            ThreadGroup parent;
            ThreadGroup g = Thread.currentThread().getThreadGroup();
            rootGroup = g;
            parent = rootGroup.getParent();
            while (parent != null) {
                rootGroup = parent;
                parent = parent.getParent();
            }

            int activeCount = rootGroup.activeCount();
            Thread[] threads = new Thread[activeCount];
            rootGroup.enumerate(threads, true);
            for (Thread thread : threads) {
                if (thread != null) {
                    String name = thread.getName();
                    if (name.startsWith("AWT-EventQueue")) {
                        awtRunning = true;
                        return true;
                    }
                }
            }
        } catch (AccessControlException ace) {
            // if we receive an access control exception then
            // it is likely that we are running in an applet
            // in which case AWT is running.
            // I'm not sure if this is always true, perhaps
            // there is another way to tell if we are running in an
            // applet.

            return true;
        }

        return false;
    }


    /**
     * Post a JSAPI SpeechEvent.  This is to be used by multiple processes to synchronize SpeechEvents.  It currently
     * uses the AWT EventQueue as a means for doing this, which has the added benefit of causing all SpeechEvent
     * notification to be done from the event dispatch thread.  This is important because the Swing Thread Model
     * requires all interaction with Swing components to be done from the event dispatch thread.
     * <p/>
     * This method will immediately return once the event has been posted if the global waitUntilDispatched flag is set
     * to false. Otherwise, it will wait until the event has been dispatched before returning.
     *
     * @param dispatcher the dispatcher that will dispatch the event
     * @param event      the SpeechEvent to post
     */
    static public void postSpeechEvent(SpeechEventDispatcher dispatcher,
                                       SpeechEvent event) {
        postSpeechEvent(dispatcher, event, waitUntilDispatched);
    }


    /**
     * Post a JSAPI SpeechEvent.  This is to be used by multiple processes to synchronize SpeechEvents.  It currently
     * uses the AWT EventQueue as a means for doing this, which has the added benefit of causing all SpeechEvent
     * notification to be done from the event dispatch thread.  This is important because the Swing Thread Model
     * requires all interaction with Swing components to be done from the event dispatch thread.
     * <p/>
     * This method will immediately return once the event has been posted if the waitUntilDispatched parameter is set to
     * false. Otherwise, it will wait until the event has been dispatched before returning.
     *
     * @param dispatcher          the dispatcher that will dispatch the event
     * @param event               the SpeechEvent to post
     * @param waitUntilDispatched if true, do not return until the event have been dispatched
     */
    static public void postSpeechEvent(
            SpeechEventDispatcher dispatcher,
            SpeechEvent event,
            boolean waitUntilDispatched) {

        /* Only use the AWT EventQueue if AWT is running.  If it isn't
         * running, then just call the dispatcher directly.  A more formal
         * event queue mechanism probably should be added at some point
         * so listeners cannot cause a hang in the engine.
         */
        if (isAWTRunning()) {
            /* Create the event target and event queue references if they
             * haven't been created yet.  This is done here to delay the
             * initialization of the AWT Toolkit until it is absolutely
             * necessary.  Creating it earlier may cause conflicts with
             * applets.
             */
            if (speechAWTEventTarget == null) {
                speechAWTEventTarget = new SpeechAWTEventTarget();
                systemEventQueue =
                        Toolkit.getDefaultToolkit().getSystemEventQueue();
            }

            /* Post the event to the AWT EventQueue.  When AWT dispatches
             * the events on its EventQueue, this event will be sent to
             * the speechAWTEventTarget for processing.
             */
            if (waitUntilDispatched) {
                Object lock = new Object();
                synchronized (lock) {
                    systemEventQueue.postEvent(
                            new SpeechAWTEvent(speechAWTEventTarget,
                                    dispatcher,
                                    event,
                                    lock));
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                    }
                }
            } else {
                systemEventQueue.postEvent(
                        new SpeechAWTEvent(speechAWTEventTarget,
                                dispatcher,
                                event));
            }
        } else {
            dispatcher.dispatchSpeechEvent(event);
        }
    }


    /**
     * Inner class used to handle events as they are dispatched from the AWT event queue.
     *
     * @see #postSpeechEvent
     */
    @SuppressWarnings("serial")
	protected static class SpeechAWTEventTarget extends Component {

        SpeechAWTEventTarget() {
            super();
            enableEvents(SpeechAWTEvent.EVENT_ID);
        }
<commit_msg>Running the event dispatcher asynchronously.<commit_after>/**
 * Copyright 1998-2003 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL 
 * WARRANTIES.
 */
package com.sun.speech.engine;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.security.AccessControlException;

import javax.speech.SpeechEvent;

/**
 * Utilities to help with dispatch JSAPI 1.0 events on the event dispatching thread of AWT/Swing.  This is needed to
 * help applications conform with the Swing Event Thread model.  If these utilities were not used, then a GUI
 * application would have to implement Runnables to handle JSAPI events that result in updates to the GUI.
 */
public class SpeechEventUtilities {

    /**
     * If true, the AWT EventQueue has been set up in the VM.  This flag is used to determine whether we should use the
     * AWT EventQueue for synchronizing SpeechEvents with the AWT EventQueue or not.
     */
    protected static boolean awtRunning;

    /**
     * The AWT EventQueue.  This is lazily created in postSpeechEvent to delay the need to initialize the Toolkit until
     * it is necessary.
     *
     * @see #postSpeechEvent
     */
    protected static EventQueue systemEventQueue;

    /**
     * A target used to process speechAWTEvent objects.  This target is a component that expresses interest in
     * SpeechAWTEvents.  It is lazily created along with systemEventQueue in postSpeechEvent.
     *
     * @see #postSpeechEvent
     */
    protected static SpeechAWTEventTarget speechAWTEventTarget;

    /**
     * If true, wait until an event has been dispatched before returning from the post method.  This is meant to be a
     * global debugging flag. If a class calling postSpeechEvent wants to wait until the SpeechEvent has been
     * dispatched, it should call the postSpeechEvent method that has the waitUntilDispatched parameter.
     *
     * @see #postSpeechEvent
     */
    public static boolean waitUntilDispatched;


    /**
     * Determine if the AWT event queue is running.  This method is one big hack, and we will be entering a bug against
     * AWT to provide us with a real method for determining if AWT is active or not.  The problem with asking AWT if it
     * is active right now is that it will activate it if it isn't already active.
     */
    static protected boolean isAWTRunning() {

        if (awtRunning) {
            return true;
        }

        try {
            ThreadGroup rootGroup;
            ThreadGroup parent;
            ThreadGroup g = Thread.currentThread().getThreadGroup();
            rootGroup = g;
            parent = rootGroup.getParent();
            while (parent != null) {
                rootGroup = parent;
                parent = parent.getParent();
            }

            int activeCount = rootGroup.activeCount();
            Thread[] threads = new Thread[activeCount];
            rootGroup.enumerate(threads, true);
            for (Thread thread : threads) {
                if (thread != null) {
                    String name = thread.getName();
                    if (name.startsWith("AWT-EventQueue")) {
                        awtRunning = true;
                        return true;
                    }
                }
            }
        } catch (AccessControlException ace) {
            // if we receive an access control exception then
            // it is likely that we are running in an applet
            // in which case AWT is running.
            // I'm not sure if this is always true, perhaps
            // there is another way to tell if we are running in an
            // applet.

            return true;
        }

        return false;
    }


    /**
     * Post a JSAPI SpeechEvent.  This is to be used by multiple processes to synchronize SpeechEvents.  It currently
     * uses the AWT EventQueue as a means for doing this, which has the added benefit of causing all SpeechEvent
     * notification to be done from the event dispatch thread.  This is important because the Swing Thread Model
     * requires all interaction with Swing components to be done from the event dispatch thread.
     * <p/>
     * This method will immediately return once the event has been posted if the global waitUntilDispatched flag is set
     * to false. Otherwise, it will wait until the event has been dispatched before returning.
     *
     * @param dispatcher the dispatcher that will dispatch the event
     * @param event      the SpeechEvent to post
     */
    public static void postSpeechEvent(SpeechEventDispatcher dispatcher,
                                       SpeechEvent event) {
        postSpeechEvent(dispatcher, event, waitUntilDispatched);
    }


    /**
     * Post a JSAPI SpeechEvent.  This is to be used by multiple processes to synchronize SpeechEvents.  It currently
     * uses the AWT EventQueue as a means for doing this, which has the added benefit of causing all SpeechEvent
     * notification to be done from the event dispatch thread.  This is important because the Swing Thread Model
     * requires all interaction with Swing components to be done from the event dispatch thread.
     * <p/>
     * This method will immediately return once the event has been posted if the waitUntilDispatched parameter is set to
     * false. Otherwise, it will wait until the event has been dispatched before returning.
     *
     * @param dispatcher          the dispatcher that will dispatch the event
     * @param event               the SpeechEvent to post
     * @param waitUntilDispatched if true, do not return until the event have been dispatched
     */
    static public void postSpeechEvent(
            final SpeechEventDispatcher dispatcher,
            final SpeechEvent event,
            boolean waitUntilDispatched) {

        /* Only use the AWT EventQueue if AWT is running.  If it isn't
         * running, then just call the dispatcher directly.  A more formal
         * event queue mechanism probably should be added at some point
         * so listeners cannot cause a hang in the engine.
         */
        if (isAWTRunning()) {
            /* Create the event target and event queue references if they
             * haven't been created yet.  This is done here to delay the
             * initialization of the AWT Toolkit until it is absolutely
             * necessary.  Creating it earlier may cause conflicts with
             * applets.
             */
            if (speechAWTEventTarget == null) {
                speechAWTEventTarget = new SpeechAWTEventTarget();
                systemEventQueue =
                        Toolkit.getDefaultToolkit().getSystemEventQueue();
            }

            /* Post the event to the AWT EventQueue.  When AWT dispatches
             * the events on its EventQueue, this event will be sent to
             * the speechAWTEventTarget for processing.
             */
            if (waitUntilDispatched) {
                Object lock = new Object();
                synchronized (lock) {
                    systemEventQueue.postEvent(
                            new SpeechAWTEvent(speechAWTEventTarget,
                                    dispatcher,
                                    event,
                                    lock));
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                    }
                }
            } else {
                systemEventQueue.postEvent(
                        new SpeechAWTEvent(speechAWTEventTarget,
                                dispatcher,
                                event));
            }
        } else {
            final Thread thread = new Thread() {
                public void run() {
                    dispatcher.dispatchSpeechEvent(event);
                }
            };
            thread.start();
        }
    }


    /**
     * Inner class used to handle events as they are dispatched from the AWT event queue.
     *
     * @see #postSpeechEvent
     */
    @SuppressWarnings("serial")
	protected static class SpeechAWTEventTarget extends Component {

        SpeechAWTEventTarget() {
            super();
            enableEvents(SpeechAWTEvent.EVENT_ID);
        }

{'fraction_non_alphanumeric': 0.05414070534147965, 'fraction_numerical': 0.001209848164055411, 'mean_word_length': 1.8922323303009096, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2765831', 'n_tokens_mistral': 4029, 'n_tokens_neox': 3810, 'n_words': 1701}