001    package 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    
022    import java.util.Collections;
023    import java.util.Comparator;
024    import java.util.List;
025    import java.util.Vector;
026    
027    import 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     */
036    public class JobQueue
037    {
038        /**
039         * The queue of <code>JobEntry</code> objects.
040         */
041        private Vector<JobEntry> queue = null;
042    
043        /**
044         * Creates a new instance.
045         */
046        public JobQueue()
047        {
048            queue = new Vector<JobEntry>(10);
049        }
050    
051        /**
052         * Return the next job off the top of the queue, or <code>null</code> if
053         * there are no jobs in the queue.
054         *
055         * @return The next job in the queue.
056         */
057        public JobEntry getNext()
058        {
059            if (queue.size() > 0)
060            {
061                return queue.elementAt(0);
062            }
063            else
064            {
065                return null;
066            }
067        }
068    
069        /**
070         * Return a specific job.
071         *
072         * @param je The JobEntry we are looking for.
073         * @return A JobEntry.
074         */
075        public JobEntry getJob(JobEntry je)
076        {
077            int index = -1;
078    
079            if (je != null)
080            {
081                index = queue.indexOf(je);
082            }
083    
084            if (index < 0)
085            {
086                return null;
087            }
088            else
089            {
090                return queue.elementAt(index);
091            }
092        }
093    
094        /**
095         * List jobs in the queue.  This is used by the scheduler UI.
096         *
097         * @return A Vector of <code>JobEntry</code> objects.
098         */
099        @SuppressWarnings("unchecked")
100        public Vector<JobEntry> list()
101        {
102            if (queue != null && queue.size() > 0)
103            {
104                return (Vector<JobEntry>) queue.clone();
105            }
106            else
107            {
108                return null;
109            }
110        }
111    
112        /**
113         * Add a job to the queue.
114         *
115         * @param je A JobEntry job.
116         */
117        public synchronized void add(JobEntry je)
118        {
119            queue.addElement(je);
120            sortQueue();
121        }
122    
123        /**
124         * Batch load jobs.  Retains any already enqueued jobs.  Called on
125         * <code>SchedulerService</code> start-up.
126         *
127         * @param jobEntries A list of the <code>JobEntry</code> objects to load.
128         */
129        public synchronized void batchLoad(List<JobEntry> jobEntries)
130        {
131            if (jobEntries != null)
132            {
133                queue.addAll(jobEntries);
134                sortQueue();
135            }
136    
137        }
138    
139        /**
140         * Remove a job from the queue.
141         *
142         * @param je A JobEntry with the job to remove.
143         */
144        public synchronized void remove(JobEntry je)
145        {
146            queue.removeElement(je);
147            sortQueue();
148        }
149    
150        /**
151         * Modify a job on the queue.
152         *
153         * @param je A JobEntry with the job to modify
154         */
155        public synchronized void modify(JobEntry je)
156                throws TurbineException
157        {
158            remove(je);
159            je.calcRunTime();
160            this.add(je);
161            sortQueue();
162        }
163    
164        /**
165         * Update the job for its next run time.
166         *
167         * @param je A JobEntry to be updated.
168         * @exception TurbineException a generic exception.
169         */
170        public synchronized void updateQueue(JobEntry je)
171                throws TurbineException
172        {
173            je.calcRunTime();
174            sortQueue();
175        }
176    
177        /**
178         * Re-sort the existing queue.  Consumers of this method should be
179         * <code>synchronized</code>.
180         */
181        private void sortQueue()
182        {
183            Comparator<JobEntry> aComparator = new Comparator<JobEntry>()
184            {
185                public int compare(JobEntry o1, JobEntry o2)
186                {
187                    Long time1 = new Long(o1.getNextRuntime());
188                    Long time2 = new Long(o2.getNextRuntime());
189                    return (time1.compareTo(time2));
190                }
191            };
192    
193            Collections.sort(queue, aComparator);
194        }
195    }