Source Code Cross Referenced for QuickServer.java in  » Net » QuickServer » org » quickserver » net » server » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » QuickServer » org.quickserver.net.server 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * This file is part of the QuickServer library 
0003:         * Copyright (C) QuickServer.org
0004:         *
0005:         * Use, modification, copying and distribution of this software is subject to
0006:         * the terms and conditions of the GNU Lesser General Public License. 
0007:         * You should have received a copy of the GNU LGP License along with this 
0008:         * library; if not, you can download a copy from <http://www.quickserver.org/>.
0009:         *
0010:         * For questions, suggestions, bug-reports, enhancement-requests etc.
0011:         * visit http://www.quickserver.org
0012:         *
0013:         */
0014:
0015:        package org.quickserver.net.server;
0016:
0017:        import java.io.*;
0018:        import java.net.*;
0019:
0020:        import org.quickserver.net.*; //v1.1
0021:        import org.quickserver.net.qsadmin.*; //v1.2
0022:        import java.util.logging.*; //v1.3
0023:        import org.quickserver.util.pool.*;
0024:        import org.quickserver.util.pool.thread.*;
0025:        import org.apache.commons.pool.*;
0026:        import org.quickserver.util.xmlreader.*;
0027:        import org.quickserver.sql.*; //v1.3.1
0028:        import java.util.*; //v1.3.2
0029:        import org.quickserver.util.*;
0030:        import java.util.regex.*; //v1.3.3
0031:        import org.quickserver.security.*; //v1.4.0
0032:        import javax.net.ssl.*;
0033:        import javax.net.*;
0034:        import java.security.*;
0035:        import java.security.cert.*;
0036:        import org.quickserver.util.io.*; //v1.4.5
0037:        import java.nio.*;
0038:        import java.nio.channels.*;
0039:        import org.quickserver.net.server.impl.*;
0040:
0041:        /**
0042:         * Main class of QuickServer library. This class is used to create 
0043:         * multi client servers quickly.
0044:         * <p>
0045:         * Ones a client is connected, it creates {@link ClientHandler} object, 
0046:         * which is run using any thread available from the pool of threads 
0047:         * maintained by {@link org.quickserver.util.pool.thread.ClientPool}, which 
0048:         * handles the client. <br/>
0049:         * QuickServer divides the application logic of its developer over eight 
0050:         * class, <br>
0051:         * 	<ul>
0052:         *		<li>ClientEventHandler<br>
0053:         * 		   &nbsp;Handles client events [Optional Class].
0054:         * 		<li>ClientCommandHandler [#]<br>
0055:         * 		   &nbsp;Handles client character/string commands.
0056:         * 		<li>ClientObjectHandler [#]<br>
0057:         * 		   &nbsp;Handles client interaction - Object commands.
0058:         *		<li>ClientBinaryHandler [#]<br>
0059:         * 		   &nbsp;Handles client interaction - binary data.
0060:         *		<li>ClientWriteHandler [Optional Class]<br>
0061:         * 		   &nbsp;Handles client interaction - writing data (Only used in non-blocking mode).
0062:         * 		<li>ClientAuthenticationHandler [Optional Class]<br>
0063:         * 			&nbsp;Used to Authencatet a client.
0064:         * 		<li>ClientData [Optional Class]<br>
0065:         * 			&nbsp;Client data carrier (support class)
0066:         *		<li>ClientExtendedEventHandler [Optional Class]<br>
0067:         * 		   &nbsp;Handles extended client events.
0068:         * 	</ul>
0069:         *
0070:         * [#] = Any one of these have to be set based on default DataMode for input. 
0071:         * The default DataMode for input is String so if not changes you will
0072:         * have to set ClientCommandHandler.
0073:         * </p>
0074:         * <p>
0075:         *  Eg:
0076:         * <code><BLOCKQUOTE><pre>
0077:         package echoserver;
0078:
0079:         import org.quickserver.net.*;
0080:         import org.quickserver.net.server.*;
0081:
0082:         import java.io.*;
0083:
0084:         public class EchoServer {
0085:         public static void main(String args[])	{
0086:         String cmdHandle = "echoserver.EchoCommandHandler";
0087:        
0088:         QuickServer myServer = new QuickServer();
0089:         myServer.setClientCommandHandler(cmdHandle);
0090:         myServer.setPort(4123);
0091:         myServer.setName(Echo Server v1.0");
0092:         try {
0093:         myServer.startServer();
0094:         } catch(AppException e) {
0095:         System.err.println("Error in server : "+e);
0096:         e.printStackTrace();
0097:         }
0098:         }
0099:         }
0100:         </pre></BLOCKQUOTE></code></p>
0101:         * 
0102:         * @version 1.4.7
0103:         * @author Akshathkumar Shetty
0104:         */
0105:        public class QuickServer implements  Runnable, Service, Cloneable,
0106:                Serializable {
0107:            //Some variable are not initialised to any value because the 
0108:            //default java value was desired initial value. 
0109:
0110:            //'dev ' = development build not yet final
0111:            //'beta' = test build all features
0112:            private final static String VER = "1.4.7";//change also in QSAdminMain
0113:            private final static String NEW_LINE = "\r\n";
0114:
0115:            static {
0116:                System.out.print("Loading QuickServer v" + getVersion() + " ");
0117:            }
0118:
0119:            private String serverBanner;
0120:
0121:            private String clientAuthenticationHandlerString; //v1.4.6
0122:            private String clientEventHandlerString; //v1.4.6
0123:            private String clientExtendedEventHandlerString; //v1.4.6
0124:            private String clientCommandHandlerString;
0125:            private String clientObjectHandlerString; //v1.2
0126:            private String clientBinaryHandlerString; //v1.4
0127:            private String clientWriteHandlerString; //v1.4.5
0128:            private String clientDataString;
0129:
0130:            private Authenticator authenticator;
0131:            private ClientAuthenticationHandler clientAuthenticationHandler; //v1.4.6
0132:            private ClientEventHandler clientEventHandler; //v1.4.6
0133:            private ClientExtendedEventHandler clientExtendedEventHandler; //v1.4.6
0134:            private ClientCommandHandler clientCommandHandler;
0135:            private ClientObjectHandler clientObjectHandler; //v1.2
0136:            private ClientBinaryHandler clientBinaryHandler; //v1.4
0137:            private ClientWriteHandler clientWriteHandler; //v1.4.5
0138:            private ClientData clientData;
0139:            protected Class clientDataClass;
0140:
0141:            private int serverPort = 9876;
0142:            private Thread t; //Main thread
0143:            private ServerSocket server;
0144:            private String serverName = "QuickServer";
0145:            private long maxConnection = -1;
0146:            private int socketTimeout = 60 * 1000; //1 min socket timeout
0147:            private String maxConnectionMsg = "-ERR Server Busy. Max Connection Reached";
0148:            private String timeoutMsg = "-ERR Timeout";
0149:            private String maxAuthTryMsg = "-ERR Max Auth Try Reached";
0150:            private int maxAuthTry = 5; //v1.2	
0151:
0152:            static {
0153:                System.out.print(".");
0154:            }
0155:
0156:            //--v1.1
0157:            private InetAddress ipAddr;
0158:            private boolean stopServer;
0159:            private Object[] storeObjects;
0160:            private QSAdminServer adminServer;
0161:
0162:            //--v1.2
0163:            //Logger for QuickServer
0164:            private static final Logger logger = Logger
0165:                    .getLogger(QuickServer.class.getName());
0166:            //Logger for the application using this QuickServer
0167:            private Logger appLogger;
0168:
0169:            //for Service interface
0170:            private long suspendMaxConnection; //backup
0171:            private String suspendMaxConnectionMsg; //backup
0172:            private int serviceState = Service.UNKNOWN;
0173:
0174:            static {
0175:                System.out.print(".");
0176:            }
0177:
0178:            //--v1.3
0179:            private QuickServerConfig config = new QuickServerConfig();
0180:            private String consoleLoggingformatter;
0181:            private String consoleLoggingLevel = "INFO";
0182:            private ClientPool pool;
0183:            private ObjectPool clientHandlerPool;
0184:            private ObjectPool clientDataPool;
0185:            private DBPoolUtil dBPoolUtil;
0186:
0187:            //--v1.3.1
0188:            private String loggingLevel = "INFO";
0189:
0190:            //--v1.3.2
0191:            private boolean skipValidation = false;
0192:            private boolean communicationLogging = true;
0193:
0194:            //--v1.3.3
0195:            private String securityManagerClass;
0196:            private AccessConstraintConfig accessConstraintConfig;
0197:            private ClassLoader classLoader;
0198:            private String applicationJarPath;
0199:            private ServerHooks serverHooks;
0200:            private ArrayList listOfServerHooks;
0201:
0202:            static {
0203:                System.out.print(".");
0204:            }
0205:
0206:            //--v1.4.0
0207:            private Secure secure;
0208:            private BasicServerConfig basicConfig = config;
0209:            private SSLContext sslc;
0210:            private KeyManager km[] = null;
0211:            private TrustManager tm[] = null;
0212:            private boolean runningSecure = false;
0213:            private SecureStoreManager secureStoreManager = null;
0214:
0215:            private Exception exceptionInRun = null;
0216:
0217:            //--v1.4.5
0218:            private ServerSocketChannel serverSocketChannel;
0219:            private Selector selector;
0220:            private boolean blockingMode = true;
0221:            private ObjectPool byteBufferPool;
0222:            private java.util.Date lastStartTime;
0223:            private ClientIdentifier clientIdentifier;
0224:            private GhostSocketReaper ghostSocketReaper;
0225:            private PoolManager poolManager;
0226:            private QSObjectPoolMaker qsObjectPoolMaker;
0227:
0228:            //--v1.4.6
0229:            private DataMode defaultDataModeIN = DataMode.STRING;
0230:            private DataMode defaultDataModeOUT = DataMode.STRING;
0231:
0232:            //-v1.4.7
0233:            private Throwable serviceError;
0234:            private Map registerChannelRequestMap;
0235:
0236:            static {
0237:                System.out.println(" Done");
0238:                //should be commented if not a patch release
0239:                //System.out.println("[Includes patch(#): t=152&p=532]");
0240:                //should be commented if not a dev release
0241:                //System.out.println("[Dev Build Date: Saturday, October 29, 2005]");
0242:            }
0243:
0244:            /** Returns the version of the library. */
0245:            public static final String getVersion() {
0246:                return VER;
0247:            }
0248:
0249:            /** 
0250:             * Returns the numerical version of the library.
0251:             * @since 1.2
0252:             */
0253:            public static final float getVersionNo() {
0254:                return getVersionNo(VER);
0255:            }
0256:
0257:            /** 
0258:             * Returns the numerical version of the library.
0259:             * @since 1.4.5
0260:             */
0261:            public static final float getVersionNo(String ver) {
0262:                //String ver = getVersion();
0263:                float version = 0;
0264:                int i = ver.indexOf(" "); //check if beta
0265:                if (i == -1)
0266:                    i = ver.length();
0267:                ver = ver.substring(0, i);
0268:
0269:                i = ver.indexOf("."); //check for sub version
0270:                if (i != -1) {
0271:                    int j = ver.indexOf(".", i);
0272:                    if (j != -1) {
0273:                        ver = ver.substring(0, i)
0274:                                + "."
0275:                                + MyString.replaceAll(ver.substring(i + 1),
0276:                                        ".", "");
0277:                    }
0278:                }
0279:
0280:                try {
0281:                    version = Float.parseFloat(ver);
0282:                } catch (NumberFormatException e) {
0283:                    throw new RuntimeException("Corrupt QuickServer");
0284:                }
0285:                return version;
0286:            }
0287:
0288:            /**
0289:             * Returns the new line string used by QuickServer.
0290:             * @since 1.2
0291:             */
0292:            public static String getNewLine() {
0293:                return NEW_LINE;
0294:            }
0295:
0296:            /**
0297:             * Returns the Server name : port of the QuickServer.
0298:             */
0299:            public String toString() {
0300:                return serverName + " : " + getPort();
0301:            }
0302:
0303:            /**
0304:             * Creates a new server without any configuration.
0305:             * Make sure you configure the QuickServer, before 
0306:             * calling startServer()
0307:             * @see org.quickserver.net.server.ClientEventHandler
0308:             * @see org.quickserver.net.server.ClientCommandHandler
0309:             * @see org.quickserver.net.server.ClientObjectHandler
0310:             * @see org.quickserver.net.server.ClientBinaryHandler
0311:             * @see org.quickserver.net.server.ClientWriteHandler
0312:             * @see org.quickserver.net.server.ClientAuthenticationHandler
0313:             * @see org.quickserver.net.server.ClientHandler
0314:             * @see #configQuickServer
0315:             * @see #initService
0316:             * @see #setPort
0317:             * @see #setClientCommandHandler
0318:             * @since 1.2
0319:             */
0320:            public QuickServer() {
0321:            }
0322:
0323:            /**
0324:             * Creates a new server with the specified  
0325:             * <code>commandHandler</code> has it {@link ClientCommandHandler}.
0326:             * @param commandHandler the fully qualified name of the 
0327:             *  desired class that implements {@link ClientCommandHandler}
0328:             *
0329:             * @see org.quickserver.net.server.ClientCommandHandler
0330:             * @see org.quickserver.net.server.ClientAuthenticationHandler
0331:             * @see org.quickserver.net.server.ClientHandler
0332:             * @see #setPort
0333:             */
0334:            public QuickServer(String commandHandler) {
0335:                setClientCommandHandler(commandHandler);
0336:            }
0337:
0338:            /**
0339:             * Creates a new server at <code>port</code> with the specified  
0340:             * <code>commandHandler</code> has it {@link ClientCommandHandler}.
0341:             *
0342:             * @param commandHandler fully qualified name of the class that
0343:             * implements {@link ClientCommandHandler}
0344:             * @param port to listen on.
0345:             *
0346:             * @see org.quickserver.net.server.ClientCommandHandler
0347:             * @see org.quickserver.net.server.ClientAuthenticationHandler
0348:             * @see org.quickserver.net.server.ClientHandler
0349:             */
0350:            public QuickServer(String commandHandler, int port) {
0351:                this (commandHandler); //send to another constructor
0352:                setPort(port);
0353:            }
0354:
0355:            /**
0356:             * Starts the QuickServer.
0357:             *
0358:             * @exception org.quickserver.net.AppException 
0359:             *  if Server already running or if it could not load the classes
0360:             *  [ClientCommandHandler, ClientAuthenticationHandler, ClientData].
0361:             * @see #startService
0362:             */
0363:            public void startServer() throws AppException {
0364:                logger.fine("Starting " + getName());
0365:
0366:                if (isClosed() == false) {
0367:                    logger.warning("Server " + getName() + " already running.");
0368:                    throw new AppException("Server " + getName()
0369:                            + " already running.");
0370:                }
0371:
0372:                if (serverBanner == null) {
0373:                    serverBanner = "\n-------------------------------"
0374:                            + "\n Name : " + getName() + "\n Port : "
0375:                            + getPort() + "\n-------------------------------\n";
0376:                    logger.finest("Default Server Banner Generated");
0377:                }
0378:                try {
0379:                    loadApplicationClasses();
0380:
0381:                    //load class from Advanced Settings
0382:                    Class clientIdentifierClass = getClass(getBasicConfig()
0383:                            .getAdvancedSettings().getClientIdentifier(), true);
0384:                    clientIdentifier = (ClientIdentifier) clientIdentifierClass
0385:                            .newInstance();
0386:                    clientIdentifier.setQuickServer(QuickServer.this );
0387:
0388:                    //load class from ObjectPoolConfig
0389:                    Class poolManagerClass = getClass(getBasicConfig()
0390:                            .getObjectPoolConfig().getPoolManager(), true);
0391:                    poolManager = (PoolManager) poolManagerClass.newInstance();
0392:
0393:                    //load class QSObjectPoolMaker
0394:                    Class qsObjectPoolMakerClass = getClass(getBasicConfig()
0395:                            .getAdvancedSettings().getQSObjectPoolMaker(), true);
0396:                    qsObjectPoolMaker = (QSObjectPoolMaker) qsObjectPoolMakerClass
0397:                            .newInstance();
0398:
0399:                    loadServerHooksClasses();
0400:                    processServerHooks(ServerHook.PRE_STARTUP);
0401:
0402:                    if (getSecure().isLoad() == true)
0403:                        loadSSLContext(); //v1.4.0
0404:
0405:                    loadBusinessLogic();
0406:                } catch (ClassNotFoundException e) {
0407:                    logger.severe("Could not load class/s : " + e.getMessage());
0408:                    throw new AppException("Could not load class/s : "
0409:                            + e.getMessage());
0410:                } catch (InstantiationException e) {
0411:                    logger.severe("Could not instantiate class/s : "
0412:                            + e.getMessage());
0413:                    throw new AppException("Could not instantiate class/s : "
0414:                            + e.getMessage());
0415:                } catch (IllegalAccessException e) {
0416:                    logger.severe("Illegal access to class/s : "
0417:                            + e.getMessage());
0418:                    throw new AppException("Illegal access to class/s : "
0419:                            + e.getMessage());
0420:                } catch (IOException e) {
0421:                    logger.severe("IOException : " + e.getMessage());
0422:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
0423:                    throw new AppException("IOException : " + e.getMessage());
0424:                } catch (Exception e) {
0425:                    logger.severe("Exception : " + e.getMessage());
0426:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
0427:                    throw new AppException("Exception : " + e);
0428:                }
0429:
0430:                //v1.3.3
0431:                if (getSecurityManagerClass() != null) {
0432:                    System.setSecurityManager(getSecurityManager());
0433:                }
0434:
0435:                blockingMode = getBasicConfig().getServerMode().getBlocking();
0436:
0437:                setServiceState(Service.INIT);
0438:                t = new Thread(this , "QuickServer - " + getName());
0439:                t.start();
0440:
0441:                do {
0442:                    Thread.yield();
0443:                } while (getServiceState() == Service.INIT);
0444:
0445:                if (getServiceState() != Service.RUNNING) {
0446:                    if (exceptionInRun != null)
0447:                        throw new AppException("Could not start server "
0448:                                + getName() + "! Details: " + exceptionInRun);
0449:                    else
0450:                        throw new AppException("Could not start server "
0451:                                + getName());
0452:                }
0453:                lastStartTime = new java.util.Date();
0454:                logger
0455:                        .fine("Started " + getName() + ", Date: "
0456:                                + lastStartTime);
0457:            }
0458:
0459:            /**
0460:             * Stops the QuickServer.
0461:             *
0462:             * @exception org.quickserver.net.AppException 
0463:             *  if could not stop server
0464:             * @since 1.1
0465:             * @see #stopService
0466:             */
0467:            public void stopServer() throws AppException {
0468:                processServerHooks(ServerHook.PRE_SHUTDOWN);
0469:                logger.warning("Stopping " + getName());
0470:                stopServer = true;
0471:                Socket death = null;
0472:                if (isClosed() == true) {
0473:                    logger.warning("Server " + getName() + " is not running!");
0474:                    throw new AppException("Server " + getName()
0475:                            + " is not running!");
0476:                }
0477:                try {
0478:                    if (getBlockingMode() == true) {
0479:                        if (getSecure().isEnable() == false) {
0480:                            death = new Socket(server.getInetAddress(), server
0481:                                    .getLocalPort());
0482:                            death.getInputStream().read();
0483:                            death.close();
0484:                        } else {
0485:                            death = getSSLSocketFactory().createSocket(
0486:                                    server.getInetAddress(),
0487:                                    server.getLocalPort());
0488:                            Thread.currentThread().sleep(100);
0489:                            death.close();
0490:                        }
0491:                    }
0492:
0493:                    if (serverSocketChannel != null) {
0494:                        serverSocketChannel.close();
0495:                    }
0496:
0497:                } catch (IOException e) {
0498:                    logger.fine("IOError stopping " + getName() + ": " + e);
0499:                } catch (Exception e) {
0500:                    logger.warning("Error stopping " + getName() + ": " + e);
0501:                    throw new AppException("Error in stopServer " + getName()
0502:                            + ": " + e);
0503:                }
0504:
0505:                for (int i = 0; getServiceState() != Service.STOPPED; i++) {
0506:                    try {
0507:                        Thread.sleep(60);
0508:                    } catch (Exception e) {
0509:                        logger.warning("Error waiting for " + getName()
0510:                                + " to fully stop. Error: " + e);
0511:                    }
0512:                    if (i > 1000) {
0513:                        logger
0514:                                .severe("Server was not stopped even after 10sec.. will terminate now.");
0515:                        System.exit(-1);
0516:                    }
0517:                }
0518:                if (adminServer == null
0519:                        || getQSAdminServer().getServer() != this ) {
0520:                    //so this is not qsadmin
0521:                    setClassLoader(null);
0522:                }
0523:                logger.info("Stopped " + getName());
0524:            }
0525:
0526:            /**
0527:             * Restarts the QuickServer.
0528:             *
0529:             * @exception org.quickserver.net.AppException 
0530:             *  if could not stop server or if it could not start the server.
0531:             * @since 1.2
0532:             */
0533:            public void restartServer() throws AppException {
0534:                stopServer();
0535:                startServer();
0536:            }
0537:
0538:            /**
0539:             * Returns the name of the QuickServer. Default is 'QuickServer'.
0540:             * @see #setName
0541:             */
0542:            public String getName() {
0543:                return serverName;
0544:            }
0545:
0546:            /**
0547:             * Sets the name for the QuickServer
0548:             * @param name for the QuickServer
0549:             * @see #getName
0550:             */
0551:            public void setName(String name) {
0552:                serverName = name;
0553:                logger.finest("Set to : " + name);
0554:            }
0555:
0556:            /**
0557:             * Returns the Server Banner of the QuickServer
0558:             * @see #setServerBanner
0559:             */
0560:            public String getServerBanner() {
0561:                return serverBanner;
0562:            }
0563:
0564:            /**
0565:             * Sets the serverBanner for the QuickServer
0566:             * that will be displayed on the standard output [console]
0567:             * when server starts. <br>&nbsp;<br>
0568:             * To set welcome message to your client
0569:             * {@link ClientEventHandler#gotConnected}
0570:             * @param banner for the QuickServer
0571:             * @see #getServerBanner
0572:             */
0573:            public void setServerBanner(String banner) {
0574:                serverBanner = banner;
0575:                logger.finest("Set to : " + banner);
0576:            }
0577:
0578:            /**
0579:             * Sets the port for the QuickServer to listen on.
0580:             * If not set, it will run on Port 9876 
0581:             * @param port to listen on.
0582:             * @see #getPort
0583:             */
0584:            public void setPort(int port) {
0585:                if (port < 0) {
0586:                    throw new IllegalArgumentException(
0587:                            "Port number can not be less than 0!");
0588:                }
0589:                serverPort = port;
0590:                logger.finest("Set to " + port);
0591:            }
0592:
0593:            /**
0594:             * Returns the port for the QuickServer.
0595:             * @see #setPort
0596:             */
0597:            public int getPort() {
0598:                if (isClosed() == false) {
0599:                    return server.getLocalPort();
0600:                }
0601:
0602:                if (getSecure().isEnable() == false) {
0603:                    return serverPort;
0604:                } else {
0605:                    int _port = getSecure().getPort();
0606:                    if (_port == -1)
0607:                        return serverPort;
0608:                    else
0609:                        return _port;
0610:                }
0611:            }
0612:
0613:            /**
0614:             * Sets the ClientCommandHandler class that interacts with 
0615:             * client sockets.
0616:             * @param handler the fully qualified name of the class that 
0617:             *  implements {@link ClientCommandHandler}
0618:             * @see #getClientCommandHandler
0619:             */
0620:            public void setClientCommandHandler(String handler) {
0621:                clientCommandHandlerString = handler;
0622:                logger.finest("Set to " + handler);
0623:            }
0624:
0625:            /**
0626:             * Returns the ClientCommandHandler class that interacts with 
0627:             * client sockets.
0628:             * @see #setClientCommandHandler
0629:             * @since 1.1
0630:             */
0631:            public String getClientCommandHandler() {
0632:                return clientCommandHandlerString;
0633:            }
0634:
0635:            /**
0636:             * Sets the ClientAuthenticationHandler class that 
0637:             * handles the authentication of a client.
0638:             * @param authenticator the fully qualified name of the class 
0639:             * that implements {@link ClientAuthenticationHandler}.
0640:             * @see #getClientAuthenticationHandler
0641:             * @since 1.4.6
0642:             */
0643:            public void setClientAuthenticationHandler(String authenticator) {
0644:                clientAuthenticationHandlerString = authenticator;
0645:                logger.finest("Set to " + authenticator);
0646:            }
0647:
0648:            /**
0649:             * Returns the ClientAuthenticationHandler class that 
0650:             * handles the authentication of a client.
0651:             * @see #setClientAuthenticationHandler
0652:             * @since 1.4.6
0653:             */
0654:            public String getClientAuthenticationHandler() {
0655:                return clientAuthenticationHandlerString;
0656:            }
0657:
0658:            /**
0659:             * Sets the Authenticator class that 
0660:             * handles the authentication of a client.
0661:             * @param authenticator the fully qualified name of the class 
0662:             * that implements {@link Authenticator} or {@link ClientAuthenticationHandler}.
0663:             * @see #getAuthenticator
0664:             * @deprecated since 1.4.6 use setClientAuthenticationHandler
0665:             * @since 1.3
0666:             */
0667:            public void setAuthenticator(String authenticator) {
0668:                clientAuthenticationHandlerString = authenticator;
0669:                logger.finest("Set to " + authenticator);
0670:            }
0671:
0672:            /**
0673:             * Returns the Authenticator class that 
0674:             * handles the authentication of a client.
0675:             * @see #setAuthenticator
0676:             * @deprecated since 1.4.6 use getClientAuthenticationHandler
0677:             * @since 1.3
0678:             */
0679:            public String getAuthenticator() {
0680:                return clientAuthenticationHandlerString;
0681:            }
0682:
0683:            /**
0684:             * Sets the ClientData class that carries client data.
0685:             * @param data the fully qualified name of the class that 
0686:             * extends {@link ClientData}.
0687:             * @see #getClientData
0688:             */
0689:            public void setClientData(String data) {
0690:                this .clientDataString = data;
0691:                logger.finest("Set to " + data);
0692:            }
0693:
0694:            /**
0695:             * Returns the ClientData class string that carries client data  
0696:             * @return the fully qualified name of the class that 
0697:             * implements {@link ClientData}.
0698:             * @see #setClientData
0699:             */
0700:            public String getClientData() {
0701:                return clientDataString;
0702:            }
0703:
0704:            /**
0705:             * Sets the client socket's timeout.
0706:             * @param time client socket timeout in milliseconds.
0707:             * @see #getTimeout
0708:             */
0709:            public void setTimeout(int time) {
0710:                if (time > 0)
0711:                    socketTimeout = time;
0712:                else
0713:                    socketTimeout = 0;
0714:                logger.finest("Set to " + socketTimeout);
0715:            }
0716:
0717:            /**
0718:             * Returns the Client socket timeout in milliseconds.
0719:             * @see #setTimeout
0720:             */
0721:            public int getTimeout() {
0722:                return socketTimeout;
0723:            }
0724:
0725:            /** 
0726:             * Sets max allowed login attempts.
0727:             * @since 1.2
0728:             * @see #getMaxAuthTry
0729:             */
0730:            public void setMaxAuthTry(int authTry) {
0731:                maxAuthTry = authTry;
0732:                logger.finest("Set to " + authTry);
0733:            }
0734:
0735:            /** 
0736:             * Returns max allowed login attempts. Default is <code>5</code>.
0737:             * @since 1.2
0738:             * @see #setMaxAuthTry
0739:             */
0740:            public int getMaxAuthTry() {
0741:                return maxAuthTry;
0742:            }
0743:
0744:            /** 
0745:             * Sets message to be displayed when maximum allowed login 
0746:             * attempts has reached.
0747:             * Default is : -ERR Max Auth Try Reached
0748:             * @see #getMaxAuthTryMsg
0749:             */
0750:            public void setMaxAuthTryMsg(String msg) {
0751:                maxAuthTryMsg = msg;
0752:                logger.finest("Set to " + msg);
0753:            }
0754:
0755:            /** 
0756:             * Returns message to be displayed when maximum allowed login 
0757:             * attempts has reached.
0758:             * @see #getMaxAuthTryMsg
0759:             */
0760:            public String getMaxAuthTryMsg() {
0761:                return maxAuthTryMsg;
0762:            }
0763:
0764:            /**
0765:             * Sets timeout message. 
0766:             * Default is : -ERR Timeout
0767:             * @see #getTimeoutMsg
0768:             */
0769:            public void setTimeoutMsg(String msg) {
0770:                timeoutMsg = msg;
0771:                logger.finest("Set to " + msg);
0772:            }
0773:
0774:            /** 
0775:             * Returns timeout message.
0776:             * @see #setTimeoutMsg
0777:             */
0778:            public String getTimeoutMsg() {
0779:                return timeoutMsg;
0780:            }
0781:
0782:            private TheClient initTheClient() {
0783:                TheClient theClient = new TheClient();
0784:                theClient.setServer(QuickServer.this );
0785:                theClient.setTimeoutMsg(getTimeoutMsg());
0786:                theClient.setMaxAuthTry(getMaxAuthTry()); //v1.2
0787:                theClient.setMaxAuthTryMsg(getMaxAuthTryMsg());
0788:
0789:                theClient.setClientEventHandler(clientEventHandler);
0790:                theClient
0791:                        .setClientExtendedEventHandler(clientExtendedEventHandler); //v1.4.6
0792:                theClient.setClientCommandHandler(clientCommandHandler);
0793:                theClient.setClientObjectHandler(clientObjectHandler); //v1.2
0794:                theClient.setClientBinaryHandler(clientBinaryHandler); //v1.4
0795:                theClient.setClientWriteHandler(clientWriteHandler); //v1.4.5
0796:                theClient.setAuthenticator(authenticator); //v1.3
0797:                theClient
0798:                        .setClientAuthenticationHandler(clientAuthenticationHandler); //v1.4.6
0799:                theClient.setTimeout(socketTimeout);
0800:                theClient.setMaxConnectionMsg(maxConnectionMsg);
0801:                theClient.setCommunicationLogging(getCommunicationLogging()); //v1.3.2
0802:                return theClient;
0803:            }
0804:
0805:            public void run() {
0806:                exceptionInRun = null;
0807:                TheClient theClient = initTheClient();
0808:                try {
0809:                    stopServer = false;
0810:
0811:                    closeAllPools();
0812:                    initAllPools();
0813:
0814:                    makeServerSocket();
0815:                    System.out.println(serverBanner); //print banner
0816:                    setServiceState(Service.RUNNING); //v1.2
0817:
0818:                    processServerHooks(ServerHook.POST_STARTUP); //v1.3.3
0819:                    if (getBlockingMode() == false) {
0820:                        runNonBlocking(theClient);
0821:                        if (stopServer == true) {
0822:                            logger.finest("Closing selector for " + getName());
0823:                            selector.close();
0824:                        }
0825:                        return;
0826:                    } else {
0827:                        runBlocking(theClient);
0828:                    }
0829:                } catch (BindException e) {
0830:                    exceptionInRun = e;
0831:                    logger.severe(getName() + " BindException for Port "
0832:                            + getPort() + " @ "
0833:                            + getBindAddr().getHostAddress() + " : "
0834:                            + e.getMessage());
0835:                } catch (javax.net.ssl.SSLException e) {
0836:                    exceptionInRun = e;
0837:                    logger.severe("SSLException " + e);
0838:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
0839:                } catch (IOException e) {
0840:                    exceptionInRun = e;
0841:                    logger.severe("IOError " + e);
0842:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
0843:                } catch (Exception e) {
0844:                    exceptionInRun = e;
0845:                    logger.severe("Error " + e);
0846:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
0847:                } finally {
0848:                    if (getBlockingMode() == true) {
0849:                        logger.warning("Closing " + getName());
0850:                        try {
0851:                            if (isClosed() == false) {
0852:                                server.close();
0853:                            }
0854:                        } catch (Exception e) {
0855:                            throw new RuntimeException(e);
0856:                        }
0857:                        server = null;
0858:                        serverSocketChannel = null;
0859:
0860:                        setServiceState(Service.STOPPED);
0861:                        logger.warning("Closed " + getName());
0862:
0863:                        processServerHooks(ServerHook.POST_SHUTDOWN);
0864:                    } else if (getBlockingMode() == false
0865:                            && exceptionInRun != null) {
0866:                        logger.warning("Closing " + getName()
0867:                                + " - Had Error: " + exceptionInRun);
0868:                        try {
0869:                            if (isClosed() == false) {
0870:                                if (serverSocketChannel != null)
0871:                                    serverSocketChannel.close();
0872:                                if (server != null)
0873:                                    server.close();
0874:                            }
0875:                        } catch (Exception e) {
0876:                            throw new RuntimeException(e);
0877:                        }
0878:
0879:                        server = null;
0880:                        serverSocketChannel = null;
0881:
0882:                        setServiceState(Service.STOPPED);
0883:                        logger.warning("Closed " + getName());
0884:
0885:                        processServerHooks(ServerHook.POST_SHUTDOWN);
0886:                    }
0887:                }
0888:            } //end of run
0889:
0890:            /**
0891:             * Sets the maximum number of client connection allowed.
0892:             * @since 1.1
0893:             * @see #getMaxConnection
0894:             */
0895:            public void setMaxConnection(long maxConnection) {
0896:                if (getServiceState() == Service.SUSPENDED)
0897:                    suspendMaxConnection = maxConnection;
0898:                else
0899:                    this .maxConnection = maxConnection;
0900:                logger.finest("Set to " + maxConnection);
0901:            }
0902:
0903:            /** 
0904:             * Returns the maximum number of client connection allowed.
0905:             * @since 1.1
0906:             * @see #setMaxConnection
0907:             */
0908:            public long getMaxConnection() {
0909:                return maxConnection;
0910:            }
0911:
0912:            /** 
0913:             * Returns number of clients connected.
0914:             * @since 1.1
0915:             */
0916:            public long getClientCount() {
0917:                if (clientHandlerPool != null) {
0918:                    try {
0919:                        return getClientHandlerPool().getNumActive();
0920:                    } catch (Exception e) {
0921:                        return 0;
0922:                    }
0923:                }
0924:                return 0;
0925:            }
0926:
0927:            /**
0928:             * Sets the message to be sent to any new client connected after
0929:             * maximum client connection has reached. 
0930:             * Default is : <code>-ERR Server Busy. Max Connection Reached</code>
0931:             * @since 1.1
0932:             * @see #getMaxConnectionMsg
0933:             */
0934:            public void setMaxConnectionMsg(String maxConnectionMsg) {
0935:                if (getServiceState() == Service.SUSPENDED)
0936:                    suspendMaxConnectionMsg = maxConnectionMsg;
0937:                else
0938:                    this .maxConnectionMsg = maxConnectionMsg;
0939:                logger.finest("Set to " + maxConnectionMsg);
0940:            }
0941:
0942:            /**
0943:             * Returns the message to be sent to any new client connected 
0944:             * after maximum client connection has reached.
0945:             * @since 1.1
0946:             * @see #setMaxConnectionMsg
0947:             */
0948:            public String getMaxConnectionMsg() {
0949:                return maxConnectionMsg;
0950:            }
0951:
0952:            /**
0953:             * Sets the Ip address to bind to. 
0954:             * @param bindAddr argument can be used on a multi-homed host for a 
0955:             * QuickServer that will only accept connect requests to one 
0956:             * of its addresses. If not set, it will default accepting 
0957:             * connections on any/all local addresses.
0958:             * @exception java.net.UnknownHostException if no IP address for 
0959:             * the host could be found
0960:             * @since 1.1
0961:             * @see #getBindAddr
0962:             */
0963:            public void setBindAddr(String bindAddr)
0964:                    throws UnknownHostException {
0965:                ipAddr = InetAddress.getByName(bindAddr);
0966:                logger.finest("Set to " + bindAddr);
0967:            }
0968:
0969:            /**
0970:             * Returns the IP address binding to. 
0971:             * @since 1.1
0972:             * @see #setBindAddr
0973:             */
0974:            public InetAddress getBindAddr() {
0975:                if (ipAddr == null) {
0976:                    try {
0977:                        ipAddr = InetAddress.getByName("0.0.0.0");
0978:                    } catch (Exception e) {
0979:                        logger
0980:                                .warning("Unable to create default ip(0.0.0.0) : "
0981:                                        + e);
0982:                        throw new RuntimeException(
0983:                                "Error: Unable to find servers own ip : " + e);
0984:                    }
0985:                }
0986:                return ipAddr;
0987:            }
0988:
0989:            /**
0990:             * Sets the store of objects to QuickServer, it is an array of objects  
0991:             * that main program or the class that created QuickServer passes to 
0992:             * the QuickServer. 
0993:             * @param storeObjects array of objects
0994:             * @see #getStoreObjects
0995:             * @since 1.1
0996:             */
0997:            public void setStoreObjects(Object[] storeObjects) {
0998:                this .storeObjects = storeObjects;
0999:            }
1000:
1001:            /**
1002:             * Returns store of objects from QuickServer, if nothing was set will
1003:             * return <code>null</code>.
1004:             * @see #setStoreObjects
1005:             * @since 1.1
1006:             */
1007:            public Object[] getStoreObjects() {
1008:                return storeObjects;
1009:            }
1010:
1011:            /** 
1012:             * Set the port to run QSAdminServer on.
1013:             * @since 1.2
1014:             */
1015:            public void setQSAdminServerPort(int port) {
1016:                getQSAdminServer().getServer().setPort(port);
1017:            }
1018:
1019:            /** 
1020:             * Returns the port to run QSAdminServer on.
1021:             * @since 1.2
1022:             */
1023:            public int getQSAdminServerPort() {
1024:                return getQSAdminServer().getServer().getPort();
1025:            }
1026:
1027:            /** 
1028:             * Set the ClientAuthenticationHandler class of 
1029:             * QSAdminServer that handles the authentication of a client.
1030:             * @since 1.2
1031:             */
1032:            public void setQSAdminServerAuthenticator(String authenticator) {
1033:                getQSAdminServer().getServer().setClientAuthenticationHandler(
1034:                        authenticator);
1035:            }
1036:
1037:            /** 
1038:             * Returns the Authenticator or ClientAuthenticationHandler class of 
1039:             * QSAdminServer that handles the authentication of a client.
1040:             * @since 1.2
1041:             */
1042:            public String getQSAdminServerAuthenticator() {
1043:                return getQSAdminServer().getServer().getAuthenticator();
1044:            }
1045:
1046:            /**
1047:             * Starts QSAdminServer for this QuickServer.
1048:             * @see org.quickserver.net.qsadmin.QSAdminServer
1049:             * @param authenticator sets the ClientAuthenticationHandler class that 
1050:             *   handles the authentication of a client, 
1051:             *   if null uses {@link org.quickserver.net.qsadmin.Authenticator}.
1052:             * @param port to run QSAdminServer on
1053:             * @exception org.quickserver.net.AppException 
1054:             *  if Server already running or if it could not load the classes
1055:             *  [ClientCommandHandler, ClientAuthenticationHandler, ClientData].
1056:             * @since 1.1
1057:             */
1058:            public void startQSAdminServer(int port, String authenticator)
1059:                    throws AppException {
1060:                getQSAdminServer()
1061:                        .setClientAuthenticationHandler(authenticator);
1062:                getQSAdminServer().startServer(port);
1063:            }
1064:
1065:            /**
1066:             * Starts QSAdminServer for this QuickServer.
1067:             * @see org.quickserver.net.qsadmin.QSAdminServer
1068:             * @since 1.2
1069:             */
1070:            public void startQSAdminServer() throws AppException {
1071:                getQSAdminServer().startServer();
1072:            }
1073:
1074:            /**
1075:             * Returns {@link QSAdminServer} associated with this QuickServer
1076:             * @since 1.1
1077:             */
1078:            public QSAdminServer getQSAdminServer() {
1079:                if (adminServer == null)
1080:                    adminServer = new QSAdminServer(QuickServer.this );
1081:                return adminServer;
1082:            }
1083:
1084:            /**
1085:             * Sets {@link QSAdminServer} associated with this QuickServer
1086:             * @since 1.3.3
1087:             */
1088:            public void setQSAdminServer(QSAdminServer adminServer) {
1089:                if (adminServer == null)
1090:                    this .adminServer = adminServer;
1091:            }
1092:
1093:            /** 
1094:             * Returns the closed state of the QuickServer Socket.
1095:             * @since 1.1
1096:             */
1097:            public boolean isClosed() {
1098:                if (server == null)
1099:                    return true;
1100:                return server.isClosed();
1101:            }
1102:
1103:            /** 
1104:             * Returns the application logger associated with QuickServer.
1105:             * If it was not set will return QuickServer's own logger.
1106:             * @since 1.2
1107:             */
1108:            public Logger getAppLogger() {
1109:                if (appLogger != null)
1110:                    return appLogger;
1111:                return logger;
1112:            }
1113:
1114:            /** 
1115:             * Sets the application logger associated with QuickServer
1116:             * @since 1.2
1117:             */
1118:            public void setAppLogger(Logger appLogger) {
1119:                this .appLogger = appLogger;
1120:            }
1121:
1122:            /**
1123:             * Sets the ClientObjectHandler class that interacts with 
1124:             * client sockets to handle java objects.
1125:             * @param handler object the fully qualified name of the class that 
1126:             *  implements {@link ClientObjectHandler}
1127:             * @see #getClientObjectHandler
1128:             * @since 1.2
1129:             */
1130:            public void setClientObjectHandler(String handler) {
1131:                clientObjectHandlerString = handler;
1132:                logger.finest("Set to " + handler);
1133:            }
1134:
1135:            /**
1136:             * Returns the ClientObjectHandler class that interacts with 
1137:             * client sockets.
1138:             * @see #setClientObjectHandler
1139:             * @since 1.2
1140:             */
1141:            public String getClientObjectHandler() {
1142:                return clientObjectHandlerString;
1143:            }
1144:
1145:            /**
1146:             * Sets the console log handler formatter.
1147:             * @param formatter fully qualified name of the class that implements 
1148:             * {@link java.util.logging.Formatter}
1149:             * @since 1.2
1150:             */
1151:            public void setConsoleLoggingFormatter(String formatter)
1152:                    throws ClassNotFoundException, InstantiationException,
1153:                    IllegalAccessException {
1154:                if (formatter == null)
1155:                    return;
1156:                consoleLoggingformatter = formatter;
1157:
1158:                Formatter conformatter = (Formatter) getClass(formatter, true)
1159:                        .newInstance();
1160:                Logger jdkLogger = Logger.getLogger("");
1161:                Handler[] handlers = jdkLogger.getHandlers();
1162:                for (int index = 0; index < handlers.length; index++) {
1163:                    if (ConsoleHandler.class.isInstance(handlers[index])) {
1164:                        handlers[index].setFormatter(conformatter);
1165:                    }
1166:                }
1167:                logger.finest("Set to " + formatter);
1168:            }
1169:
1170:            /**
1171:             * Gets the console log handler formatter.
1172:             * @since 1.3
1173:             */
1174:            public String getConsoleLoggingFormatter() {
1175:                return consoleLoggingformatter;
1176:            }
1177:
1178:            /**
1179:             * Sets the console log handler formater to 
1180:             * {@link org.quickserver.util.logging.MiniFormatter}
1181:             * @since 1.2
1182:             */
1183:            public void setConsoleLoggingToMini() {
1184:                try {
1185:                    setConsoleLoggingFormatter("org.quickserver.util.logging.MiniFormatter");
1186:                } catch (Exception e) {
1187:                    logger.warning("Setting to logging.MiniFormatter : " + e);
1188:                }
1189:            }
1190:
1191:            /**
1192:             * Sets the console log handler formater to 
1193:             * {@link org.quickserver.util.logging.MicroFormatter}
1194:             * @since 1.2
1195:             */
1196:            public void setConsoleLoggingToMicro() {
1197:                try {
1198:                    setConsoleLoggingFormatter("org.quickserver.util.logging.MicroFormatter");
1199:                } catch (Exception e) {
1200:                    logger.warning("Setting to MicroFormatter : " + e);
1201:                }
1202:            }
1203:
1204:            /**
1205:             * Sets the console log handler level.
1206:             * @since 1.2
1207:             */
1208:            public void setConsoleLoggingLevel(Level level) {
1209:                Logger rlogger = Logger.getLogger("");
1210:                Handler[] handlers = rlogger.getHandlers();
1211:                for (int index = 0; index < handlers.length; index++) {
1212:                    if (ConsoleHandler.class.isInstance(handlers[index])) {
1213:                        handlers[index].setLevel(level);
1214:                    }
1215:                }
1216:                if (level == Level.SEVERE)
1217:                    consoleLoggingLevel = "SEVERE";
1218:                else if (level == Level.WARNING)
1219:                    consoleLoggingLevel = "WARNING";
1220:                else if (level == Level.INFO)
1221:                    consoleLoggingLevel = "INFO";
1222:                else if (level == Level.CONFIG)
1223:                    consoleLoggingLevel = "CONFIG";
1224:                else if (level == Level.FINE)
1225:                    consoleLoggingLevel = "FINE";
1226:                else if (level == Level.FINER)
1227:                    consoleLoggingLevel = "FINER";
1228:                else if (level == Level.FINEST)
1229:                    consoleLoggingLevel = "FINEST";
1230:                else
1231:                    consoleLoggingLevel = "UNKNOWN";
1232:
1233:                logger.fine("Set to " + level);
1234:            }
1235:
1236:            /**
1237:             * Gets the console log handler level.
1238:             * @since 1.3
1239:             */
1240:            public String getConsoleLoggingLevel() {
1241:                return consoleLoggingLevel;
1242:            }
1243:
1244:            /**
1245:             * Sets the level for all log handlers.
1246:             * @since 1.3.1
1247:             */
1248:            public void setLoggingLevel(Level level) {
1249:                Logger rlogger = Logger.getLogger("");
1250:                Handler[] handlers = rlogger.getHandlers();
1251:                for (int index = 0; index < handlers.length; index++) {
1252:                    handlers[index].setLevel(level);
1253:                }
1254:
1255:                if (level == Level.SEVERE)
1256:                    loggingLevel = "SEVERE";
1257:                else if (level == Level.WARNING)
1258:                    loggingLevel = "WARNING";
1259:                else if (level == Level.INFO)
1260:                    loggingLevel = "INFO";
1261:                else if (level == Level.CONFIG)
1262:                    loggingLevel = "CONFIG";
1263:                else if (level == Level.FINE)
1264:                    loggingLevel = "FINE";
1265:                else if (level == Level.FINER)
1266:                    loggingLevel = "FINER";
1267:                else if (level == Level.FINEST)
1268:                    loggingLevel = "FINEST";
1269:                else
1270:                    loggingLevel = "UNKNOWN";
1271:
1272:                consoleLoggingLevel = loggingLevel;
1273:
1274:                logger.fine("Set to " + level);
1275:            }
1276:
1277:            //*** Start of Service interface methods
1278:            /**
1279:             * Returns service error if any.
1280:             * @since 1.4.7
1281:             */
1282:            public Throwable getServiceError() {
1283:                return serviceError;
1284:            }
1285:
1286:            /**
1287:             * Initialise and create the service.
1288:             * @param param of the xml configuration file.
1289:             * @since 1.2
1290:             */
1291:            public synchronized boolean initService(Object param[]) {
1292:                serviceError = null;
1293:                try {
1294:                    initServer(param);
1295:                } catch (Exception e) {
1296:                    serviceError = e;
1297:                    return false;
1298:                }
1299:                return true;
1300:            }
1301:
1302:            /**
1303:             * Initialise and create the service.
1304:             * @param qsConfig QuickServerConfig object.
1305:             * @since 1.4.6
1306:             */
1307:            public synchronized boolean initService(QuickServerConfig qsConfig) {
1308:                serviceError = null;
1309:                try {
1310:                    initServer(qsConfig);
1311:                } catch (Exception e) {
1312:                    serviceError = e;
1313:                    return false;
1314:                }
1315:                return true;
1316:            }
1317:
1318:            /**
1319:             * Start the service.
1320:             * @return true if serivce was stopped from Running state.
1321:             * @since 1.2
1322:             */
1323:            public boolean startService() {
1324:                serviceError = null;
1325:                if (getServiceState() == Service.RUNNING)
1326:                    return false;
1327:                try {
1328:                    startServer();
1329:                } catch (AppException e) {
1330:                    serviceError = e;
1331:                    return false;
1332:                }
1333:                return true;
1334:            }
1335:
1336:            /**
1337:             * Stop the service.
1338:             * @return true if serivce was stopped from Running state.
1339:             * @since 1.2
1340:             */
1341:            public boolean stopService() {
1342:                serviceError = null;
1343:                if (getServiceState() == Service.STOPPED)
1344:                    return false;
1345:                try {
1346:                    stopServer();
1347:                    clearAllPools();
1348:                } catch (AppException e) {
1349:                    serviceError = e;
1350:                    return false;
1351:                } catch (Exception e) {
1352:                    serviceError = e;
1353:                    return false;
1354:                }
1355:                return true;
1356:            }
1357:
1358:            /**
1359:             * Suspends the service.
1360:             * @return true if service was suspended from resumed state.
1361:             * @since 1.2
1362:             */
1363:            public boolean suspendService() {
1364:                serviceError = null;
1365:                if (getServiceState() == Service.RUNNING) {
1366:                    suspendMaxConnection = maxConnection;
1367:                    suspendMaxConnectionMsg = maxConnectionMsg;
1368:                    maxConnection = 0;
1369:                    maxConnectionMsg = "Service is suspended.";
1370:                    setServiceState(Service.SUSPENDED);
1371:                    logger.info("Service " + getName() + " is suspended.");
1372:                    return true;
1373:                }
1374:                return false;
1375:            }
1376:
1377:            /**
1378:             * Resume the service.
1379:             * @return true if service was resumed from suspended state.
1380:             * @since 1.2
1381:             */
1382:            public boolean resumeService() {
1383:                serviceError = null;
1384:                if (getServiceState() == Service.SUSPENDED) {
1385:                    maxConnection = suspendMaxConnection;
1386:                    maxConnectionMsg = suspendMaxConnectionMsg;
1387:                    setServiceState(Service.RUNNING);
1388:                    logger.info("Service " + getName() + " resumed.");
1389:                    return true;
1390:                }
1391:                return false;
1392:            }
1393:
1394:            /** 
1395:             * Information about the service.
1396:             * @since 1.2
1397:             */
1398:            public String info() {
1399:                serviceError = null;
1400:                StringBuffer buf = new StringBuffer();
1401:                buf.append(getName() + "\n");
1402:                buf.append(getBindAddr().getHostAddress() + " " + getPort()
1403:                        + "\n");
1404:                return buf.toString();
1405:            }
1406:
1407:            // *** End of Service interface methods
1408:
1409:            /**
1410:             * Initialise and create the server.
1411:             * @param param of the xml configuration file.
1412:             * @exception AppException if QuickServerConfig creation failed from the xml config file.
1413:             * @since 1.4.7
1414:             */
1415:            public synchronized void initServer(Object param[])
1416:                    throws AppException {
1417:                QuickServerConfig qsConfig = null;
1418:                try {
1419:                    qsConfig = ConfigReader.read((String) param[0]);
1420:                } catch (Exception e) {
1421:                    logger.severe("Could not init server from xml file "
1422:                            + (new File((String) param[0]).getAbsolutePath())
1423:                            + " : " + e);
1424:                    throw new AppException(
1425:                            "Could not init server from xml file", e);
1426:                }
1427:                initServer(qsConfig);
1428:            }
1429:
1430:            /**
1431:             * Initialise and create the service.
1432:             * @param qsConfig QuickServerConfig object.
1433:             * @since 1.4.7
1434:             */
1435:            public synchronized void initServer(QuickServerConfig qsConfig)
1436:                    throws AppException {
1437:                setConfig(qsConfig);
1438:                try {
1439:                    configQuickServer();
1440:
1441:                    loadApplicationClasses();
1442:
1443:                    //start InitServerHooks
1444:                    InitServerHooks ish = getConfig().getInitServerHooks();
1445:                    if (ish != null) {
1446:                        Iterator iterator = ish.iterator();
1447:                        String initServerHookClassName = null;
1448:                        Class initServerHookClass = null;
1449:                        InitServerHook initServerHook = null;
1450:                        while (iterator.hasNext()) {
1451:                            initServerHookClassName = (String) iterator.next();
1452:                            initServerHookClass = getClass(
1453:                                    initServerHookClassName, true);
1454:                            initServerHook = (InitServerHook) initServerHookClass
1455:                                    .newInstance();
1456:
1457:                            logger.info("Loaded init server hook: "
1458:                                    + initServerHookClassName);
1459:                            logger.fine("Init server hook info: "
1460:                                    + initServerHook.info());
1461:                            initServerHook.handleInit(QuickServer.this );
1462:                        }
1463:                    }
1464:                } catch (Exception e) {
1465:                    logger.severe("Could not load init server hook: " + e);
1466:                    logger.warning("StackTrace:\n" + MyString.getStackTrace(e));
1467:                    throw new AppException("Could not load init server hook", e);
1468:                }
1469:                setServiceState(Service.INIT);
1470:                logger.finest("\r\n" + MyString.getSystemInfo(getVersion()));
1471:            }
1472:
1473:            /** 
1474:             * Returns the state of the process 
1475:             * As any constant of {@link Service} interface.
1476:             * @since 1.2
1477:             */
1478:            public int getServiceState() {
1479:                return serviceState;
1480:            }
1481:
1482:            /** 
1483:             * Sets the state of the process 
1484:             * As any constant of {@link Service} interface.
1485:             * @since 1.2
1486:             */
1487:            public void setServiceState(int state) {
1488:                serviceState = state;
1489:            }
1490:
1491:            private void configConsoleLoggingLevel(QuickServer qs, String temp) {
1492:                if (temp.equals("SEVERE"))
1493:                    qs.setConsoleLoggingLevel(Level.SEVERE);
1494:                else if (temp.equals("WARNING"))
1495:                    qs.setConsoleLoggingLevel(Level.WARNING);
1496:                else if (temp.equals("INFO"))
1497:                    qs.setConsoleLoggingLevel(Level.INFO);
1498:                else if (temp.equals("CONFIG"))
1499:                    qs.setConsoleLoggingLevel(Level.CONFIG);
1500:                else if (temp.equals("FINE"))
1501:                    qs.setConsoleLoggingLevel(Level.FINE);
1502:                else if (temp.equals("FINER"))
1503:                    qs.setConsoleLoggingLevel(Level.FINER);
1504:                else if (temp.equals("FINEST"))
1505:                    qs.setConsoleLoggingLevel(Level.FINEST);
1506:                else
1507:                    logger.warning("unknown level " + temp);
1508:            }
1509:
1510:            /**
1511:             * Configures QuickServer based on the passed QuickServerConfig object.
1512:             * @since 1.2
1513:             */
1514:            public void configQuickServer(QuickServerConfig config)
1515:                    throws Exception {
1516:                QuickServer qs = QuickServer.this ;
1517:                qs.setConfig(config); //v1.3
1518:                qs.setBasicConfig(config);
1519:                String temp = config.getConsoleLoggingLevel();
1520:                configConsoleLoggingLevel(qs, temp);
1521:                temp = null;
1522:
1523:                qs.setConsoleLoggingFormatter(config
1524:                        .getConsoleLoggingFormatter());
1525:
1526:                qs.setName(config.getName());
1527:                qs.setPort(config.getPort());
1528:                qs.setClientEventHandler(config.getClientEventHandler());
1529:                qs.setClientCommandHandler(config.getClientCommandHandler());
1530:                if (config.getAuthenticator() != null)
1531:                    qs.setAuthenticator(config.getAuthenticator()); //v1.3
1532:                else if (config.getClientAuthenticationHandler() != null)
1533:                    qs.setClientAuthenticationHandler(config
1534:                            .getClientAuthenticationHandler()); //v1.4.6
1535:                qs.setClientObjectHandler(config.getClientObjectHandler());
1536:                qs.setClientBinaryHandler(config.getClientBinaryHandler());//v1.4
1537:                qs.setClientWriteHandler(config.getClientWriteHandler());//v1.4.5
1538:                qs.setClientData(config.getClientData());
1539:                qs.setClientExtendedEventHandler(config
1540:                        .getClientExtendedEventHandler());
1541:                qs.setDefaultDataMode(config.getDefaultDataMode());//v1.4.6
1542:                qs.setServerBanner(config.getServerBanner());
1543:                qs.setTimeout(config.getTimeout());
1544:                qs.setMaxAuthTry(config.getMaxAuthTry());
1545:                qs.setMaxAuthTryMsg(config.getMaxAuthTryMsg());
1546:                qs.setTimeoutMsg(config.getTimeoutMsg());
1547:                qs.setMaxConnection(config.getMaxConnection());
1548:                qs.setMaxConnectionMsg(config.getMaxConnectionMsg());
1549:                qs.setBindAddr(config.getBindAddr());
1550:                //v1.3.2
1551:                qs.setCommunicationLogging(config.getCommunicationLogging());
1552:                //v1.3.3
1553:                qs.setSecurityManagerClass(config.getSecurityManagerClass());
1554:                qs
1555:                        .setAccessConstraintConfig(config
1556:                                .getAccessConstraintConfig());
1557:                temp = config.getApplicationJarPath();
1558:                if (temp != null) {
1559:                    File ajp = new File(temp);
1560:                    if (ajp.isAbsolute() == false) {
1561:                        temp = config.getConfigFile();
1562:                        ajp = new File(temp);
1563:                        temp = ajp.getParent() + File.separatorChar
1564:                                + config.getApplicationJarPath();
1565:                        config.setApplicationJarPath(temp);
1566:                        temp = null;
1567:                    }
1568:                    qs.setApplicationJarPath(config.getApplicationJarPath());
1569:                    //set path also to QSAdmin
1570:                    if (config.getQSAdminServerConfig() != null) {
1571:                        getQSAdminServer().getServer().setApplicationJarPath(
1572:                                config.getApplicationJarPath());
1573:                    }
1574:                }
1575:                qs.setServerHooks(config.getServerHooks());
1576:                qs.setSecure(config.getSecure());
1577:            }
1578:
1579:            /**
1580:             * Configures QSAdminServer based on the passed QuickServerConfig object.
1581:             * @since 1.2
1582:             */
1583:            public void configQuickServer(QSAdminServerConfig config)
1584:                    throws Exception {
1585:                QuickServer qs = getQSAdminServer().getServer();
1586:                qs.setBasicConfig(config);
1587:
1588:                //set the Logging Level to same as main QS
1589:                String temp = getConsoleLoggingLevel();//config.getConsoleLoggingLevel();
1590:                configConsoleLoggingLevel(qs, temp);
1591:
1592:                //set the Logging Formatter to same as main QS
1593:                //qs.setConsoleLoggingFormatter(config.getConsoleLoggingFormatter());
1594:                qs.setConsoleLoggingFormatter(getConsoleLoggingFormatter());
1595:
1596:                qs.setClientEventHandler(config.getClientEventHandler());//v1.4.6
1597:                qs.setClientCommandHandler(config.getClientCommandHandler());
1598:                qs.setName(config.getName());
1599:                qs.setPort(config.getPort());
1600:                if (config.getAuthenticator() != null)
1601:                    qs.setAuthenticator(config.getAuthenticator()); //v1.3
1602:                else if (config.getClientAuthenticationHandler() != null)
1603:                    qs.setClientAuthenticationHandler(config
1604:                            .getClientAuthenticationHandler()); //v1.4.6
1605:                qs.setClientObjectHandler(config.getClientObjectHandler());
1606:                qs.setClientBinaryHandler(config.getClientBinaryHandler());//v1.4
1607:                qs.setClientWriteHandler(config.getClientWriteHandler());//v1.4.5
1608:                qs.setClientData(config.getClientData());
1609:                qs.setClientExtendedEventHandler(config
1610:                        .getClientExtendedEventHandler());//v1.4.6
1611:                qs.setDefaultDataMode(config.getDefaultDataMode());//v1.4.6
1612:                qs.setServerBanner(config.getServerBanner());
1613:                qs.setTimeout(config.getTimeout());
1614:                qs.setMaxAuthTry(config.getMaxAuthTry());
1615:                qs.setMaxAuthTryMsg(config.getMaxAuthTryMsg());
1616:                qs.setTimeoutMsg(config.getTimeoutMsg());
1617:                qs.setMaxConnection(config.getMaxConnection());
1618:                qs.setMaxConnectionMsg(config.getMaxConnectionMsg());
1619:                qs.setBindAddr(config.getBindAddr());
1620:                //v1.3.2
1621:                qs.setCommunicationLogging(config.getCommunicationLogging());
1622:                getQSAdminServer().setCommandPlugin(config.getCommandPlugin());
1623:                //v1.3.2
1624:                if (config.getCommandShellEnable().equals("true"))
1625:                    getQSAdminServer().setShellEnable(true);
1626:                getQSAdminServer().setPromptName(
1627:                        config.getCommandShellPromptName());
1628:                //v1.3.3
1629:                qs
1630:                        .setAccessConstraintConfig(config
1631:                                .getAccessConstraintConfig());
1632:                qs.setServerHooks(config.getServerHooks());
1633:                qs.setSecure(config.getSecure());
1634:            }
1635:
1636:            /**
1637:             * Configures QSAdminServer and QuickServer based on the 
1638:             * internal QuickServerConfig object.
1639:             * @since 1.3
1640:             */
1641:            public void configQuickServer() throws Exception {
1642:                configQuickServer(getConfig());
1643:                if (getConfig().getQSAdminServerConfig() != null) {
1644:                    configQuickServer(getConfig().getQSAdminServerConfig());
1645:                }
1646:            }
1647:
1648:            /**
1649:             * Usage: QuickServer [-options]<br/>
1650:             * Where options include:<br/>
1651:             *   -about		Opens About Dialogbox<br/>
1652:             *   -load <xml_config_file> [options]	Loads the server from xml file.
1653:             * where options include:
1654:             *    -fullXML2File <new_file_name>
1655:             */
1656:            public static void main(String args[]) {
1657:                try {
1658:                    if (args.length >= 1) {
1659:                        if (args[0].equals("-about")) {
1660:                            org.quickserver.net.server.gui.About.main(null);
1661:                        } else if (args[0].equals("-load") && args.length >= 2) {
1662:                            QuickServer qs = QuickServer.load(args[1]);
1663:                            if (qs != null)
1664:                                handleOptions(args, qs);
1665:                        } else {
1666:                            System.out.println(printUsage());
1667:                        }
1668:                    } else {
1669:                        System.out.println(printUsage());
1670:                        org.quickserver.net.server.gui.About.showAbout();
1671:                    }
1672:                } catch (Exception e) {
1673:                    e.printStackTrace();
1674:                }
1675:            }
1676:
1677:            /**
1678:             * Loads the server from the xml file name passed.
1679:             * @since 1.4.7
1680:             */
1681:            public static QuickServer load(String xml) throws AppException {
1682:                QuickServer qs = new QuickServer();
1683:                Object config[] = new Object[] { xml };
1684:                qs.initServer(config);
1685:                qs.startServer();
1686:                if (qs.getConfig().getQSAdminServerConfig() != null) {
1687:                    qs.startQSAdminServer();
1688:                }
1689:                return qs;
1690:            }
1691:
1692:            /** Prints usage */
1693:            private static String printUsage() {
1694:                StringBuffer sb = new StringBuffer();
1695:                sb
1696:                        .append("QuickServer - Java library/framework for creating robust multi-client TCP servers.\n");
1697:                sb.append("Copyright (C) QuickServer.org\n\n");
1698:                sb.append("Usage: QuickServer [-options]\n");
1699:                sb.append("Where options include:\n");
1700:                sb.append("  -about\t" + "Opens About Dialog box\n");
1701:                sb.append("  -load <xml_config_file> [load-options]\t"
1702:                        + "Loads the server from xml file.\n");
1703:                sb.append("  Where load-options include:\n");
1704:                sb
1705:                        .append("     -fullXML2File <file_name>\t"
1706:                                + "Dumps the Full XML configuration of the QuickServer loaded.\n");
1707:                return sb.toString();
1708:            }
1709:
1710:            private static void handleOptions(String args[],
1711:                    QuickServer quickserver) {
1712:                if (args.length < 3)
1713:                    return;
1714:
1715:                if (args[2].equals("-fullXML2File") && args.length >= 4) {
1716:                    File file = new File(args[3]);
1717:                    logger.info("Writing full xml configuration to file: "
1718:                            + file.getAbsolutePath());
1719:                    try {
1720:                        TextFile.write(file, quickserver.getConfig()
1721:                                .toXML(null));
1722:                    } catch (Exception e) {
1723:                        logger.warning("Error writing full xml configuration: "
1724:                                + e);
1725:                    }
1726:                }
1727:            }
1728:
1729:            /**
1730:             * Cleans all Object and Thread pools
1731:             * @since 1.3
1732:             */
1733:            public void clearAllPools() throws Exception {
1734:                try {
1735:                    if (pool != null)
1736:                        getClientPool().clear();
1737:                    if (clientHandlerPool != null)
1738:                        getClientHandlerPool().clear();
1739:                    if (getClientDataPool() != null)
1740:                        getClientDataPool().clear();
1741:                    if (getDBPoolUtil() != null)
1742:                        getDBPoolUtil().clean();
1743:                    if (byteBufferPool != null)
1744:                        getByteBufferPool().clear();
1745:                } catch (Exception e) {
1746:                    logger.warning("Error: " + e);
1747:                    throw e;
1748:                }
1749:            }
1750:
1751:            /**
1752:             * Closes all Object and Thread pools
1753:             * @since 1.3
1754:             */
1755:            public void closeAllPools() throws Exception {
1756:                if (pool == null && clientHandlerPool == null
1757:                        && getClientDataPool() == null
1758:                        && getDBPoolUtil() == null && byteBufferPool == null) {
1759:                    return;
1760:                }
1761:                logger.fine("Closing pools for " + getName());
1762:                try {
1763:                    if (pool != null
1764:                            && PoolHelper.isPoolOpen(getClientPool()
1765:                                    .getObjectPool())) {
1766:                        logger.finer("Closing ClientThread pool.");
1767:                        getClientPool().close();
1768:                    }
1769:                    if (clientHandlerPool != null
1770:                            && PoolHelper.isPoolOpen(getClientHandlerPool())) {
1771:                        logger.finer("Closing ClientHandler pool.");
1772:                        getClientHandlerPool().close();
1773:                    }
1774:                    if (getClientDataPool() != null
1775:                            && PoolHelper.isPoolOpen(getClientDataPool())) {
1776:                        logger.finer("Closing ClientData pool.");
1777:                        getClientDataPool().close();
1778:                    }
1779:                    if (getDBPoolUtil() != null) {
1780:                        logger.finer("Closing DB pool.");
1781:                        getDBPoolUtil().clean();
1782:                    }
1783:                    if (byteBufferPool != null
1784:                            && PoolHelper.isPoolOpen(getByteBufferPool())) {
1785:                        logger.finer("Closing ByteBuffer pool.");
1786:                        getByteBufferPool().close();
1787:                    }
1788:                    logger.fine("Closed pools for " + getName());
1789:                } catch (Exception e) {
1790:                    logger.warning("Error closing pools for " + getName()
1791:                            + ": " + e);
1792:                    throw e;
1793:                }
1794:            }
1795:
1796:            /**
1797:             * Initialise all Object and Thread pools.
1798:             * @since 1.3
1799:             */
1800:            public void initAllPools() throws Exception {
1801:                logger.fine("Creating pools");
1802:                if (getBlockingMode() == false) {
1803:                    makeByteBufferPool(getBasicConfig().getObjectPoolConfig()
1804:                            .getByteBufferObjectPoolConfig());
1805:                }
1806:
1807:                makeClientPool(getBasicConfig().getObjectPoolConfig()
1808:                        .getThreadObjectPoolConfig());
1809:
1810:                makeClientHandlerPool(getBasicConfig().getObjectPoolConfig()
1811:                        .getClientHandlerObjectPoolConfig());
1812:
1813:                //check if client data is poolable
1814:                if (clientDataClass != null) {
1815:                    try {
1816:                        clientData = (ClientData) clientDataClass.newInstance();
1817:                        if (PoolableObject.class.isInstance(clientData) == true) {
1818:                            PoolableObject po = (PoolableObject) clientData;
1819:                            if (po.isPoolable() == true) {
1820:                                makeClientDataPool(
1821:                                        po.getPoolableObjectFactory(),
1822:                                        getBasicConfig()
1823:                                                .getObjectPoolConfig()
1824:                                                .getClientDataObjectPoolConfig());
1825:                            } else {
1826:                                clientDataPool = null;
1827:                                logger.fine("ClientData is not poolable!");
1828:                            }
1829:                        }
1830:                    } catch (Exception e) {
1831:                        logger.warning("Error: " + e);
1832:                        throw e;
1833:                    }
1834:                }
1835:
1836:                try {
1837:                    makeDBObjectPool();
1838:                } catch (Exception e) {
1839:                    logger.warning("Error in makeDBObjectPool() : " + e);
1840:                    logger.fine("StackTrace:\n" + MyString.getStackTrace(e));
1841:                    throw e;
1842:                }
1843:                logger.fine("Created pools");
1844:            }
1845:
1846:            /**
1847:             * Returns {@link org.quickserver.util.pool.thread.ClientPool} class that 
1848:             * managing the pool of threads for handling clients.
1849:             * @exception IllegalStateException if pool is not created yet.
1850:             * @since 1.3
1851:             */
1852:            public ClientPool getClientPool() {
1853:                if (pool == null)
1854:                    throw new IllegalStateException(
1855:                            "No ClientPool available yet!");
1856:                return pool;
1857:            }
1858:
1859:            /** 
1860:             * Makes the pool of ClientHandler
1861:             * @since 1.3
1862:             */
1863:            private void makeClientHandlerPool(PoolConfig opConfig)
1864:                    throws Exception {
1865:                logger.finer("Creating ClientHandler pool");
1866:                PoolableObjectFactory factory = new ClientHandlerObjectFactory(
1867:                        getBlockingMode());
1868:                clientHandlerPool = poolManager.makeClientHandlerPool(factory,
1869:                        opConfig);
1870:                poolManager.initPool(clientHandlerPool, opConfig);
1871:                clientHandlerPool = makeQSObjectPool(clientHandlerPool);
1872:                clientIdentifier
1873:                        .setClientHandlerPool((QSObjectPool) clientHandlerPool);
1874:            }
1875:
1876:            /**
1877:             * Returns ObjectPool of {@link org.quickserver.net.server.ClientHandler} 
1878:             * class.
1879:             * @exception IllegalStateException if pool is not created yet.
1880:             * @since 1.3
1881:             */
1882:            public ObjectPool getClientHandlerPool() {
1883:                if (clientHandlerPool == null)
1884:                    throw new IllegalStateException(
1885:                            "No ClientHandler Pool available yet!");
1886:                return clientHandlerPool;
1887:            }
1888:
1889:            /**
1890:             * Sets the confiuration of the QuickServer.
1891:             * @since 1.3
1892:             */
1893:            public void setConfig(QuickServerConfig config) {
1894:                this .config = config;
1895:            }
1896:
1897:            /**
1898:             * Returns the confiuration of the QuickServer.
1899:             * @since 1.3
1900:             */
1901:            public QuickServerConfig getConfig() {
1902:                return config;
1903:            }
1904:
1905:            /** 
1906:             * Makes the pool of ClientData
1907:             * @since 1.3
1908:             */
1909:            private void makeClientDataPool(PoolableObjectFactory factory,
1910:                    PoolConfig opConfig) throws Exception {
1911:                logger.finer("Creating ClientData pool");
1912:                clientDataPool = poolManager.makeClientDataPool(factory,
1913:                        opConfig);
1914:                poolManager.initPool(clientDataPool, opConfig);
1915:                clientDataPool = makeQSObjectPool(clientDataPool);
1916:            }
1917:
1918:            /**
1919:             * Returns ObjectPool of {@link org.quickserver.net.server.ClientData} 
1920:             * class. If ClientData was not poolable will return  null.
1921:             * @since 1.3
1922:             */
1923:            public ObjectPool getClientDataPool() {
1924:                return clientDataPool;
1925:            }
1926:
1927:            /**
1928:             * Returns {@link org.quickserver.sql.DBPoolUtil} object if
1929:             * {@link org.quickserver.util.xmlreader.DBObjectPoolConfig} was set.
1930:             * @return DBPoolUtil object if object could be loaded, else will return <code>null</code>
1931:             * @since 1.3
1932:             */
1933:            public DBPoolUtil getDBPoolUtil() {
1934:                return dBPoolUtil;
1935:            }
1936:
1937:            /**
1938:             * Sets {@link org.quickserver.util.xmlreader.DBObjectPoolConfig}
1939:             * @since 1.3
1940:             */
1941:            public void setDBObjectPoolConfig(
1942:                    DBObjectPoolConfig dBObjectPoolConfig) {
1943:                getConfig().setDBObjectPoolConfig(dBObjectPoolConfig);
1944:            }
1945:
1946:            /** 
1947:             * Makes the pool of Database Objects
1948:             * @since 1.3
1949:             */
1950:            private void makeDBObjectPool() throws Exception {
1951:                if (getConfig().getDBObjectPoolConfig() != null) {
1952:                    logger.fine("Creating DBObject Pool");
1953:                    //logger.finest("Got:\n"+getConfig().getDBObjectPoolConfig().toXML(null));
1954:                    Class dbPoolUtilClass = getClass(getConfig()
1955:                            .getDBObjectPoolConfig().getDbPoolUtil(), true);
1956:                    dBPoolUtil = (DBPoolUtil) dbPoolUtilClass.newInstance();
1957:                    dBPoolUtil.setDatabaseConnections(getConfig()
1958:                            .getDBObjectPoolConfig().getDatabaseConnectionSet()
1959:                            .iterator());
1960:                    dBPoolUtil.initPool();
1961:                }
1962:            }
1963:
1964:            /**
1965:             * Tries to find the Client by the Id passed.
1966:             * <p>
1967:             * Note: This command is an expensive so do use it limitedly and
1968:             * cache the returned object. But before you start sending message to the 
1969:             * cached object do validate that ClientHandler with you is currently 
1970:             * connected and is pointing to the same clinet has it was before.
1971:             * This can be done as follows. <pre>
1972:            foundClientHandler.isConnected(); //this method will through SocketException if not connected
1973:            Date newTime = foundClientHandler.getClientConnectedTime();
1974:            if(oldCachedTime!=newTime) {
1975:            	//Client had disconnected and ClientHandler was reused for
1976:            	//someother client, so write code to again find ur client
1977:            	foundClientHandler = handler.getServer().findFirstClientById("friendsid");
1978:            	...
1979:            }</pre>
1980:             * </p>
1981:             * @see ClientIdentifiable
1982:             * @return ClientHandler object if client was found else <code>null</code>
1983:             * @since 1.3.1
1984:             */
1985:            public ClientHandler findFirstClientById(String id) {
1986:                return clientIdentifier.findFirstClientById(id);
1987:            }
1988:
1989:            /**
1990:             * Returns an iterator containing all the 
1991:             * {@link org.quickserver.net.server.ClientHandler} that
1992:             * are currently handling clients. 
1993:             * It is recommended not to change the collection under an iterator. 
1994:             *
1995:             * It is imperative that the user manually synchronize on the returned collection 
1996:             * when iterating over it: 
1997:             * <code><pre>
1998:            Eg:
1999:
2000:            ClientData foundClientData = null;
2001:            Object syncObj = quickserver.getClientIdentifier().getObjectToSynchronize();
2002:            synchronized(syncObj) {	
2003:            	Iterator iterator = quickserver.findAllClient();
2004:            	while(iterator.hasNext()) {
2005:            		foundClientHandler = (ClientHandler) iterator.next();
2006:            		....
2007:            	}
2008:            }
2009:
2010:            //OR
2011:
2012:            ClientData foundClientData = null;
2013:            ClientIdentifier clientIdentifier = quickserver.getClientIdentifier();
2014:            synchronized(clientIdentifier.getObjectToSynchronize()) {	
2015:            	Iterator iterator = clientIdentifier.findAllClient();
2016:            	while(iterator.hasNext()) {
2017:            		foundClientHandler = (ClientHandler) iterator.next();
2018:            		....
2019:            	}
2020:            }
2021:            </code></pre>
2022:             * @since 1.3.1
2023:             */
2024:            public Iterator findAllClient() {
2025:                return clientIdentifier.findAllClient();
2026:            }
2027:
2028:            /**
2029:             * Tries to find the Client by the matching pattern passed to the Id.
2030:             * <p>
2031:             * Note: This command is an expensive so do use it limitedly and
2032:             * cache the returned object. But before you start sending message to the 
2033:             * cached object do validate that ClientHandler with you is currently 
2034:             * connected and is pointing to the same clinet has it was before.
2035:             * This can be done as follows. <pre>
2036:            foundClientHandler.isConnected(); //this method will through SocketException if not connected
2037:            Date newTime = foundClientHandler.getClientConnectedTime();
2038:            if(oldCachedTime!=newTime) {
2039:            	//Client had disconnected and ClientHandler was reused for
2040:            	//someother client, so write code to again find ur client
2041:            	foundClientHandler = handler.getServer().findFirstClientById("friendsid");
2042:            	...
2043:            }</pre>
2044:             * </p>
2045:             * @see ClientIdentifiable
2046:             * @return ClientHandler object if client was found else <code>null</code>
2047:             * @since 1.3.2
2048:             */
2049:            public Iterator findAllClientById(String pattern) {
2050:                return clientIdentifier.findAllClientById(pattern);
2051:            }
2052:
2053:            /**
2054:             * Tries to find the Client by the Key passed.
2055:             * <p>
2056:             * Note: This command is an expensive so do use it limitedly and
2057:             * cache the returned object. But before you start sending message to the 
2058:             * cached object do validate that ClientHandler with you is currently 
2059:             * connected and is pointing to the same clinet has it was before.
2060:             * This can be done as follows. <pre>
2061:            foundClientHandler.isConnected(); //this method will through SocketException if not connected
2062:            Date newTime = foundClientHandler.getClientConnectedTime();
2063:            if(oldCachedTime!=newTime) {
2064:            	//Client had disconnected and ClientHandler was reused for
2065:            	//someother client, so write code to again find ur client
2066:            	foundClientHandler = handler.getServer().findClientByKey("friendskey");
2067:            	...
2068:            }</pre>
2069:             * </p>
2070:             * @see ClientIdentifiable
2071:             * @return ClientHandler object if client was found else <code>null</code>
2072:             * @since 1.3.1
2073:             */
2074:            public ClientHandler findClientByKey(String key) {
2075:                return clientIdentifier.findClientByKey(key);
2076:            }
2077:
2078:            /**
2079:             * Tries to find the Client by the matching pattern passed to the key.
2080:             * <p>
2081:             * Note: This command is an expensive so do use it limitedly and
2082:             * cache the returned object. But before you start sending message to the 
2083:             * cached object do validate that ClientHandler with you is currently 
2084:             * connected and is pointing to the same clinet has it was before.
2085:             * This can be done as follows. <pre>
2086:            foundClientHandler.isConnected(); //this method will through SocketException if not connected
2087:            Date newTime = foundClientHandler.getClientConnectedTime();
2088:            if(oldCachedTime!=newTime) {
2089:            	//Client had disconnected and ClientHandler was reused for
2090:            	//some other client, so write code to again find ur client
2091:            	foundClientHandler = handler.getServer().findFirstClientByKey("friendsid");
2092:            	...
2093:            }</pre>
2094:             * </p>
2095:             * @see ClientIdentifiable
2096:             * @return ClientHandler object if client was found else <code>null</code>
2097:             * @since 1.4
2098:             */
2099:            public Iterator findAllClientByKey(String pattern) {
2100:                return clientIdentifier.findAllClientByKey(pattern);
2101:            }
2102:
2103:            /**
2104:             * Sets next client has a trusted client. 
2105:             * <p>This will skip any authentication and will not set any timout.</p>
2106:             * @since 1.3.2
2107:             */
2108:            public void nextClientIsTrusted() {
2109:                setSkipValidation(true);
2110:            }
2111:
2112:            /**
2113:             * @since 1.3.2
2114:             */
2115:            private boolean getSkipValidation() {
2116:                return skipValidation;
2117:            }
2118:
2119:            /**
2120:             * @since 1.3.2
2121:             */
2122:            private synchronized void setSkipValidation(boolean validation) {
2123:                skipValidation = validation;
2124:            }
2125:
2126:            /**
2127:             * Sets the communication logging flag.
2128:             * @see #getCommunicationLogging
2129:             * @since 1.3.2
2130:             */
2131:            public void setCommunicationLogging(boolean communicationLogging) {
2132:                this .communicationLogging = communicationLogging;
2133:            }
2134:
2135:            /**
2136:             * Returns the communication logging flag.
2137:             * @see #setCommunicationLogging
2138:             * @since 1.3.2
2139:             */
2140:            public boolean getCommunicationLogging() {
2141:                return communicationLogging;
2142:            }
2143:
2144:            /**
2145:             * Sets the SecurityManager class
2146:             * @param securityManagerClass the fully qualified name of the class 
2147:             * that extends {@link java.lang.SecurityManager}.
2148:             * @see #getSecurityManagerClass
2149:             * @since 1.3.3
2150:             */
2151:            public void setSecurityManagerClass(String securityManagerClass) {
2152:                if (securityManagerClass != null)
2153:                    this .securityManagerClass = securityManagerClass;
2154:            }
2155:
2156:            /**
2157:             * Returns the SecurityManager class
2158:             * @see #setSecurityManagerClass
2159:             * @since 1.3.3
2160:             */
2161:            public String getSecurityManagerClass() {
2162:                return securityManagerClass;
2163:            }
2164:
2165:            public SecurityManager getSecurityManager() throws AppException {
2166:                if (getSecurityManagerClass() == null)
2167:                    return null;
2168:                SecurityManager sm = null;
2169:                try {
2170:                    sm = (SecurityManager) getClass(getSecurityManagerClass(),
2171:                            true).newInstance();
2172:                } catch (ClassNotFoundException e) {
2173:                    throw new AppException(e.getMessage());
2174:                } catch (InstantiationException e) {
2175:                    throw new AppException(e.getMessage());
2176:                } catch (IllegalAccessException e) {
2177:                    throw new AppException(e.getMessage());
2178:                }
2179:                return sm;
2180:            }
2181:
2182:            /**
2183:             * Sets the Access constraints
2184:             * @since 1.3.3
2185:             */
2186:            public void setAccessConstraintConfig(
2187:                    AccessConstraintConfig accessConstraintConfig) {
2188:                this .accessConstraintConfig = accessConstraintConfig;
2189:            }
2190:
2191:            /**
2192:             * Returns Access constraints if present else <code>null</code>.
2193:             * @since 1.3.3
2194:             */
2195:            public AccessConstraintConfig getAccessConstraintConfig() {
2196:                return accessConstraintConfig;
2197:            }
2198:
2199:            /**
2200:             * Sets the classloader to be used to load the dynamicaly resolved 
2201:             * classes
2202:             * @since 1.3.3
2203:             */
2204:            public void setClassLoader(ClassLoader classLoader) {
2205:                this .classLoader = classLoader;
2206:                Thread.currentThread().setContextClassLoader(classLoader);
2207:            }
2208:
2209:            /**
2210:             * Gets the classloader used to load the dynamicaly resolved 
2211:             * classes.
2212:             * @since 1.4.6
2213:             */
2214:            public ClassLoader getClassLoader() {
2215:                return classLoader;
2216:            }
2217:
2218:            /**
2219:             * Utility method to load a class
2220:             * @since 1.3.3
2221:             */
2222:            public Class getClass(String name, boolean reload)
2223:                    throws ClassNotFoundException {
2224:                if (name == null)
2225:                    throw new IllegalArgumentException(
2226:                            "Class name can't be null!");
2227:                logger.finest("Class: " + name + ", reload: " + reload);
2228:                if (reload == true && classLoader != null) {
2229:                    return classLoader.loadClass(name);
2230:                } else if (reload == true && classLoader == null
2231:                        && this .getClass().getClassLoader() != null) {
2232:                    return this .getClass().getClassLoader().loadClass(name);
2233:                } else if (reload == false && classLoader != null) {
2234:                    return Class.forName(name, true, classLoader);
2235:                } else /*if(reload==false && classLoader==null)*/{
2236:                    return Class.forName(name, true, this .getClass()
2237:                            .getClassLoader());
2238:                }
2239:            }
2240:
2241:            /**
2242:             * Sets the applications jar/s path. This can be either absolute or
2243:             * relative(to config file) path to the jar file or the directory containing 
2244:             * the jars needed by the application.
2245:             * @see #getApplicationJarPath
2246:             * @since 1.3.3
2247:             */
2248:            protected void setApplicationJarPath(String applicationJarPath) {
2249:                this .applicationJarPath = applicationJarPath;
2250:            }
2251:
2252:            /**
2253:             * Returns the applications jar/s path. This can be either absolute or
2254:             * relative(to config file) path to the jar file or the directory containing the 
2255:             * jars needed by the application.
2256:             * @see #setApplicationJarPath
2257:             * @since 1.3.3
2258:             */
2259:            public String getApplicationJarPath() {
2260:                return applicationJarPath;
2261:            }
2262:
2263:            /**
2264:             * Sets the ServerHooks
2265:             * @since 1.3.3
2266:             */
2267:            public void setServerHooks(ServerHooks serverHooks) {
2268:                this .serverHooks = serverHooks;
2269:            }
2270:
2271:            /**
2272:             * Returns ServerHooks if present else <code>null</code>.
2273:             * @since 1.3.3
2274:             */
2275:            public ServerHooks getServerHooks() {
2276:                if (serverHooks == null)
2277:                    serverHooks = new ServerHooks();
2278:                return serverHooks;
2279:            }
2280:
2281:            /**
2282:             * @since 1.3.3
2283:             */
2284:            private void loadServerHooksClasses() {
2285:                if (getServerHooks() == null)
2286:                    return;
2287:                listOfServerHooks = new ArrayList();
2288:                ServerHook serverHook = null;
2289:                String serverHookClassName = null;
2290:                Class serverHookClass = null;
2291:
2292:                //add system hooks
2293:                serverHook = new GhostSocketReaper();
2294:                serverHook.initHook(QuickServer.this );
2295:                listOfServerHooks.add(serverHook);
2296:                ghostSocketReaper = (GhostSocketReaper) serverHook;
2297:
2298:                //add user hooks if any
2299:                Iterator iterator = getServerHooks().iterator();
2300:                while (iterator.hasNext()) {
2301:                    serverHookClassName = (String) iterator.next();
2302:                    try {
2303:                        serverHookClass = getClass(serverHookClassName, true);
2304:                        serverHook = (ServerHook) serverHookClass.newInstance();
2305:                        serverHook.initHook(QuickServer.this );
2306:                        listOfServerHooks.add(serverHook);
2307:                        logger.info("Loaded server hook: "
2308:                                + serverHookClassName);
2309:                        logger.fine("Server hook info: " + serverHook.info());
2310:                    } catch (Exception e) {
2311:                        logger.warning("Could not load server hook ["
2312:                                + serverHookClassName + "]: " + e);
2313:                        logger
2314:                                .fine("StackTrace:\n"
2315:                                        + MyString.getStackTrace(e));
2316:                    }
2317:                }//end of while
2318:            }
2319:
2320:            /**
2321:             * @since 1.3.3
2322:             */
2323:            private void processServerHooks(int event) {
2324:                if (listOfServerHooks == null) {
2325:                    logger.warning("listOfServerHooks was null!");
2326:                    return;
2327:                }
2328:                ServerHook serverHook = null;
2329:                boolean result = false;
2330:                Iterator iterator = listOfServerHooks.iterator();
2331:
2332:                String hooktype = "UNKNOWN";
2333:                switch (event) {
2334:                case ServerHook.PRE_STARTUP:
2335:                    hooktype = "PRE_STARTUP";
2336:                    break;
2337:                case ServerHook.POST_STARTUP:
2338:                    hooktype = "POST_STARTUP";
2339:                    break;
2340:                case ServerHook.PRE_SHUTDOWN:
2341:                    hooktype = "PRE_SHUTDOWN";
2342:                    break;
2343:                case ServerHook.POST_SHUTDOWN:
2344:                    hooktype = "POST_SHUTDOWN";
2345:                    break;
2346:                }
2347:
2348:                while (iterator.hasNext()) {
2349:                    serverHook = (ServerHook) iterator.next();
2350:                    try {
2351:                        result = serverHook.handleEvent(event);
2352:                    } catch (Exception e) {
2353:                        result = false;
2354:                        logger.warning("Error invoking " + hooktype + " hook ["
2355:                                + serverHook.getClass().getName() + "]: "
2356:                                + e.getMessage());
2357:                    }
2358:                    logger.fine("Invoked " + hooktype + " hook ["
2359:                            + serverHook.getClass().getName() + "] was: "
2360:                            + result);
2361:                }
2362:            }
2363:
2364:            /**
2365:             * Creates and returns a copy of this object.
2366:             * @since 1.3.3
2367:             */
2368:            public Object clone() {
2369:                Object object = null;
2370:                try {
2371:                    object = super .clone();
2372:                    QuickServer _qs = (QuickServer) object;
2373:                    _qs.setQSAdminServer(new QSAdminServer(_qs));
2374:                } catch (CloneNotSupportedException e) {
2375:                    logger.warning("Error cloning : " + e);//should not happ
2376:                }
2377:                return object;
2378:            }
2379:
2380:            /**
2381:             * Sets the Secure setting for QuickServer
2382:             * @since 1.4.0
2383:             */
2384:            public void setSecure(Secure secure) {
2385:                this .secure = secure;
2386:            }
2387:
2388:            /**
2389:             * Returns Secure setting for QuickServer
2390:             * @since 1.4.0
2391:             */
2392:            public Secure getSecure() {
2393:                if (secure == null)
2394:                    secure = new Secure();
2395:                return secure;
2396:            }
2397:
2398:            /**
2399:             * <p>Returns if the server is running in Secure mode [SSL or TLS].</p>
2400:             * @since 1.4.0
2401:             */
2402:            public boolean isRunningSecure() {
2403:                return runningSecure;
2404:            }
2405:
2406:            /**
2407:             * <p>Sets the server mode if its running in Secure mode [SSL or TLS].</p>
2408:             * @since 1.4.0
2409:             */
2410:            public void setRunningSecure(boolean runningSecure) {
2411:                this .runningSecure = runningSecure;
2412:            }
2413:
2414:            private File makeAbsoluteToConfig(String fileName) {
2415:                Assertion.affirm(fileName != null, "FileName can't be null");
2416:                return ConfigReader.makeAbsoluteToConfig(fileName, getConfig());
2417:            }
2418:
2419:            /**
2420:             * Returns a ServerSocket object to be used for listening.
2421:             * @since 1.4.0
2422:             */
2423:            protected void makeServerSocket() throws BindException, IOException {
2424:                server = null;
2425:                logger.finest("Binding " + getName() + " to IP: "
2426:                        + getBindAddr());
2427:                InetSocketAddress bindAddress = new InetSocketAddress(
2428:                        getBindAddr(), getPort());
2429:
2430:                try {
2431:                    NetworkInterface ni = NetworkInterface
2432:                            .getByInetAddress(getBindAddr());
2433:                    if (ni != null) {
2434:                        logger.fine("NetworkInterface: " + ni);
2435:                    }
2436:                } catch (Exception igrnore) {/*ignore*/
2437:                } catch (Error igrnore) {/*ignore*/
2438:                }
2439:
2440:                if (getSecure().isEnable() == false) {
2441:                    logger
2442:                            .fine("Making a normal ServerSocket for "
2443:                                    + getName());
2444:                    setRunningSecure(false);
2445:
2446:                    if (getBlockingMode() == false) {
2447:                        //for non-blocking
2448:                        serverSocketChannel = ServerSocketChannel.open();
2449:                        server = serverSocketChannel.socket();
2450:                        server.bind(bindAddress, getBasicConfig()
2451:                                .getAdvancedSettings().getBacklog());
2452:                    } else {
2453:                        //for blocking
2454:                        server = new ServerSocket(getPort(), getBasicConfig()
2455:                                .getAdvancedSettings().getBacklog(),
2456:                                getBindAddr());
2457:                    }
2458:                } else {
2459:                    logger
2460:                            .fine("Making a secure ServerSocket for "
2461:                                    + getName());
2462:                    try {
2463:                        ServerSocketFactory ssf = getSSLContext()
2464:                                .getServerSocketFactory();
2465:                        SSLServerSocket serversocket = (SSLServerSocket) ssf
2466:                                .createServerSocket(getPort(), getBasicConfig()
2467:                                        .getAdvancedSettings().getBacklog(),
2468:                                        getBindAddr());
2469:                        serversocket.setNeedClientAuth(secure
2470:                                .isClientAuthEnable());
2471:                        setRunningSecure(true);
2472:
2473:                        secureStoreManager.logSSLServerSocketInfo(serversocket);
2474:
2475:                        server = serversocket;
2476:                        serverSocketChannel = server.getChannel();
2477:                        if (serverSocketChannel == null
2478:                                && getBlockingMode() == false) {
2479:                            logger
2480:                                    .warning("Secure Server does not support Channel! So will run in blocking mode.");
2481:                            blockingMode = true;
2482:                        }
2483:                    } catch (NoSuchAlgorithmException e) {
2484:                        logger.warning("NoSuchAlgorithmException : " + e);
2485:                        throw new IOException("Error creating secure socket : "
2486:                                + e.getMessage());
2487:                    } catch (KeyManagementException e) {
2488:                        logger.warning("KeyManagementException : " + e);
2489:                        throw new IOException("Error creating secure socket : "
2490:                                + e.getMessage());
2491:                    }
2492:                }
2493:
2494:                server.setReuseAddress(true);
2495:
2496:                if (getBlockingMode() == false) {
2497:                    logger.fine("Server Mode " + getName() + " - Non Blocking");
2498:                    if (selector == null || selector.isOpen() == false) {
2499:                        logger.finest("Opening new selector");
2500:                        selector = Selector.open();
2501:                    } else {
2502:                        logger.finest("Reusing selector: " + selector);
2503:                    }
2504:                    serverSocketChannel.configureBlocking(false);
2505:                    serverSocketChannel.register(selector,
2506:                            SelectionKey.OP_ACCEPT);
2507:                    selector.wakeup();
2508:                } else {
2509:                    logger.fine("Server Mode " + getName() + " - Blocking");
2510:                }
2511:            }
2512:
2513:            /**
2514:             * Sets the basic confiuration of the QuickServer.
2515:             * @since 1.4.0
2516:             */
2517:            public void setBasicConfig(BasicServerConfig basicConfig)
2518:                    throws Exception {
2519:                Assertion.affirm(basicConfig != null,
2520:                        "BasicServerConfig can't be null");
2521:                this .basicConfig = basicConfig;
2522:            }
2523:
2524:            /**
2525:             * Returns the basic confiuration of the QuickServer.
2526:             * @since 1.4.0
2527:             */
2528:            public BasicServerConfig getBasicConfig() {
2529:                return basicConfig;
2530:            }
2531:
2532:            /**
2533:             * Loads the <code>SSLContext</code> from Secure configuring if set.
2534:             * @see #setSecure
2535:             * @since 1.4.0
2536:             */
2537:            public void loadSSLContext() throws IOException {
2538:                if (getSecure().isLoad() == false) {
2539:                    throw new IllegalStateException(
2540:                            "Secure setting is not yet enabled for loading!");
2541:                }
2542:                logger.info("Loading Secure Context..");
2543:                km = null;
2544:                tm = null;
2545:                try {
2546:                    String ssManager = "org.quickserver.security.SecureStoreManager";
2547:                    if (getSecure().getSecureStore() != null)
2548:                        ssManager = getSecure().getSecureStore()
2549:                                .getSecureStoreManager();
2550:
2551:                    Class secureStoreManagerClass = getClass(ssManager, true);
2552:
2553:                    secureStoreManager = (SecureStoreManager) secureStoreManagerClass
2554:                            .newInstance();
2555:
2556:                    km = secureStoreManager.loadKeyManagers(getConfig());
2557:                    logger.fine("KeyManager got");
2558:
2559:                    tm = secureStoreManager.loadTrustManagers(getConfig());
2560:                    logger.fine("TrustManager got");
2561:
2562:                    sslc = secureStoreManager.getSSLContext(getConfig()
2563:                            .getSecure().getProtocol());
2564:                    sslc.init(km, tm, null);
2565:                    logger.fine("SSLContext loaded");
2566:                } catch (KeyStoreException e) {
2567:                    logger.warning("KeyStoreException : " + e);
2568:                    throw new IOException("Error creating secure socket : "
2569:                            + e.getMessage());
2570:                } catch (NoSuchAlgorithmException e) {
2571:                    logger.warning("NoSuchAlgorithmException : " + e);
2572:                    throw new IOException("Error creating secure socket : "
2573:                            + e.getMessage());
2574:                } catch (NoSuchProviderException e) {
2575:                    logger.warning("NoSuchProviderException : " + e);
2576:                    throw new IOException("Error creating secure socket : "
2577:                            + e.getMessage());
2578:                } catch (UnrecoverableKeyException e) {
2579:                    logger.warning("UnrecoverableKeyException : " + e);
2580:                    throw new IOException("Error creating secure socket : "
2581:                            + e.getMessage());
2582:                } catch (CertificateException e) {
2583:                    logger.warning("CertificateException : " + e);
2584:                    throw new IOException("Error creating secure socket : "
2585:                            + e.getMessage());
2586:                } catch (KeyManagementException e) {
2587:                    logger.warning("KeyManagementException : " + e);
2588:                    throw new IOException("Error creating secure socket : "
2589:                            + e.getMessage());
2590:                } catch (GeneralSecurityException e) {
2591:                    logger.warning("GeneralSecurityException : " + e);
2592:                    throw new IOException("Error creating secure socket : "
2593:                            + e.getMessage());
2594:                } catch (ClassNotFoundException e) {
2595:                    logger.warning("ClassNotFoundException : " + e);
2596:                    throw new IOException("Error creating secure socket : "
2597:                            + e.getMessage());
2598:                } catch (InstantiationException e) {
2599:                    logger.warning("InstantiationException : " + e);
2600:                    throw new IOException("Error creating secure socket : "
2601:                            + e.getMessage());
2602:                } catch (IllegalAccessException e) {
2603:                    logger.warning("IllegalAccessException : " + e);
2604:                    throw new IOException("Error creating secure socket : "
2605:                            + e.getMessage());
2606:                }
2607:            }
2608:
2609:            /**
2610:             * Returns the <code>SSLContext</code> from Secure configuring.
2611:             * @see #loadSSLContext
2612:             * @since 1.4.0
2613:             */
2614:            public SSLContext getSSLContext() throws IOException,
2615:                    NoSuchAlgorithmException, KeyManagementException {
2616:                return getSSLContext(null);
2617:            }
2618:
2619:            /**
2620:             * Returns the <code>SSLContext</code> object that implements the specified 
2621:             * secure socket protocol from Secure configuring.
2622:             * @see #loadSSLContext
2623:             * @param protocol the standard name of the requested protocol. If <code>null</code> will use the protocol set in secure configuration of the server.
2624:             * @throws IOException
2625:             * @throws NoSuchAlgorithmException
2626:             * @throws KeyManagementException
2627:             * @since 1.4.0
2628:             */
2629:            public SSLContext getSSLContext(String protocol)
2630:                    throws IOException, NoSuchAlgorithmException,
2631:                    KeyManagementException {
2632:                if (sslc == null)
2633:                    loadSSLContext();
2634:                if (protocol != null && secureStoreManager != null) {
2635:                    SSLContext _sslc = secureStoreManager
2636:                            .getSSLContext(protocol);
2637:                    _sslc.init(km, tm, null);
2638:                    return _sslc;
2639:                }
2640:                return sslc;
2641:            }
2642:
2643:            /**
2644:             * Returns a SSLSocketFactory object to be used for creating SSLSockets. 
2645:             * Secure socket protocol will be picked from the Secure configuring.
2646:             * @see #setSecure
2647:             * @throws IOException
2648:             * @throws NoSuchAlgorithmException
2649:             * @throws KeyManagementException
2650:             * @since 1.4.0
2651:             */
2652:            public SSLSocketFactory getSSLSocketFactory() throws IOException,
2653:                    NoSuchAlgorithmException, KeyManagementException {
2654:                if (sslc == null)
2655:                    loadSSLContext();
2656:                return secureStoreManager.getSocketFactory(getSSLContext());
2657:            }
2658:
2659:            /**
2660:             * Returns a SSLSocketFactory object to be used for creating SSLSockets. 
2661:             * @see #setSecure
2662:             * @param protocol the standard name of the requested protocol. If 
2663:             * <code>null</code> will use the protocol set in secure configuration 
2664:             * of the server.
2665:             * @throws IOException
2666:             * @throws NoSuchAlgorithmException
2667:             * @throws KeyManagementException
2668:             * @since 1.4.0
2669:             */
2670:            public SSLSocketFactory getSSLSocketFactory(String protocol)
2671:                    throws IOException, NoSuchAlgorithmException,
2672:                    KeyManagementException {
2673:                if (sslc == null)
2674:                    loadSSLContext();
2675:                return secureStoreManager
2676:                        .getSocketFactory(getSSLContext(protocol));
2677:            }
2678:
2679:            /**
2680:             * Sets the ClientBinaryHandler class that interacts with 
2681:             * client sockets to handle binary data.
2682:             * @param handler object the fully qualified name of the class that 
2683:             *  implements {@link ClientBinaryHandler}
2684:             * @see #getClientBinaryHandler
2685:             * @since 1.4
2686:             */
2687:            public void setClientBinaryHandler(String handler) {
2688:                clientBinaryHandlerString = handler;
2689:                logger.finest("Set to " + handler);
2690:            }
2691:
2692:            /**
2693:             * Returns the ClientBinaryHandler class that interacts with 
2694:             * client sockets.
2695:             * @see #setClientBinaryHandler
2696:             * @since 1.4
2697:             */
2698:            public String getClientBinaryHandler() {
2699:                return clientBinaryHandlerString;
2700:            }
2701:
2702:            /**
2703:             * Sets the Selector (NIO).
2704:             * @since 1.4.5
2705:             */
2706:            public void setSelector(Selector selector) {
2707:                this .selector = selector;
2708:            }
2709:
2710:            /**
2711:             * Returns the Selector (NIO),if any.
2712:             * @since 1.4.5
2713:             */
2714:            public Selector getSelector() {
2715:                return selector;
2716:            }
2717:
2718:            /**
2719:             * Starts server in blocking mode.
2720:             * @since 1.4.5
2721:             */
2722:            private void runBlocking(TheClient theClient) throws Exception {
2723:                Socket client = null;
2724:                ClientHandler _chPolled = null;
2725:                int linger = getBasicConfig().getAdvancedSettings()
2726:                        .getSocketLinger();
2727:
2728:                //long stime = System.currentTimeMillis();
2729:                //long etime = System.currentTimeMillis();
2730:                while (true) {
2731:                    //etime = System.currentTimeMillis();
2732:                    //System.out.println("Time Taken: "+(etime-stime));
2733:                    client = server.accept();
2734:                    //stime = System.currentTimeMillis();
2735:
2736:                    if (linger < 0) {
2737:                        client.setSoLinger(false, 0);
2738:                    } else {
2739:                        client.setSoLinger(true, linger);
2740:                    }
2741:
2742:                    if (stopServer) {
2743:                        //Client connected when server was about to be shutdown.
2744:                        try {
2745:                            client.close();
2746:                        } catch (Exception e) {
2747:                        }
2748:                        break;
2749:                    }
2750:
2751:                    if (checkAccessConstraint(client) == false) {
2752:                        continue;
2753:                    }
2754:
2755:                    //Check if max connection has reached
2756:                    if (getSkipValidation() != true
2757:                            && maxConnection != -1
2758:                            && getClientHandlerPool().getNumActive() >= maxConnection) {
2759:                        theClient.setClientEvent(ClientEvent.MAX_CON_BLOCKING);
2760:                    } else {
2761:                        theClient.setClientEvent(ClientEvent.RUN_BLOCKING);
2762:                    }
2763:
2764:                    theClient.setTrusted(getSkipValidation());
2765:                    theClient.setSocket(client);
2766:                    theClient.setSocketChannel(client.getChannel()); //mostly null
2767:
2768:                    if (clientDataClass != null) {
2769:                        if (getClientDataPool() == null) {
2770:                            clientData = (ClientData) clientDataClass
2771:                                    .newInstance();
2772:                        } else {
2773:                            clientData = (ClientData) getClientDataPool()
2774:                                    .borrowObject();
2775:                        }
2776:                        theClient.setClientData(clientData);
2777:                    }
2778:
2779:                    try {
2780:                        _chPolled = (ClientHandler) getClientHandlerPool()
2781:                                .borrowObject();
2782:                        _chPolled.handleClient(theClient);
2783:                    } catch (java.util.NoSuchElementException nsee) {
2784:                        logger
2785:                                .warning("Could not borrow ClientHandler from pool. Error: "
2786:                                        + nsee);
2787:                        logger.warning("Closing Socket [" + client
2788:                                + "] since no ClientHandler available.");
2789:                        client.close();
2790:                    }
2791:
2792:                    if (_chPolled != null) {
2793:                        try {
2794:                            getClientPool().addClient(_chPolled, true);
2795:                        } catch (java.util.NoSuchElementException nsee) {
2796:                            logger
2797:                                    .warning("Could not borrow Thread from pool. Error: "
2798:                                            + nsee);
2799:                            //logger.warning("Closing Socket ["+client+"] since no Thread available.");
2800:                            //client.close();
2801:                            //returnClientHandlerToPool(_chPolled);
2802:                        }
2803:                        _chPolled = null;
2804:                    }
2805:                    client = null;
2806:
2807:                    //reset it back
2808:                    setSkipValidation(false);
2809:                }//end of loop
2810:            }
2811:
2812:            /**
2813:             * Starts server in non-blocking mode.
2814:             * @since 1.4.5
2815:             */
2816:            private void runNonBlocking(TheClient theClient) throws Exception {
2817:                int selectCount = 0;
2818:                Iterator iterator = null;
2819:                SelectionKey key = null;
2820:                ServerSocketChannel serverChannel = null;
2821:                SocketChannel socketChannel = null;
2822:                Socket client = null;
2823:                ClientHandler _chPolled = null;
2824:                boolean stopServerProcessed = false;
2825:                int linger = getBasicConfig().getAdvancedSettings()
2826:                        .getSocketLinger();
2827:                registerChannelRequestMap = new HashMap();
2828:
2829:                while (true) {
2830:                    selectCount = selector.select(500);
2831:                    //selectCount = selector.select();//for testing
2832:
2833:                    //check for any pending registerChannel req.
2834:                    synchronized (registerChannelRequestMap) {
2835:                        if (registerChannelRequestMap.size() > 0) {
2836:                            RegisterChannelRequest req = null;
2837:                            Object hashkey = null;
2838:                            iterator = registerChannelRequestMap.keySet()
2839:                                    .iterator();
2840:                            while (iterator.hasNext()) {
2841:                                hashkey = iterator.next();
2842:                                req = (RegisterChannelRequest) registerChannelRequestMap
2843:                                        .get(hashkey);
2844:                                req.register(getSelector());
2845:                            }
2846:                            iterator = null;
2847:                            registerChannelRequestMap.clear();
2848:                        }//if
2849:                    }//sync
2850:
2851:                    if (stopServer == true && stopServerProcessed == false) {
2852:                        logger.warning("Closing " + getName());
2853:                        serverSocketChannel.close();
2854:                        stopServerProcessed = true;
2855:
2856:                        server = null;
2857:                        serverSocketChannel = null;
2858:
2859:                        setServiceState(Service.STOPPED);
2860:                        logger.warning("Closed " + getName());
2861:
2862:                        processServerHooks(ServerHook.POST_SHUTDOWN);
2863:                    }
2864:
2865:                    if (stopServer == false && stopServerProcessed == true) {
2866:                        logger
2867:                                .finest("Server must have re-started.. will break");
2868:                        break;
2869:                    }
2870:
2871:                    if (selectCount == 0 && stopServerProcessed == true) {
2872:                        java.util.Set keyset = selector.keys();
2873:                        if (keyset.isEmpty() == true && getClientCount() <= 0) {
2874:                            break;
2875:                        } else {
2876:                            continue;
2877:                        }
2878:                    } else if (selectCount == 0) {
2879:                        continue;
2880:                    }
2881:
2882:                    iterator = selector.selectedKeys().iterator();
2883:                    while (iterator.hasNext()) {
2884:                        key = (SelectionKey) iterator.next();
2885:
2886:                        if (key.isValid() == false) {
2887:                            iterator.remove();
2888:                            continue;
2889:                        }
2890:
2891:                        if (key.isAcceptable() && stopServer == false) {
2892:                            logger.finest("Key is Acceptable");
2893:                            serverChannel = (ServerSocketChannel) key.channel();
2894:                            socketChannel = serverChannel.accept();
2895:
2896:                            if (socketChannel == null) {
2897:                                iterator.remove();
2898:                                continue;
2899:                            }
2900:
2901:                            client = socketChannel.socket();
2902:
2903:                            if (linger < 0) {
2904:                                client.setSoLinger(false, 0);
2905:                            } else {
2906:                                client.setSoLinger(true, linger);
2907:                            }
2908:
2909:                            if (checkAccessConstraint(client) == false) {
2910:                                iterator.remove();
2911:                                continue;
2912:                            }
2913:
2914:                            socketChannel.configureBlocking(false);
2915:                            theClient.setTrusted(getSkipValidation());
2916:                            theClient.setSocket(socketChannel.socket());
2917:                            theClient.setSocketChannel(socketChannel);
2918:
2919:                            if (clientDataClass != null) {
2920:                                if (getClientDataPool() == null) {
2921:                                    clientData = (ClientData) clientDataClass
2922:                                            .newInstance();
2923:                                } else {
2924:                                    //borrow a object from pool
2925:                                    clientData = (ClientData) getClientDataPool()
2926:                                            .borrowObject();
2927:                                }
2928:                                theClient.setClientData(clientData);
2929:                            }
2930:
2931:                            //Check if max connection has reached
2932:                            if (getSkipValidation() != true
2933:                                    && maxConnection != -1
2934:                                    && getClientHandlerPool().getNumActive() >= maxConnection) {
2935:                                theClient.setClientEvent(ClientEvent.MAX_CON);
2936:                            } else {
2937:                                theClient.setClientEvent(ClientEvent.ACCEPT);
2938:                            }
2939:
2940:                            try {
2941:                                _chPolled = (ClientHandler) getClientHandlerPool()
2942:                                        .borrowObject();
2943:                                logger.finest("Asking " + _chPolled.getName()
2944:                                        + " to handle.");
2945:                                _chPolled.handleClient(theClient);
2946:                            } catch (java.util.NoSuchElementException nsee) {
2947:                                logger
2948:                                        .warning("Could not borrow ClientHandler Object from pool. Error: "
2949:                                                + nsee);
2950:                                logger
2951:                                        .warning("Closing SocketChannel ["
2952:                                                + serverChannel.socket()
2953:                                                + "] since no ClientHandler available.");
2954:                                socketChannel.close();
2955:                            }
2956:
2957:                            if (_chPolled != null) {
2958:                                try {
2959:                                    getClientPool().addClient(_chPolled, true);
2960:                                } catch (java.util.NoSuchElementException nsee) {
2961:                                    logger
2962:                                            .warning("Could not borrow Thread from pool. Error: "
2963:                                                    + nsee);
2964:                                    //logger.warning("Closing SocketChannel ["+serverChannel.socket()+"] since no Thread available.");
2965:                                    //socketChannel.close();
2966:                                    //returnClientHandlerToPool(_chPolled);
2967:                                }
2968:                                _chPolled = null;
2969:                            }
2970:                            socketChannel = null;
2971:                            client = null;
2972:
2973:                            setSkipValidation(false);//reset it back
2974:                        } else if (key.isValid() && key.isReadable()) {
2975:                            boolean addedEvent = false;
2976:                            ClientHandler _ch = null;
2977:                            try {
2978:                                _ch = (ClientHandler) key.attachment();
2979:                                logger
2980:                                        .finest("Key is Readable, removing OP_READ from interestOps for "
2981:                                                + _ch.getName());
2982:                                key.interestOps(key.interestOps()
2983:                                        & (~SelectionKey.OP_READ));
2984:                                _ch.addEvent(ClientEvent.READ);
2985:                                addedEvent = true;
2986:                                //_ch.setSelectionKey(key);
2987:                                getClientPool().addClient(_ch);
2988:                            } catch (CancelledKeyException cke) {
2989:                                logger
2990:                                        .fine("Ignored Error - Key was Cancelled: "
2991:                                                + cke);
2992:                            } catch (java.util.NoSuchElementException nsee) {
2993:                                logger
2994:                                        .finest("NoSuchElementException: "
2995:                                                + nsee);
2996:                                if (addedEvent)
2997:                                    _ch.removeEvent(ClientEvent.READ);
2998:                                continue;//no need to remove the key
2999:                            }
3000:                            _ch = null;
3001:                        } else if (key.isValid() && key.isWritable()) {
3002:                            if (getClientPool().shouldNioWriteHappen() == false) {
3003:                                continue; //no need to remove the key
3004:                            }
3005:                            boolean addedEvent = false;
3006:                            ClientHandler _ch = null;
3007:                            try {
3008:                                _ch = (ClientHandler) key.attachment();
3009:                                logger
3010:                                        .finest("Key is Writable, removing OP_WRITE from interestOps for "
3011:                                                + _ch.getName());
3012:                                //remove OP_WRITE from interest set
3013:                                key.interestOps(key.interestOps()
3014:                                        & (~SelectionKey.OP_WRITE));
3015:                                _ch.addEvent(ClientEvent.WRITE);
3016:                                addedEvent = true;
3017:                                //_ch.setSelectionKey(key);
3018:                                getClientPool().addClient(_ch);
3019:                            } catch (CancelledKeyException cke) {
3020:                                logger
3021:                                        .fine("Ignored Error - Key was Cancelled: "
3022:                                                + cke);
3023:                            } catch (java.util.NoSuchElementException nsee) {
3024:                                logger
3025:                                        .finest("NoSuchElementException: "
3026:                                                + nsee);
3027:                                if (addedEvent)
3028:                                    _ch.removeEvent(ClientEvent.WRITE);
3029:                                continue;//no need to remove the key
3030:                            }
3031:                            _ch = null;
3032:                        } else if (stopServer == true && key.isAcceptable()) {
3033:                            //we will not accept this key
3034:                            setSkipValidation(false);//reset it back
3035:                        } else {
3036:                            logger.warning("Unknown key got in SelectionKey: "
3037:                                    + key);
3038:                        }
3039:                        iterator.remove(); //Remove key
3040:
3041:                        Thread.yield();
3042:                    } //end of iterator
3043:                    iterator = null;
3044:                }//end of loop
3045:            }
3046:
3047:            private boolean checkAccessConstraint(Socket socket) {
3048:                try {
3049:                    if (getAccessConstraintConfig() != null) {
3050:                        getAccessConstraintConfig().checkAccept(socket);
3051:                    }
3052:                    return true;
3053:                } catch (SecurityException se) {
3054:                    logger
3055:                            .warning("SecurityException occurred accepting connection : "
3056:                                    + se.getMessage());
3057:                    return false;
3058:                }
3059:            }
3060:
3061:            /**
3062:             * Register the given channel for the given operations. This adds the request
3063:             * to a list and will be processed after selector select wakes up.
3064:             * @return boolean flag to indicate if new entry was added to the list to register.
3065:             * @since 1.4.5
3066:             */
3067:            public boolean registerChannel(SocketChannel channel, int ops,
3068:                    Object att) throws IOException, ClosedChannelException {
3069:                if (getSelector() == null) {
3070:                    throw new IllegalStateException("Selector is not open!");
3071:                }
3072:                if (channel == null) {
3073:                    throw new IllegalArgumentException(
3074:                            "Can't register a null channel!");
3075:                }
3076:
3077:                if (channel.isConnected() == false) {
3078:                    throw new ClosedChannelException();
3079:                }
3080:
3081:                RegisterChannelRequest req = new RegisterChannelRequest(
3082:                        channel, ops, att);
3083:                RegisterChannelRequest reqOld = null;
3084:                synchronized (registerChannelRequestMap) {
3085:                    reqOld = (RegisterChannelRequest) registerChannelRequestMap
3086:                            .get(channel);
3087:                    if (reqOld == null) {
3088:                        registerChannelRequestMap.put(channel, req);
3089:                        getSelector().wakeup();
3090:                        return true;
3091:                    } else {
3092:                        if (reqOld.equals(req) == false) {
3093:                            reqOld.setOps(reqOld.getOps() | req.getOps());
3094:                            reqOld.setAtt(req.getAtt());
3095:                            return true;
3096:                        }
3097:                        return false;
3098:                    }
3099:                }
3100:                /*
3101:                logger.warning("Before register...");
3102:                channel.register(getSelector(), ops, att);
3103:                logger.warning("Before wakeup and after register...");
3104:                getSelector().wakeup();
3105:                logger.warning("After wakeup...");
3106:                 */
3107:            }
3108:
3109:            /** 
3110:             * Makes the pool of ByteBuffer
3111:             * @since 1.4.5
3112:             */
3113:            private void makeByteBufferPool(PoolConfig opConfig) {
3114:                logger.finer("Creating ByteBufferPool pool");
3115:
3116:                int bufferSize = getBasicConfig().getAdvancedSettings()
3117:                        .getByteBufferSize();
3118:                boolean useDirectByteBuffer = getBasicConfig()
3119:                        .getAdvancedSettings().getUseDirectByteBuffer();
3120:                PoolableObjectFactory factory = new ByteBufferObjectFactory(
3121:                        bufferSize, useDirectByteBuffer);
3122:
3123:                byteBufferPool = poolManager.makeByteBufferPool(factory,
3124:                        opConfig);
3125:                poolManager.initPool(byteBufferPool, opConfig);
3126:            }
3127:
3128:            /**
3129:             * Returns ObjectPool of java.nio.ByteBuffer class. 
3130:             * @since 1.4.5
3131:             */
3132:            public ObjectPool getByteBufferPool() {
3133:                return byteBufferPool;
3134:            }
3135:
3136:            /** 
3137:             * Makes the pool of ByteBuffer
3138:             * @since 1.4.5
3139:             */
3140:            private void makeClientPool(PoolConfig opConfig) throws Exception {
3141:                logger.finer("Creating ClientThread pool");
3142:                ThreadObjectFactory factory = new ThreadObjectFactory();
3143:                ObjectPool objectPool = poolManager.makeClientPool(factory,
3144:                        opConfig);
3145:                pool = new ClientPool(makeQSObjectPool(objectPool), opConfig);
3146:                factory.setClientPool(pool);
3147:                pool.setMaxThreadsForNioWrite(getBasicConfig()
3148:                        .getAdvancedSettings().getMaxThreadsForNioWrite());
3149:                poolManager.initPool(objectPool, opConfig);
3150:            }
3151:
3152:            /**
3153:             * Sets the ClientWriteHandler class that interacts with 
3154:             * client sockets to handle data write (only used in non-blocking mode).
3155:             * @param handler object the fully qualified name of the class that 
3156:             *  implements {@link ClientWriteHandler}
3157:             * @see #getClientWriteHandler
3158:             * @since 1.4.5
3159:             */
3160:            public void setClientWriteHandler(String handler) {
3161:                clientWriteHandlerString = handler;
3162:                logger.finest("Set to " + handler);
3163:            }
3164:
3165:            /**
3166:             * Returns the ClientWriteHandler class that interacts with 
3167:             * client sockets (only used in non-blocking mode).
3168:             * @see #setClientWriteHandler
3169:             * @since 1.4.5
3170:             */
3171:            public String getClientWriteHandler() {
3172:                return clientWriteHandlerString;
3173:            }
3174:
3175:            /**
3176:             * Returns the date/time when the server was last started.
3177:             * @return last started time. Will be <code>null</code> if never started.
3178:             * @since 1.4.5
3179:             */
3180:            public java.util.Date getLastStartTime() {
3181:                return lastStartTime;
3182:            }
3183:
3184:            /**
3185:             * Sets the debug flag to ByteBufferOutputStream and
3186:             * ByteBufferInputStream class that are used in non-blcking mode
3187:             * @since 1.4.5
3188:             */
3189:            public static void setDebugNonBlockingMode(boolean flag) {
3190:                org.quickserver.util.io.ByteBufferOutputStream.setDebug(flag);
3191:                org.quickserver.util.io.ByteBufferInputStream.setDebug(flag);
3192:            }
3193:
3194:            /**
3195:             * Returns the implementation that is used to do Client Identification.
3196:             * @since 1.4.5
3197:             */
3198:            public ClientIdentifier getClientIdentifier() {
3199:                return clientIdentifier;
3200:            }
3201:
3202:            /**
3203:             * Makes QSObjectPool from ObjectPool
3204:             * @since 1.4.5
3205:             */
3206:            private QSObjectPool makeQSObjectPool(ObjectPool objectPool)
3207:                    throws Exception {
3208:                return (QSObjectPool) qsObjectPoolMaker
3209:                        .getQSObjectPool(objectPool);
3210:            }
3211:
3212:            /**
3213:             * Returns the current blocking mode of the server.
3214:             * @since 1.4.6
3215:             */
3216:            public boolean getBlockingMode() {
3217:                return blockingMode;
3218:            }
3219:
3220:            /**
3221:             * Loads all the Business Logic class
3222:             * @since 1.4.6
3223:             */
3224:            protected void loadBusinessLogic() throws Exception {
3225:                if (clientCommandHandlerString == null
3226:                        && clientEventHandlerString == null) {
3227:                    logger
3228:                            .severe("ClientCommandHandler AND ClientEventHandler was not set.");
3229:                    throw new AppException(
3230:                            "ClientCommandHandler AND ClientEventHandler was not set.");
3231:                }
3232:
3233:                clientCommandHandler = null;
3234:                if (clientCommandHandlerString != null) {
3235:                    logger.finest("Loading ClientCommandHandler class..");
3236:                    Class clientCommandHandlerClass = getClass(
3237:                            clientCommandHandlerString, true);
3238:                    clientCommandHandler = (ClientCommandHandler) clientCommandHandlerClass
3239:                            .newInstance();
3240:                }
3241:
3242:                boolean setClientCommandHandlerLookup = false;
3243:                clientEventHandler = null;
3244:                if (clientEventHandlerString == null) {
3245:                    clientEventHandlerString = "org.quickserver.net.server.impl.DefaultClientEventHandler";
3246:                    setClientCommandHandlerLookup = true;
3247:                }
3248:                logger.finest("Loading ClientEventHandler class..");
3249:                if (clientEventHandlerString.equals(clientCommandHandlerString)
3250:                        && ClientEventHandler.class
3251:                                .isInstance(clientCommandHandler)) {
3252:                    clientEventHandler = (ClientEventHandler) clientCommandHandler;
3253:                } else {
3254:                    clientEventHandler = (ClientEventHandler) getClass(
3255:                            clientEventHandlerString, true).newInstance();
3256:                    if (setClientCommandHandlerLookup) {
3257:                        ((DefaultClientEventHandler) clientEventHandler)
3258:                                .setClientCommandHandler(clientCommandHandler);
3259:                    }
3260:                }
3261:
3262:                clientExtendedEventHandler = null;
3263:                if (clientExtendedEventHandlerString != null) {
3264:                    logger.finest("Loading ClientExtendedEventHandler class..");
3265:                    if (clientExtendedEventHandlerString
3266:                            .equals(clientCommandHandlerString)
3267:                            && ClientExtendedEventHandler.class
3268:                                    .isInstance(clientCommandHandler)) {
3269:                        clientExtendedEventHandler = (ClientExtendedEventHandler) clientCommandHandler;
3270:                    } else if (clientExtendedEventHandlerString
3271:                            .equals(clientEventHandlerString)
3272:                            && ClientExtendedEventHandler.class
3273:                                    .isInstance(clientEventHandler)) {
3274:                        clientExtendedEventHandler = (ClientExtendedEventHandler) clientEventHandler;
3275:                    } else {
3276:                        Class clientExtendedEventHandlerClass = getClass(
3277:                                clientExtendedEventHandlerString, true);
3278:                        clientExtendedEventHandler = (ClientExtendedEventHandler) clientExtendedEventHandlerClass
3279:                                .newInstance();
3280:                    }
3281:                }
3282:
3283:                clientObjectHandler = null;
3284:                if (clientObjectHandlerString != null) {
3285:                    logger.finest("Loading ClientObjectHandler class..");
3286:                    if (clientObjectHandlerString
3287:                            .equals(clientCommandHandlerString)
3288:                            && ClientObjectHandler.class
3289:                                    .isInstance(clientCommandHandler)) {
3290:                        clientObjectHandler = (ClientObjectHandler) clientCommandHandler;
3291:                    } else if (clientObjectHandlerString
3292:                            .equals(clientEventHandlerString)
3293:                            && ClientObjectHandler.class
3294:                                    .isInstance(clientEventHandler)) {
3295:                        clientObjectHandler = (ClientObjectHandler) clientEventHandler;
3296:                    } else if (clientObjectHandlerString
3297:                            .equals(clientExtendedEventHandlerString)
3298:                            && ClientObjectHandler.class
3299:                                    .isInstance(clientExtendedEventHandler)) {
3300:                        clientObjectHandler = (ClientObjectHandler) clientExtendedEventHandler;
3301:                    } else {
3302:                        clientObjectHandler = (ClientObjectHandler) getClass(
3303:                                clientObjectHandlerString, true).newInstance();
3304:                    }
3305:                } //end of != null
3306:
3307:                clientBinaryHandler = null;
3308:                if (clientBinaryHandlerString != null) {
3309:                    logger.finest("Loading ClientBinaryHandler class..");
3310:                    if (clientBinaryHandlerString
3311:                            .equals(clientCommandHandlerString)
3312:                            && ClientBinaryHandler.class
3313:                                    .isInstance(clientCommandHandler)) {
3314:                        clientBinaryHandler = (ClientBinaryHandler) clientCommandHandler;
3315:                    } else if (clientBinaryHandlerString
3316:                            .equals(clientEventHandlerString)
3317:                            && ClientBinaryHandler.class
3318:                                    .isInstance(clientEventHandler)) {
3319:                        clientBinaryHandler = (ClientBinaryHandler) clientEventHandler;
3320:                    } else if (clientBinaryHandlerString
3321:                            .equals(clientExtendedEventHandlerString)
3322:                            && ClientBinaryHandler.class
3323:                                    .isInstance(clientExtendedEventHandler)) {
3324:                        clientBinaryHandler = (ClientBinaryHandler) clientExtendedEventHandler;
3325:                    } else if (clientBinaryHandlerString
3326:                            .equals(clientObjectHandlerString)
3327:                            && ClientBinaryHandler.class
3328:                                    .isInstance(clientObjectHandler)) {
3329:                        clientBinaryHandler = (ClientBinaryHandler) clientObjectHandler;
3330:                    } else {
3331:                        clientBinaryHandler = (ClientBinaryHandler) getClass(
3332:                                clientBinaryHandlerString, true).newInstance();
3333:                    }
3334:                } //end of != null
3335:
3336:                clientWriteHandler = null;
3337:                if (clientWriteHandlerString != null) {
3338:                    logger.finest("Loading ClientWriteHandler class..");
3339:                    if (clientWriteHandlerString
3340:                            .equals(clientCommandHandlerString)
3341:                            && ClientWriteHandler.class
3342:                                    .isInstance(clientCommandHandler)) {
3343:                        clientWriteHandler = (ClientWriteHandler) clientCommandHandler;
3344:                    } else if (clientWriteHandlerString
3345:                            .equals(clientEventHandlerString)
3346:                            && ClientWriteHandler.class
3347:                                    .isInstance(clientEventHandler)) {
3348:                        clientWriteHandler = (ClientWriteHandler) clientEventHandler;
3349:                    } else if (clientWriteHandlerString
3350:                            .equals(clientExtendedEventHandlerString)
3351:                            && ClientWriteHandler.class
3352:                                    .isInstance(clientExtendedEventHandler)) {
3353:                        clientWriteHandler = (ClientWriteHandler) clientExtendedEventHandler;
3354:                    } else if (clientWriteHandlerString
3355:                            .equals(clientObjectHandlerString)
3356:                            && ClientWriteHandler.class
3357:                                    .isInstance(clientObjectHandler)) {
3358:                        clientWriteHandler = (ClientWriteHandler) clientObjectHandler;
3359:                    } else if (clientWriteHandlerString
3360:                            .equals(clientBinaryHandlerString)
3361:                            && ClientWriteHandler.class
3362:                                    .isInstance(clientBinaryHandler)) {
3363:                        clientWriteHandler = (ClientWriteHandler) clientBinaryHandler;
3364:                    } else {
3365:                        clientWriteHandler = (ClientWriteHandler) getClass(
3366:                                clientWriteHandlerString, true).newInstance();
3367:                    }
3368:                } //end of != null
3369:
3370:                Class authenticatorClass = null;
3371:                if (clientAuthenticationHandlerString != null) {
3372:                    logger
3373:                            .finest("Loading ClientAuthenticationHandler class..");
3374:                    authenticatorClass = getClass(
3375:                            clientAuthenticationHandlerString, true);
3376:                }
3377:
3378:                if (authenticatorClass != null) {
3379:                    Object obj = authenticatorClass.newInstance();
3380:
3381:                    if (ClientAuthenticationHandler.class.isInstance(obj))
3382:                        clientAuthenticationHandler = (ClientAuthenticationHandler) obj;
3383:                    else
3384:                        authenticator = (Authenticator) obj;
3385:                }
3386:
3387:                clientDataClass = null;
3388:                if (clientDataString != null) {
3389:                    logger.finest("Loading ClientData class..");
3390:                    clientDataClass = getClass(clientDataString, true);
3391:                }
3392:
3393:                Assertion.affirm(clientEventHandler != null,
3394:                        "ClientEventHandler was not loaded!");
3395:            }
3396:
3397:            /**
3398:             * Sets the ClientEventHandler class that gets notified of 
3399:             * client events.
3400:             * @param handler the fully qualified name of the class that 
3401:             *  implements {@link ClientEventHandler}
3402:             * @see #getClientEventHandler
3403:             * @since 1.4.6
3404:             */
3405:            public void setClientEventHandler(String handler) {
3406:                clientEventHandlerString = handler;
3407:                logger.finest("Set to " + handler);
3408:            }
3409:
3410:            /**
3411:             * Returns the ClientEventHandler class that gets notified of 
3412:             * client events.
3413:             * @see #setClientEventHandler
3414:             * @since 1.4.6
3415:             */
3416:            public String getClientEventHandler() {
3417:                return clientEventHandlerString;
3418:            }
3419:
3420:            /**
3421:             * Sets the default {@link DataMode} for the ClientHandler
3422:             * @since 1.4.6
3423:             */
3424:            public void setDefaultDataMode(DataMode dataMode, DataType dataType)
3425:                    throws IOException {
3426:                if (dataType == DataType.IN)
3427:                    this .defaultDataModeIN = dataMode;
3428:                if (dataType == DataType.OUT)
3429:                    this .defaultDataModeOUT = dataMode;
3430:            }
3431:
3432:            /**
3433:             * Sets the default {@link DataMode} for the ClientHandler
3434:             * @since 1.4.6
3435:             */
3436:            public void setDefaultDataMode(DefaultDataMode defaultDataMode)
3437:                    throws IOException {
3438:                defaultDataModeIN = defaultDataMode.getDataMode(DataType.IN);
3439:                defaultDataModeOUT = defaultDataMode.getDataMode(DataType.OUT);
3440:                ;
3441:            }
3442:
3443:            /**
3444:             * Returns the default {@link DataMode} for the ClientHandler
3445:             * @since 1.4.6
3446:             */
3447:            public DataMode getDefaultDataMode(DataType dataType) {
3448:                if (dataType == DataType.IN)
3449:                    return defaultDataModeIN;
3450:                if (dataType == DataType.OUT)
3451:                    return defaultDataModeOUT;
3452:                else
3453:                    throw new IllegalArgumentException("Unknown DataType: "
3454:                            + dataType);
3455:            }
3456:
3457:            /**
3458:             * Sets the ClientExtendedEventHandler class that gets notified of 
3459:             * extended client events.
3460:             * @param handler the fully qualified name of the class that 
3461:             *  implements {@link ClientExtendedEventHandler}
3462:             * @see #getClientExtendedEventHandler
3463:             * @since 1.4.6
3464:             */
3465:            public void setClientExtendedEventHandler(String handler) {
3466:                clientExtendedEventHandlerString = handler;
3467:                logger.finest("Set to " + handler);
3468:            }
3469:
3470:            /**
3471:             * Returns the ClientExtendedEventHandler class that gets notified of 
3472:             * extended client events.
3473:             * @see #setClientExtendedEventHandler
3474:             * @since 1.4.6
3475:             */
3476:            public String getClientExtendedEventHandler() {
3477:                return clientExtendedEventHandlerString;
3478:            }
3479:
3480:            /**
3481:             * If Application Jar Path was set, load the jars
3482:             * @since 1.4.6
3483:             */
3484:            private void loadApplicationClasses() throws Exception {
3485:                if (getApplicationJarPath() != null && getClassLoader() == null) {
3486:                    setClassLoader(ClassUtil
3487:                            .getClassLoader(getApplicationJarPath()));
3488:                    //update qsadmin to use the same
3489:                    if (adminServer != null) {
3490:                        adminServer.getServer()
3491:                                .setClassLoader(getClassLoader());
3492:                    }
3493:                }
3494:            }
3495:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.