View Javadoc
1 /************************************************************ 2 * Copyright * 3 * Portions of this software are Copyright (c) 1993 - 2002, * 4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew * 5 * - http://www.nevrona.com/Indy/ * 6 ************************************************************/ 7 package org.indy; 8 9 import java.beans.Beans; 10 11 import java.io.IOException; 12 13 import java.net.InetAddress; 14 import java.net.ServerSocket; 15 16 import java.util.ArrayList; 17 import java.util.Collection; 18 import java.util.Collections; 19 import java.util.HashSet; 20 import java.util.List; 21 import java.util.Vector; 22 23 import org.indy.io.IndyIOException; 24 import org.indy.io.ServerIOHandler; 25 import org.indy.io.ServerIOHandlerSocket; 26 27 import org.indy.util.IndyUtilities; 28 29 30 /*** 31 * Description of the Class 32 * 33 *@author owen 34 *@created 26 September 2002 35 */ 36 public class TCPServer extends IndyComponent { 37 private final List bindings = new ArrayList(); 38 private final CommandHandlers commandHandlers = new CommandHandlers(this); 39 private final ServerListenerList listenerList = new ServerListenerList(); 40 private final List listenerThreadList = new ArrayList(); 41 private final List threadList = Collections.synchronizedList(new ArrayList()); 42 private volatile boolean commandHandlersEnabled; 43 private boolean commandHandlersInitialized; 44 private int defaultPort = 6666; 45 46 //Execution listener is unicast 47 private TCPServerExecuteListener executor; 48 private RFCReply greeting; 49 private boolean implicitIOHandler; 50 private boolean implicitThreadManager; 51 private ServerIOHandler ioHandler; 52 private boolean active = false; 53 private int listenQueue; 54 private ListenerThread listenThread; 55 private RFCReply maxConnectionReply; 56 private int maxConnections; 57 private RFCReplies relpyTexts = new RFCReplies(); 58 private RFCReply replyUnknownCommand; 59 private int terminateWaitTime; 60 private PeerThreadManager threadManager = new DefaultPeerThreadManager(); 61 transient private Vector TCPServerListeners; 62 63 /*** 64 * Constructor for the TCPServer object 65 */ 66 public TCPServer() { 67 } 68 69 /*** 70 * Description of the Method 71 * 72 *@param thread Description of the Parameter 73 */ 74 protected void doAfterCommandHandler(PeerThread thread) { 75 TCPServerListener[] l = listenerList.getArray(); 76 77 for (int i = 0; i < l.length; i++) { 78 l[i].onAfterCommandHandler(this, thread); 79 } 80 } 81 82 /*** 83 * Description of the Method 84 * 85 *@param thread Description of the Parameter 86 *@param line Description of the Parameter 87 */ 88 protected void doBeforeCommandHandler(PeerThread thread, String line) { 89 TCPServerListener[] l = listenerList.getArray(); 90 91 for (int i = 0; i < l.length; i++) { 92 l[i].onBeforeCommandHandler(this, thread, line); 93 } 94 } 95 96 /*** 97 * Description of the Method 98 * 99 *@param thread Description of the Parameter 100 */ 101 protected void doConnect(PeerThread thread) { 102 TCPServerListener[] listeners = listenerList.getArray(); 103 104 for (int i = 0; i < listeners.length; i++) { 105 listeners[i].onConnect(thread); 106 } 107 } 108 109 /*** 110 * Description of the Method 111 * 112 *@param thread Description of the Parameter 113 */ 114 protected void doDisconnect(PeerThread thread) { 115 TCPServerListener[] l = listenerList.getArray(); 116 117 for (int i = 0; i < l.length; i++) { 118 l[i].onDisconnect(thread); 119 } 120 } 121 122 /*** 123 * Description of the Method 124 * 125 *@param thread Description of the Parameter 126 *@param exception Description of the Parameter 127 */ 128 protected void doException(PeerThread thread, IndyException exception) { 129 if (listenerList.isEmpty()) { 130 System.err.println("No Server Listener Available:"); 131 exception.printStackTrace(); 132 133 return; 134 } 135 136 TCPServerListener[] listeners = listenerList.getArray(); 137 138 for (int i = 0; i < listeners.length; i++) { 139 listeners[i].onException(thread, exception); 140 } 141 } 142 143 /*** 144 * Description of the Method 145 * 146 *@param thread Description of the Parameter 147 *@return Description of the Return Value 148 *@throws IndyException Description of the Exception 149 */ 150 protected boolean doExecute(PeerThread thread) throws IndyException { 151 if (commandHandlersEnabled && (commandHandlers.size() > 0)) { 152 String line = thread.getConnection().readLine(); 153 154 if (line.length() > 0) { 155 doBeforeCommandHandler(thread, line); 156 157 try { 158 for (int i = 0, n = commandHandlers.size(); i < n; i++) { 159 CommandHandler ch = commandHandlers.getCommandHandler(i); 160 161 if (ch.isEnabled()) { 162 if (ch.check(line, thread)) { 163 break; 164 } 165 } 166 167 if (i == (n - 1)) { 168 doNoCommandHandler(thread, line); 169 } 170 } 171 } 172 finally { 173 doAfterCommandHandler(thread); 174 175 return true; 176 } 177 } 178 } 179 else { 180 if (executor != null) { 181 executor.onExecute(this, thread.getConnection()); 182 183 return true; 184 } 185 } 186 187 return false; 188 } 189 190 /*** 191 * Description of the Method 192 * 193 *@param thread Description of the Parameter 194 *@param exception Description of the Parameter 195 */ 196 protected void doListenException(ListenerThread thread, 197 IndyException exception) { 198 if (listenerList.isEmpty()) { 199 //just do a stack trace and bail 200 System.err.println("LISTEN EXCEPTION"); 201 exception.printStackTrace(); 202 203 return; 204 } 205 206 TCPServerListener[] listeners = listenerList.getArray(); 207 208 for (int i = 0; i < listeners.length; i++) { 209 listeners[i].onListenException(thread, exception); 210 } 211 } 212 213 /*** 214 * Description of the Method 215 * 216 *@param thread Description of the Parameter 217 *@param data Description of the Parameter 218 *@exception TCPServerException Description of the Exception 219 *@throws IdTCPServerError Description of the Exception 220 */ 221 protected void doNoCommandHandler(PeerThread thread, String data) 222 throws TCPServerException { 223 if (!commandHandlers.isEmpty()) { 224 TCPServerListener[] listeners = listenerList.getArray(); 225 226 for (int i = 0; i < listeners.length; i++) { 227 listeners[i].onNoCommandHandler(this, thread, data); 228 } 229 } 230 231 else if (replyUnknownCommand.replyExists()) { 232 try { 233 thread.getConnection().writeRFCReply(replyUnknownCommand); 234 } 235 catch (IndyException ide) { 236 throw new TCPServerException(ide.getMessage()); 237 } 238 } 239 240 else { 241 throw new TCPServerException(IndyUtilities.getResourceString( 242 "RSNoCommandHandlerFound")); 243 } 244 } 245 246 /*** 247 * DOCUMENT ME! 248 * 249 * @param b DOCUMENT ME! 250 */ 251 public void addBinding(TCPServerBinding b) { 252 bindings.add(b); 253 } 254 255 /*** 256 * Adds a feature to the CommandHandlerListener attribute of the IdTCPServer 257 * object 258 * 259 *@param l The feature to be added to the CommandHandlerListener attribute 260 */ 261 public void removeBinding(TCPServerBinding b) { 262 bindings.remove(b); 263 } 264 265 /*** 266 * Description of the Method 267 * 268 *@param l Description of the Parameter 269 */ 270 /*** 271 * Sets the active attribute of the IdTCPServer object 272 * 273 *@param active The new active value 274 *@exception IndyIOException Description of the Exception 275 */ 276 public void setActive(boolean makeActive) throws IndyIOException { 277 if (!Beans.isDesignTime() && makeActive && (makeActive != active)) { 278 try { 279 ioHandler = new ServerIOHandlerSocket(); 280 ioHandler.init(); 281 282 if (bindings.isEmpty()) { 283 bindings.add(new TCPServerBinding(null, defaultPort)); 284 } 285 286 for (int i = 0, n = bindings.size(); i < n; i++) { 287 TCPServerBinding binding = (TCPServerBinding) bindings.get(i); 288 ServerSocket ss = null; 289 290 int port = binding.getPort(); 291 292 if (binding.getHost() != null) { 293 InetAddress addr = InetAddress.getByName(binding.getHost()); 294 295 ss = new ServerSocket(port, listenQueue, addr); 296 } 297 else { 298 ss = new ServerSocket(port, listenQueue); 299 } 300 301 ListenerThread listener = new ListenerThread(this, ss); 302 303 listenerThreadList.add(listener); 304 listener.start(); 305 } 306 } 307 catch (IOException ioe) { 308 throw new IndyIOException(ioe); 309 } 310 } 311 else { 312 try { 313 System.err.println("Here"); 314 315 threadManager.terminateThreads(); 316 System.err.println("There"); 317 318 for (int i = 0, n = listenerThreadList.size(); i < n; i++) { 319 ListenerThread listener = (ListenerThread) listenerThreadList.get(i); 320 321 listener.terminateAndWait(); 322 } 323 324 listenerThreadList.clear(); 325 } 326 catch (InterruptedException ie) { 327 ie.printStackTrace(); 328 } 329 } 330 331 active = makeActive; 332 } 333 334 /*** 335 * Sets the port attribute of the IdTCPServer object 336 * 337 *@param newPort The new port value 338 */ 339 public void setDefaultPort(int newPort) { 340 this.defaultPort = newPort; 341 } 342 343 /*** 344 * Sets the executionListener attribute of the IdTCPServer object 345 * 346 *@param e The new executionListener value 347 */ 348 public void addServerExecuteListener(TCPServerExecuteListener e) { //throws TooManyListenersException{ 349 350 // if(executor == null){ 351 executor = e; 352 353 // } 354 // else { 355 // throw new TooManyListenersException("Only one TCPServerExecuteListener is permitted at a time. Call removeServerExecuteListener() first"); 356 // } 357 } 358 359 /*** 360 * DOCUMENT ME! 361 * 362 * @param e DOCUMENT ME! 363 */ 364 public void removeServerExecuteListener(TCPServerExecuteListener e) { 365 executor = null; 366 } 367 368 /*** 369 * DOCUMENT ME! 370 * 371 * @param listenQueue DOCUMENT ME! 372 */ 373 public void setListenQueue(int listenQueue) { 374 this.listenQueue = listenQueue; 375 } 376 377 /*** 378 * Sets the threadMgr attribute of the IdTCPServer object 379 * 380 *@param threadMgr The new threadMgr value 381 */ 382 public void setThreadManager(PeerThreadManager threadMgr) { 383 threadManager = threadMgr; 384 } 385 386 /*** 387 * DOCUMENT ME! 388 * 389 * @param index DOCUMENT ME! 390 * 391 * @return DOCUMENT ME! 392 */ 393 public TCPServerBinding getBinding(int index) { 394 return (TCPServerBinding) bindings.get(index); 395 } 396 397 /*** 398 * DOCUMENT ME! 399 * 400 * @return DOCUMENT ME! 401 */ 402 public TCPServerBinding[] getBindings() { 403 return (TCPServerBinding[]) bindings.toArray(); 404 } 405 406 /*** 407 * Gets the port attribute of the IdTCPServer object 408 * 409 *@return The port value 410 */ 411 public int getDefaultPort() { 412 return defaultPort; 413 } 414 415 /*** 416 * Gets the iOHandler attribute of the IdTCPServer object 417 * 418 *@return The iOHandler value 419 */ 420 public ServerIOHandler getIOHandler() { 421 return ioHandler; 422 } 423 424 /*** 425 * DOCUMENT ME! 426 * 427 * @return DOCUMENT ME! 428 */ 429 public int getListenQueue() { 430 return listenQueue; 431 } 432 433 /*** 434 * Gets the maxConnectionReply attribute of the IdTCPServer object 435 * 436 *@return The maxConnectionReply value 437 */ 438 public RFCReply getMaxConnectionReply() { 439 return maxConnectionReply; 440 } 441 442 /*** 443 * Gets the maxConnections attribute of the IdTCPServer object 444 * 445 *@return The maxConnections value 446 */ 447 public int getMaxConnections() { 448 return maxConnections; 449 } 450 451 /*** 452 * Gets the replyTexts attribute of the IdTCPServer object 453 * 454 *@return The replyTexts value 455 */ 456 public RFCReplies getReplyTexts() { 457 return relpyTexts; 458 } 459 460 /*** 461 * Gets the threadList attribute of the IdTCPServer object 462 * 463 *@return The threadList value 464 */ 465 public List getThreadList() { 466 return threadList; 467 } 468 469 /*** 470 * Gets the threadMgr attribute of the IdTCPServer object 471 * 472 *@return The threadMgr value 473 */ 474 public PeerThreadManager getThreadManager() { 475 return threadManager; 476 } 477 478 /*** 479 * DOCUMENT ME! 480 * 481 * @return DOCUMENT ME! 482 */ 483 public boolean isActive() { 484 return active; 485 } 486 487 /*** 488 * DOCUMENT ME! 489 * 490 * @param l DOCUMENT ME! 491 */ 492 public synchronized void removeTCPServerListener(TCPServerListener l) { 493 if ((TCPServerListeners != null) && TCPServerListeners.contains(l)) { 494 Vector v = (Vector) TCPServerListeners.clone(); 495 496 v.removeElement(l); 497 TCPServerListeners = v; 498 } 499 } 500 501 /*** 502 * DOCUMENT ME! 503 * 504 * @param l DOCUMENT ME! 505 */ 506 public synchronized void addTCPServerListener(TCPServerListener l) { 507 Vector v = (TCPServerListeners == null) 508 ? new Vector(2) : (Vector) TCPServerListeners.clone(); 509 510 if (!v.contains(l)) { 511 v.addElement(l); 512 TCPServerListeners = v; 513 } 514 } 515 516 /*** 517 * Collection for server listeners that handles syncing on the listener list 518 * on a request by request basis to reduce contention on the list at higher 519 * traffic volumes. 520 * 521 *@author Owen Green 522 *@created 26 September 2002 523 */ 524 private class ServerListenerList { 525 private final Collection listenerList = Collections.synchronizedCollection( 526 new HashSet()); 527 528 public void add(TCPServerListener l) { 529 listenerList.add(l); 530 } 531 532 public void remove(TCPServerListener l) { 533 listenerList.remove(l); 534 } 535 536 public TCPServerListener[] getArray() { 537 return (TCPServerListener[]) listenerList.toArray( 538 new TCPServerListener[listenerList.size()]); 539 } 540 541 public boolean isEmpty() { 542 return listenerList.isEmpty(); 543 } 544 } 545 }

This page was automatically generated by Maven