    001package org.apache.turbine.services.schedule;
    002
    003/*
    004 * Licensed to the Apache Software Foundation (ASF) under one
    005 * or more contributor license agreements.  See the NOTICE file
    006 * distributed with this work for additional information
    007 * regarding copyright ownership.  The ASF licenses this file
    008 * to you under the Apache License, Version 2.0 (the
    009 * "License"); you may not use this file except in compliance
    010 * with the License.  You may obtain a copy of the License at
    011 *
    012 *   http://www.apache.org/licenses/LICENSE-2.0
    013 *
    014 * Unless required by applicable law or agreed to in writing,
    015 * software distributed under the License is distributed on an
    016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    017 * KIND, either express or implied.  See the License for the
    018 * specific language governing permissions and limitations
    019 * under the License.
    020 */
    021
    022import java.util.Collections;
    023import java.util.Comparator;
    024import java.util.List;
    025import java.util.Vector;
    026
    027import org.apache.turbine.util.TurbineException;
    028
    029/**
    030 * Queue for the scheduler.
    031 *
    032 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
    033 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
    034 * @version $Id: JobQueue.java 615328 2008-01-25 20:25:05Z tv $
    035 * @param <J> a specialized job entry type
    036 */
    037public class JobQueue<J extends JobEntry>
    038{
    039    /**
    040     * The queue of <code>JobEntry</code> objects.
    041     */
    042    private Vector<J> queue = null;
    043
    044    /**
    045     * Creates a new instance.
    046     */
    047    public JobQueue()
    048    {
    049        queue = new Vector<J>(10);
    050    }
    051
    052    /**
    053     * Return the next job off the top of the queue, or <code>null</code> if
    054     * there are no jobs in the queue.
    055     *
    056     * @return The next job in the queue.
    057     */
    058    public J getNext()
    059    {
    060        if (queue.size() > 0)
    061        {
    062            return queue.elementAt(0);
    063        }
    064        else
    065        {
    066            return null;
    067        }
    068    }
    069
    070    /**
    071     * Return a specific job.
    072     *
    073     * @param je The JobEntry we are looking for.
    074     * @return A JobEntry.
    075     */
    076    public J getJob(J je)
    077    {
    078        int index = -1;
    079
    080        if (je != null)
    081        {
    082            index = queue.indexOf(je);
    083        }
    084
    085        if (index < 0)
    086        {
    087            return null;
    088        }
    089        else
    090        {
    091            return queue.elementAt(index);
    092        }
    093    }
    094
    095    /**
    096     * List jobs in the queue.  This is used by the scheduler UI.
    097     *
    098     * @return A Vector of <code>JobEntry</code> objects.
    099     */
    100    @SuppressWarnings("unchecked")
    101    public Vector<J> list()
    102    {
    103        if (queue != null && queue.size() > 0)
    104        {
    105            return (Vector<J>) queue.clone();
    106        }
    107        else
    108        {
    109            return null;
    110        }
    111    }
    112
    113    /**
    114     * Add a job to the queue.
    115     *
    116     * @param je A JobEntry job.
    117     */
    118    public synchronized void add(J je)
    119    {
    120        queue.addElement(je);
    121        sortQueue();
    122    }
    123
    124    /**
    125     * Batch load jobs.  Retains any already enqueued jobs.  Called on
    126     * <code>SchedulerService</code> start-up.
    127     *
    128     * @param jobEntries A list of the <code>JobEntry</code> objects to load.
    129     */
    130    public synchronized void batchLoad(List<J> jobEntries)
    131    {
    132        if (jobEntries != null)
    133        {
    134            queue.addAll(jobEntries);
    135            sortQueue();
    136        }
    137
    138    }
    139
    140    /**
    141     * Remove a job from the queue.
    142     *
    143     * @param je A JobEntry with the job to remove.
    144     */
    145    public synchronized void remove(J je)
    146    {
    147        queue.removeElement(je);
    148        sortQueue();
    149    }
    150
    151    /**
    152     * Modify a job on the queue.
    153     *
    154     * @param je A JobEntry with the job to modify
    155     * @throws TurbineException if the runtime calculation fails
    156     */
    157    public synchronized void modify(J je) throws TurbineException
    158    {
    159        remove(je);
    160        je.calcRunTime();
    161        this.add(je);
    162        sortQueue();
    163    }
    164
    165    /**
    166     * Update the job for its next run time.
    167     *
    168     * @param je A JobEntry to be updated.
    169     * @throws TurbineException a generic exception.
    170     */
    171    public synchronized void updateQueue(J je)
    172            throws TurbineException
    173    {
    174        je.calcRunTime();
    175        sortQueue();
    176    }
    177
    178    /**
    179     * Re-sort the existing queue.  Consumers of this method should be
    180     * <code>synchronized</code>.
    181     */
    182    private void sortQueue()
    183    {
    184        Comparator<J> aComparator = new Comparator<J>()
    185        {
    186            @Override
    187            public int compare(J o1, J o2)
    188            {
    189                Long time1 = Long.valueOf(o1.getNextRuntime());
    190                Long time2 = Long.valueOf(o2.getNextRuntime());
    191                return (time1.compareTo(time2));
    192            }
    193        };
    194
    195        Collections.sort(queue, aComparator);
    196    }
    197}