/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *     "Apache Jetspeed" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache" or
 *    "Apache Jetspeed", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.jetspeed.daemon.impl.util;

import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;

/**
Util class for joining a ThreadGroup and joining all of its Threads and waiting
for completion.

@author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
@version $Id: ThreadGroupJoin.java,v 1.9 2003/08/13 04:18:17 taylor Exp $
*/
public class ThreadGroupJoin 
{    
    /**
     * Static initialization of the logger for this class
     */
    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(ThreadGroupJoin.class.getName());
    
    /**
    Join a ThreadGroup and wait until it finishes
    */
    public static void join( ThreadGroup tg ) 
    {
        //join the threadgroup but don't have a source.
        join( tg, null, 0 );
    }

    /**
    Join a ThreadGroup bug specify a source and use a default interval.
    */
    public static void join( ThreadGroup tg,
                             String source ) 
    {
        join( tg, source, 100 );
    }
    
    /**
    Join a ThreadGroup except also log when interval number of Threads have 
    finished.
    */
    public static void join( ThreadGroup tg, 
                             String source, 
                             int interval ) 
    {

        Thread[] threads = new Thread[ tg.activeCount() ];
        
        tg.enumerate( threads );

        //keep waiting until all the DownloadThreads have stopped.

        long begin = System.currentTimeMillis();        
        
        for ( int i = 0; i < threads.length; ++i ) {

            if ( !threads[i].interrupted() ) 
            {
                try 
                {
                    if ( threads[i] != null ) 
                    {
                        threads[i].join();
                        
                        //if this is an even MOD of this interval and a source
                        //is defined then log it
                        if ( i != 0 && 
                            i % interval == 0 && 
                            source != null ) 
                        {
                            long seconds = ( System.currentTimeMillis() - begin ) / 1000;
                            begin = System.currentTimeMillis();
                            
                            if ( logger.isInfoEnabled() )
                            {
                                logger.info( source + ": has completed " + i + " threads in " + seconds + " second(s)" );
                            }
                            
                        }
                        
                    }

                } 
                catch (InterruptedException e) 
                {
                    logger.info( "Thread: " + threads[i].getName() + " -> DONE");
                    //noop.  this is standard.
                }
           }

        }
        
        
    }
    
}
    
  
