001 /**
002 * Copyright 2007 Mike Kroutikov.
003 *
004 * This program is free software; you can redistribute it and/or modify
005 * it under the terms of the Lesser GNU General Public License as
006 * published by the Free Software Foundation; either version 3 of
007 * the License, or (at your option) any later version.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012 * Lesser GNU General Public License for more details.
013 *
014 * You should have received a copy of the Lesser GNU General Public License
015 * along with this program. If not, see <http://www.gnu.org/licenses/>.
016 */
017
018 package org.otfeed.support;
019
020 import java.util.LinkedList;
021 import java.util.List;
022
023 import org.otfeed.IConnection;
024 import org.otfeed.IConnectionFactory;
025 import org.otfeed.IRequest;
026 import org.otfeed.event.IConnectionStateListener;
027 import org.otfeed.protocol.ICommand;
028
029 /**
030 * Class that runs a list of commands, then waits
031 * for the completion. Sometimes useful in scripts.
032 */
033 public class CommandRunner {
034
035 /**
036 * Creates new CommandRunner.
037 */
038 public CommandRunner() { }
039
040 /**
041 * Creates new CommandRunner from a given connection
042 * factory, with the given list of commands.
043 *
044 * @param cf connection factory.
045 * @param commands list of commands.
046 */
047 public CommandRunner(IConnectionFactory cf, List<ICommand> commands) {
048 setConnectionFactory(cf);
049 setCommandList(commands);
050 }
051
052 private IConnectionFactory connectionFactory;
053
054 /**
055 * Connection factory to use.
056 *
057 * @return connection factory.
058 */
059 public IConnectionFactory getConnectionFactory() {
060 return connectionFactory;
061 }
062
063 /**
064 * Sets the connection factory.
065 *
066 * @param val connection factory.
067 */
068 public void setConnectionFactory(IConnectionFactory val) {
069 connectionFactory = val;
070 }
071
072 private List<ICommand> commandList = new LinkedList<ICommand>();
073
074 /**
075 * List of commands to execute.
076 * If empty, the runner will just do connect, login, and disconnect.
077 *
078 * @return lsit of commands.
079 */
080 public List<ICommand> getCommandList() {
081 return commandList;
082 }
083
084 /**
085 * Sets list of commands.
086 *
087 * @param val list of commands.
088 */
089 public void setCommandList(List<ICommand> val) {
090 commandList = val;
091 }
092
093 private IConnectionStateListener connectionStateListener
094 = new SimpleConnectionStateListener();
095
096 /**
097 * Listener that watches connection-level events.
098 * Defaul is an instance of {@link SimpleConnectionStateListener},
099 * which will print the events to the System.err.
100 *
101 * @return connection state listener.
102 */
103 public IConnectionStateListener getConnectionStateListener() {
104 return connectionStateListener;
105 }
106
107 /**
108 * Sets connection state listener.
109 *
110 * @param val connection state listener.
111 */
112 public void setConnectionStateListener(IConnectionStateListener val) {
113 connectionStateListener = val;
114 }
115
116 /**
117 * Main method: connects to the server and executes all
118 * commands. Blocks untill the processing is finished.
119 *
120 * @throws Exception is something is not
121 * configured correctly, or something goes extremely
122 * wrong at the runtime.
123 */
124 public void runCommands() throws Exception {
125 runCommands(Integer.MAX_VALUE);
126 }
127
128 /**
129 * Main method: connects to the server and executes all
130 * commands. Blocks for the given timeout value
131 * waiting for the requests to complete. If timeout expires,
132 * the connection is shutdown, all pending requests are
133 * aborted with error.
134 *
135 * @param timeout how long to wait for the request to complete (in milliseconds).
136 * @throws Exception if something is not
137 * configured correctly, or something goes extremely
138 * wrong at the runtime.
139 */
140 public void runCommands(long timeout) throws Exception {
141 if(connectionFactory == null) {
142 throw new NullPointerException("connectionFactory property must be set");
143 }
144
145 if(commandList == null) {
146 throw new NullPointerException("commandList property must be set");
147 }
148
149 long target = System.currentTimeMillis() + timeout;
150
151 IConnection connection = connectionFactory.connect(null, connectionStateListener);
152
153 try {
154 List<IRequest> requestList = new LinkedList<IRequest>();
155 for(ICommand command : commandList) {
156 IRequest r = connection.prepareRequest(command);
157 r.submit();
158 requestList.add(r);
159 }
160
161 for(IRequest r : requestList) {
162 long delay = target - System.currentTimeMillis();
163 if(delay > 0) {
164 r.waitForCompletion(delay);
165 }
166 }
167 } finally {
168 connection.shutdown();
169 connection.waitForCompletion();
170 }
171 }
172 }