001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.examples.panorama.startup.impl;
016    
017    import java.util.Iterator;
018    import java.util.List;
019    
020    import org.apache.commons.logging.Log;
021    import org.apache.hivemind.ErrorLog;
022    import org.apache.hivemind.Messages;
023    import org.apache.hivemind.order.Orderer;
024    
025    /**
026     * A service that executes a series of {@link org.apache.examples.panorama.startup.impl.Task}s. Tasks have an
027     * ordering based on pre- and post-requisites.
028     * 
029     * @author Howard Lewis Ship
030     */
031    public class TaskExecutor implements Runnable
032    {
033        private Log _log;
034    
035        private ErrorLog _errorLog;
036    
037        private List _tasks;
038    
039        private Messages _messages;
040    
041        /**
042         * Orders the {@link #setTasks(List) tasks} into an execution order, and executes each in turn.
043         * Logs the elapsed time, number of tasks, and the number of failures (if any).
044         */
045        public void run()
046        {
047            long startTime = System.currentTimeMillis();
048    
049            Orderer orderer = new Orderer(_errorLog, task());
050    
051            Iterator i = _tasks.iterator();
052            while (i.hasNext())
053            {
054                Task t = (Task) i.next();
055    
056                orderer.add(t, t.getId(), t.getAfter(), t.getBefore());
057            }
058    
059            List orderedTasks = orderer.getOrderedObjects();
060    
061            int failures = 0;
062    
063            i = orderedTasks.iterator();
064            while (i.hasNext())
065            {
066                Task t = (Task) i.next();
067    
068                if (!execute(t))
069                    failures++;
070            }
071    
072            long elapsedTime = System.currentTimeMillis() - startTime;
073    
074            if (failures == 0)
075                _log.info(success(orderedTasks.size(), elapsedTime));
076            else
077                _log.info(failure(failures, orderedTasks.size(), elapsedTime));
078        }
079    
080        /**
081         * Execute a single task.
082         * 
083         * @return true on success, false on failure
084         */
085        private boolean execute(Task t)
086        {
087            _log.info(executingTask(t));
088    
089            try
090            {
091                t.execute();
092    
093                return true;
094            }
095            catch (Exception ex)
096            {
097                _errorLog.error(exceptionInTask(t, ex), t.getLocation(), ex);
098    
099                return false;
100            }
101        }
102    
103        private String task()
104        {
105            return _messages.getMessage("task");
106        }
107    
108        private String executingTask(Task t)
109        {
110            return _messages.format("executing-task", t.getTitle());
111        }
112    
113        private String exceptionInTask(Task t, Throwable cause)
114        {
115            return _messages.format("exception-in-task", t.getTitle(), cause);
116        }
117    
118        private String success(int count, long elapsedTimeMillis)
119        {
120            return _messages.format("success", new Integer(count), new Long(elapsedTimeMillis));
121        }
122    
123        private String failure(int failureCount, int totalCount, long elapsedTimeMillis)
124        {
125            return _messages.format(
126                    "failure",
127                    new Integer(failureCount),
128                    new Integer(totalCount),
129                    new Long(elapsedTimeMillis));
130        }
131    
132        public void setLog(Log log)
133        {
134            _log = log;
135        }
136    
137        public void setErrorLog(ErrorLog errorLog)
138        {
139            _errorLog = errorLog;
140        }
141    
142        public void setMessages(Messages messages)
143        {
144            _messages = messages;
145        }
146    
147        public void setTasks(List list)
148        {
149            _tasks = list;
150        }
151    
152    }