Clover coverage report - Ledge Components - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:13:20 CET
file stats: LOC: 177   Methods: 4
NCLOC: 105   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Daemon.java 75% 86.7% 75% 83.3%
coverage coverage
 1    //
 2    // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    // All rights reserved.
 4    //
 5    // Redistribution and use in source and binary forms, with or without modification,
 6    // are permitted provided that the following conditions are met:
 7    //
 8    // * Redistributions of source code must retain the above copyright notice,
 9    // this list of conditions and the following disclaimer.
 10    // * Redistributions in binary form must reproduce the above copyright notice,
 11    // this list of conditions and the following disclaimer in the documentation
 12    // and/or other materials provided with the distribution.
 13    // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    // nor the names of its contributors may be used to endorse or promote products
 15    // derived from this software without specific prior written permission.
 16    //
 17    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    // POSSIBILITY OF SUCH DAMAGE.
 27    //
 28    package org.objectledge.threads.impl;
 29   
 30    import org.jcontainer.dna.Logger;
 31    import org.objectledge.context.Context;
 32    import org.objectledge.pipeline.Valve;
 33    import org.objectledge.threads.Task;
 34    import org.picocontainer.Startable;
 35   
 36    /**
 37    * A daemon thread helper object.
 38    *
 39    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
 40    * @version $Id: Daemon.java,v 1.4 2005/02/10 17:46:53 rafal Exp $
 41    */
 42    public class Daemon
 43    implements Runnable, Startable
 44    {
 45    private Thread thread;
 46   
 47    private Logger log;
 48   
 49    private Task task;
 50   
 51    private Context context;
 52   
 53    private Valve cleanup;
 54   
 55    private boolean shutdown = false;
 56   
 57    private boolean running = false;
 58   
 59    /**
 60    * Creates a daemon thread.
 61    *
 62    * @param task the task to run.
 63    * @param priority the task's priority (see {@link java.lang.Thread} description)
 64    * @param threadGroup the thread group where the thread should belong.
 65    * @param log the logger to use.
 66    * @param context thread's processing context.
 67    * @param cleanup cleanup valve to invoke, should the task terminate.
 68    */
 69  5060 public Daemon(Task task, int priority,
 70    ThreadGroup threadGroup, Logger log, Context context, Valve cleanup)
 71    {
 72  5060 this.log = log;
 73  5060 this.context = context;
 74  5060 this.task = task;
 75  5060 this.cleanup = cleanup;
 76  5060 thread = new Thread(threadGroup, this, task.getName());
 77  5060 thread.setPriority(priority);
 78  5060 thread.setDaemon(true);
 79  5060 thread.start();
 80    }
 81   
 82    /**
 83    * {@inheritDoc}
 84    */
 85  5056 public void run()
 86    {
 87  5056 log.info("starting "+task.getName());
 88  5054 try
 89    {
 90  5054 running = true;
 91  5054 task.process(context);
 92    }
 93    ///CLOVER:OFF
 94    catch(VirtualMachineError e)
 95    {
 96    throw e;
 97    }
 98    ///CLOVER:ON
 99    catch(ThreadDeath e)
 100    {
 101  0 if(!shutdown)
 102    {
 103  0 log.warn(task.getName()+" was forcibly stopped", e);
 104    }
 105    else
 106    {
 107  0 log.info("finished "+task.getName());
 108    }
 109  0 throw e;
 110    }
 111    catch(Throwable e)
 112    {
 113  46 log.error("unhandled exception in "+task.getName(), e);
 114    }
 115    finally
 116    {
 117  323 running = false;
 118    }
 119   
 120  323 if(shutdown)
 121    {
 122  231 log.info("finished "+task.getName());
 123    }
 124    else
 125    {
 126  92 log.error(task.getName()+" has quit");
 127    }
 128   
 129    // cleanup
 130  323 if(cleanup != null)
 131    {
 132  230 try
 133    {
 134  230 cleanup.process(context);
 135    }
 136    ///CLOVER:OFF
 137    catch(VirtualMachineError e)
 138    {
 139    throw e;
 140    }
 141    catch(ThreadDeath e)
 142    {
 143    throw e;
 144    }
 145    ///CLOVER:ON
 146    catch(Throwable e)
 147    {
 148  46 log.error("error in cleanup after "+task.getName(), e);
 149    }
 150    }
 151    }
 152   
 153    /**
 154    * {@inheritDoc}
 155    */
 156  0 public void start()
 157    {
 158    // Startable interface should really be split
 159    }
 160   
 161    /**
 162    * {@inheritDoc}
 163    */
 164  552 public void stop()
 165    {
 166  552 shutdown = true;
 167  552 if(running)
 168    {
 169  414 log.info("asking "+task.getName()+" to terminate");
 170  414 task.terminate(thread);
 171    }
 172    else
 173    {
 174  138 log.warn(task.getName()+" is not running");
 175    }
 176    }
 177    }