Source Code Cross Referenced for DataShareServer.java in  » Groupware » Data-share » org » datashare » 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 » Groupware » Data share » org.datashare 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ----- BEGIN LICENSE BLOCK -----
0002:         * Version: MPL 1.1
0003:         *
0004:         * The contents of this file are subject to the Mozilla Public License Version
0005:         * 1.1 (the "License"); you may not use this file except in compliance with
0006:         * the License. You may obtain a copy of the License at
0007:         * http://www.mozilla.org/MPL/
0008:         *
0009:         * Software distributed under the License is distributed on an "AS IS" basis,
0010:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0011:         * for the specific language governing rights and limitations under the
0012:         * License.
0013:         *
0014:         * The Original Code is the DataShare server.
0015:         *
0016:         * The Initial Developer of the Original Code is
0017:         * Ball Aerospace & Technologies Corp, Fairborn, Ohio
0018:         * Portions created by the Initial Developer are Copyright (C) 2001
0019:         * the Initial Developer. All Rights Reserved.
0020:         *
0021:         * Contributor(s): Charles Wood <cwood@ball.com>
0022:         *
0023:         * ----- END LICENSE BLOCK ----- */
0024:        /* RCS $Id: DataShareServer.java,v 1.12 2002/02/21 13:20:12 lizellaman Exp $
0025:         * $Log: DataShareServer.java,v $
0026:         * Revision 1.12  2002/02/21 13:20:12  lizellaman
0027:         * correct problem of not getting history finished object
0028:         *
0029:         * Revision 1.11  2002/02/20 14:15:11  lizellaman
0030:         * changes to improve history retrieval
0031:         *
0032:         * Revision 1.10  2002/02/11 20:02:10  lizellaman
0033:         * Correct problem with retreiving non-cached EJBs, and update version/date
0034:         *
0035:         * Revision 1.9  2002/02/06 18:57:11  lizellaman
0036:         * Added the database deletion of Sessions if they have no channels that were saving data.
0037:         *
0038:         * Revision 1.8  2002/02/04 19:34:57  lizellaman
0039:         * correct spelling of privilege
0040:         *
0041:         * Revision 1.7  2002/02/04 13:51:39  lizellaman
0042:         * Remove all references to past product names (or)
0043:         * Add PublicAPI for creating Rendezvous Sessions
0044:         *
0045:         * Revision 1.6  2002/01/29 20:50:17  lizellaman
0046:         * Added LoggingInterface, modified the PropertiesInterface implementation
0047:         *
0048:         * Revision 1.5  2002/01/22 15:05:53  lizellaman
0049:         * make admin attribute for clients default to false (was true)
0050:         *
0051:         * Revision 1.4  2002/01/20 23:26:29  lizellaman
0052:         * add command line parameter that causes an plain DataShareObject to be sent to 'inactive' TCP connections after X milliseconds on inactivity
0053:         *
0054:         * Revision 1.3  2002/01/03 03:37:36  lizellaman
0055:         * periodic update of changes I have made
0056:         *
0057:         * Revision 1.2  2001/10/31 16:12:15  lizellaman
0058:         * changed to look for functions-file as file and as resource before giving up
0059:         *
0060:         * Revision 1.1.1.1  2001/10/23 13:37:18  lizellaman
0061:         * initial sourceforge release
0062:         *
0063:         */
0064:
0065:        package org.datashare;
0066:
0067:        import java.net.SocketPermission;
0068:        import java.net.InetAddress;
0069:        import java.io.ObjectOutputStream;
0070:        import java.io.ByteArrayOutputStream;
0071:        import java.io.BufferedOutputStream;
0072:        import java.io.BufferedReader;
0073:        import java.io.FileReader;
0074:        import java.io.IOException;
0075:        import java.io.FileNotFoundException;
0076:        import java.util.StringTokenizer;
0077:        import java.util.Vector;
0078:        import java.util.List;
0079:        import java.util.LinkedList;
0080:        import java.util.Collections;
0081:        import java.util.Enumeration;
0082:        import java.util.Hashtable;
0083:        import java.util.Properties;
0084:        import java.util.GregorianCalendar;
0085:        import java.util.Date;
0086:        import java.lang.reflect.Method;
0087:        import java.lang.reflect.Field;
0088:        import javax.swing.tree.DefaultMutableTreeNode;
0089:
0090:        import org.datashare.objects.ChannelDescription;
0091:        import org.datashare.objects.ChannelDescriptionArray;
0092:        import org.datashare.objects.RegistrationInfo;
0093:        import org.datashare.objects.ServerInfo;
0094:        import org.datashare.objects.DataShareConnectionDescriptor;
0095:        import org.datashare.objects.DataShareObject;
0096:        import org.datashare.objects.ClientSessionInfo;
0097:        import org.datashare.objects.ActivateConnectionObject;
0098:        import org.datashare.objects.CreateSessionRequest;
0099:        import org.datashare.objects.RegisterTreeListener;
0100:        import org.datashare.objects.RequestTree;
0101:        import org.datashare.objects.TreeObject;
0102:        import org.datashare.objects.JoinSession;
0103:        import org.datashare.objects.DeleteSession;
0104:        import org.datashare.objects.DisconnectConsumer;
0105:        import org.datashare.objects.InstantMsgData;
0106:        import org.datashare.objects.RequestHistory;
0107:        import org.datashare.objects.RequestFunctionInfo;
0108:        import org.datashare.objects.HistoryCountObject;
0109:        import org.datashare.objects.TokenRequestObject;
0110:        import org.datashare.objects.ControlServerObject;
0111:        import org.datashare.objects.RequestSessionNames;
0112:        import org.datashare.objects.SessionNames;
0113:        import org.datashare.objects.RequestFunctionsInSession;
0114:        import org.datashare.objects.FunctionsInSession;
0115:        import org.datashare.objects.ServerStatusObject;
0116:        import org.datashare.plugins.LoggingManager.LoggingAdapter;
0117:        import org.datashare.plugins.PropertiesManager.PropertiesManagerAdapter;
0118:
0119:        /**
0120:         * For now, a limitation of this design is that it uses a separate port for each Session and Channel.
0121:         * This will be changed in the future so that better 'in band' information will let a single server port
0122:         * serve more that one purpose.  Trying to keep it simple for now.
0123:         * @date March 01, 2001
0124:         * @author Charles Wood
0125:         * @version 1.0
0126:         */
0127:        public class DataShareServer implements  DataReceiverInterface,
0128:                TreeViewServerInterface, FifoConsumer {
0129:            // these are set to indicate the availability of the pluggable interfaces we can use
0130:            static boolean persistenceAdapterFound = false; // true if we have an implemention for the PersistenceInterface
0131:            //static boolean loggingAdapterFound=false; // not needed, we always have a LoggingInterface
0132:            static boolean logInAdapterFound = false; // true if we have an implementation for the LogInInterface
0133:            static boolean serviceAdapterFound = false; // true if we have an implementation for the ServiceInterface
0134:            //static boolean propertiesManagerAdapterFound=false; // true if we have an implementation for the PropertiesMangerInterface
0135:
0136:            static String persistenceInterfaceClassName; // loaded from properties
0137:            static String propertiesInterfaceClassName; // loaded from properties
0138:            static String logInInterfaceClassName; // loaded from properties
0139:            static String loggingInterfaceClassName; // loaded from properties
0140:            static String serviceInterfaceClassName; // loaded from properties
0141:
0142:            static PersistenceInterface persistenceInterface = null; // will be set to the class that implements the persistenceInterface
0143:            static PropertiesInterface propertiesInterface = null; // optional pluggable properties manager, run after generic one
0144:            static ServiceInterface serviceInterface = null;
0145:            static LoggingInterface loggingInterface = new LoggingAdapter();
0146:            static LogInInterface logInInterface = null;
0147:
0148:            static String propertiesFile; // loaded from properties
0149:
0150:            /**
0151:             * this is where we will store our configurable data, can be overwritten by
0152:             * Java defines.  May also be overwritten by command line options.  Normal
0153:             * SystemProperties may be added into this if a propertiesManager is loaded.
0154:             */
0155:            static Hashtable properties = new Hashtable();
0156:
0157:            /**
0158:             * true if we will be using a database to save info about DataShare objects.  Must be false
0159:             * if useDatabase is false.  Note that individual channels have their own control over saving data.
0160:             * This value is set at startup and must not change.  Cannot be true if useDatabase is false.  If useDatabase
0161:             * is true and this is false, then information about Clients and Sessions (and their associated info) will
0162:             * not be saved.  This can be initialized as a command line parameter.
0163:             */
0164:            static protected boolean persistData;
0165:
0166:            /**
0167:             * true if we have access to a database.  The database by default is used for client accounts, saving info
0168:             * about active Clients and Sessions, etc.  This can be initialized as a command line parameter.
0169:             */
0170:            static private boolean useDatabase /*inAContainer*/;
0171:
0172:            /**
0173:             * true if we have access to a database and should try to authenticate clients.  Must be false
0174:             * if useDatabase is false.  This can be initialized as a command line parameter.
0175:             */
0176:            static private boolean authenticatingClients = true; // set to true if we should try to find userproxy (this feature is untested)
0177:
0178:            static TcpSocketServer commandStatusServerThread = null;
0179:
0180:            // command line parameters...
0181:            static private int firstPort;
0182:            static private int lastPort;
0183:            static private boolean debug = true; // this value will be used until we read in a new value from commandLine/file
0184:            static private int commandStatusPort;
0185:            static boolean showArchivedSessionsToAdmin; // if true, admin clients will see closed sessions, must be false if useDatabase is false
0186:            static String channelTypesFile; // set to file on server that contains information about functions
0187:            static String multiCastIPaddress; // set to a valid IP Multicast address
0188:            static int TCPSocketReadTimeout; // used to set timeouts on TCP reads
0189:            static int currentPort;
0190:
0191:            /**
0192:             * This hashtable is used to keep up with who is connected to the commandStatus
0193:             * Connection.  It stores SocketAdapters, one for each client who is connected
0194:             * on the commandStatus Connection, keyed by the clientKeyValue.  Entries are
0195:             * removed when we lose the commandStatus connection to a client (see connectionLost() );
0196:             */
0197:            static private Hashtable commandStatusSocketHandlers = new Hashtable();
0198:
0199:            /**
0200:             * contains SessionInfo objects, keyed by the Session name (active sessions names are unique), one
0201:             * for every Session on the Server.
0202:             */
0203:            static private Hashtable sessionTable = new Hashtable();
0204:
0205:            /**
0206:             * contains all SpecialClients, keyed by client names (unique, converted to lowercase), one for every Client,
0207:             * used to check for unique names, must be in table to create/delete Sessions and show up as a Consumer,
0208:             */
0209:            static private Hashtable specialClientTable = new Hashtable();
0210:
0211:            /**
0212:             * This is a Hashtable of ThreadedSockets that have been opened on the server's
0213:             * CommandStatus connection.  These sockets have not been 'registered', i.e. the
0214:             * client has not yet sent its RegistrationInfo object to the server.  Once registered,
0215:             * these client entries will be removed from this table and put into the clients table.
0216:             * This table contains ThreadedSockets indexed by their keyValues.  Note that clients
0217:             * that will be viewing History Data will be in this table because their connections
0218:             * will not have been activated.
0219:             */
0220:            static private Hashtable connections = new Hashtable();
0221:
0222:            /**
0223:             * this will contain all the DataReceiverAdapters that have been created (one for each channel)
0224:             */
0225:            static private Vector allDataReceiverAdapters = new Vector();
0226:
0227:            /**
0228:             * this is a LIFO Queue that will be used to create our data from a seperate Thread.
0229:             * The PersistDataQueueObject is put in the Queue and fully describes the EJB to be created.
0230:             */
0231:            static private FifoQueue persistDataQueue = null;
0232:
0233:            static private final String serverStartTime = new GregorianCalendar()
0234:                    .getTime().toString();
0235:            static private String serverVersion = null;
0236:            static private String serverVersionHtml = null;
0237:            static private String myClientKeyValue = null;
0238:            static private InetAddress myIPAddress = null;
0239:            static private DataShareConnectionDescriptor commandStatusDescriptor = null;
0240:
0241:            /**
0242:             * This info is loaded from the configuration files and contains all we need to know
0243:             * about what type functions will be available for collaboration.
0244:             */
0245:            static private ChannelDescriptionArray channelDescriptionArray = null;
0246:
0247:            static TreeView treeView = null;
0248:
0249:            static private boolean alreadyShuttingDown = false; // so we don't call shutdown procedure more than once
0250:            static String serverInfoString = "";
0251:
0252:            /**
0253:             * Constructor, creates our DataShare server
0254:             */
0255:            public DataShareServer() // throws RemoteException
0256:            {
0257:                try {
0258:                    // SessionUtilities.setLoggingInterface(loggingInterface); // handled by SessionUtilities 'static'
0259:                    myIPAddress = InetAddress.getLocalHost();
0260:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
0261:                            loggingInterface.NETWORK, "My IP address is "
0262:                                    + myIPAddress.getHostAddress());
0263:                    SessionUtilities
0264:                            .setServername(myIPAddress.getHostAddress());
0265:                } catch (Exception e) {
0266:                    loggingInterface.debugMsg(loggingInterface.ERROR,
0267:                            loggingInterface.NETWORK,
0268:                            "Problems getting my IP address...");
0269:                    loggingInterface.logException(LoggingInterface.ERROR, e);
0270:                    this .shutDownConnectionsAndThreads();
0271:                }
0272:            }
0273:
0274:            public static void
0275:   main(String args[])
0276:      {
0277:      SessionUtilities.setVerbose(debug);
0278:      DataShareServer dataShareServer = new DataShareServer();
0279:      dataShareServer.initializeValues(args);  // will use PropertiesManager to set attribute values
0280:      SessionUtilities.setVerbose(debug);  // may have changed
0281:      dataShareServer.loadInterfaces();  // find the other interfaces and load if found
0282:
0283:      try{
0284:         if(serviceAdapterFound)
0285:            serviceInterface.initialize(dataShareServer);
0286:
0287:         if(useDatabase)
0288:            persistenceInterface.initialize();
0289:
0290:         // debug to print out the values of our properties
0291:         try{
0292:            for(Enumeration enum = properties.keys(); enum.hasMoreElements();)
0293:               {
0294:               String name = (String)enum.nextElement();
0295:               loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.GENERALSTATUS,
0296:                            "Name = " + name + ", Value = " + properties.get(name));
0297:               }
0298:            }
0299:         catch(Exception e)
0300:            {
0301:            loggingInterface.debugMsg(loggingInterface.WARNING,loggingInterface.GENERALSTATUS,
0302:                       "Problems getting Properties..." + e);
0303:            //e.printStackTrace();
0304:            }
0305:
0306:         dataShareServer.getChannelDescriptionsFromConfigFile();
0307:         dataShareServer.initialize();
0308:         }
0309:      catch(Exception e)
0310:         {
0311:         loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.GENERALSTATUS,
0312:            "Problems in DataShareServer.main()...");
0313:         loggingInterface.logException(LoggingInterface.ERROR, e); 
0314:         }
0315:      try{
0316:         // register the shutdown hook
0317:         final DataShareServer dss = dataShareServer;
0318:         Runtime.getRuntime().addShutdownHook(new Thread()
0319:            {
0320:            public void run()
0321:               {
0322:               System.out.println("shutdownHook()...");
0323:               dss.shutDownConnectionsAndThreads();
0324:               }
0325:            });
0326:         }
0327:      catch(Exception e){}
0328:      }
0329:
0330:            /**
0331:             * uses the *InterfaceClassName to try to load the classes and
0332:             * make them available for general use
0333:             */
0334:            private void loadInterfaces() {
0335:                // we will let InterfaceClassName values that are not set generate an exception
0336:                // and disable their interfaces that way (cleaner than putting in test for strings)
0337:
0338:                // logging interface (configuration may request we may replace the one we are using now)
0339:                try {
0340:                    if (loggingInterfaceClassName != null
0341:                            && !loggingInterfaceClassName.equals("")) {
0342:                        final ClassLoader cl = getClass().getClassLoader();
0343:                        LoggingInterface li = (LoggingInterface) cl.loadClass(
0344:                                loggingInterfaceClassName).newInstance();
0345:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0346:                                loggingInterface.GENERALSTATUS,
0347:                                "LoggingInterface class loaded-> " + li);
0348:                        loggingInterface
0349:                                .debugMsg(loggingInterface.DEBUG,
0350:                                        loggingInterface.GENERALSTATUS,
0351:                                        "Logging will now be handled by the new class...");
0352:                        loggingInterface = li; // don't replace ours until it is loaded
0353:                        SessionUtilities.setLoggingInterface(li);
0354:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0355:                                loggingInterface.GENERALSTATUS,
0356:                                "Start of new LoggingInterface class");
0357:                    }
0358:                } catch (Exception e) {
0359:                    loggingInterface.debugMsg(loggingInterface.WARNING,
0360:                            loggingInterface.GENERALSTATUS,
0361:                            "Problem when trying to load LoggingInterface class-> "
0362:                                    + loggingInterfaceClassName + "\n" + e);
0363:                }
0364:
0365:                // persistence interface
0366:                try {
0367:                    if (persistenceInterfaceClassName != null
0368:                            && !persistenceInterfaceClassName.equals("")) {
0369:                        final ClassLoader cl = getClass().getClassLoader();
0370:                        persistenceInterface = (PersistenceInterface) cl
0371:                                .loadClass(persistenceInterfaceClassName)
0372:                                .newInstance();
0373:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0374:                                loggingInterface.GENERALSTATUS,
0375:                                "PersistenceInterface class loaded-> "
0376:                                        + persistenceInterface);
0377:                        persistenceAdapterFound = true;
0378:                    }
0379:                } catch (Exception e) {
0380:                    loggingInterface.debugMsg(loggingInterface.WARNING,
0381:                            loggingInterface.GENERALSTATUS,
0382:                            "Problem when trying to load PersistenceInterface class-> "
0383:                                    + persistenceInterfaceClassName + "\n" + e);
0384:                    //e.printStackTrace();
0385:                    persistenceAdapterFound = false;
0386:                } finally {
0387:                    if (!persistenceAdapterFound) // otherwise, leave follow values as-is
0388:                    {
0389:                        useDatabase = false;
0390:                        persistData = false;
0391:                        authenticatingClients = false;
0392:                    }
0393:                }
0394:
0395:                // service interface
0396:                try {
0397:                    if (serviceInterfaceClassName != null
0398:                            && !serviceInterfaceClassName.equals("")) {
0399:                        final ClassLoader cl = getClass().getClassLoader();
0400:                        serviceInterface = (ServiceInterface) cl.loadClass(
0401:                                serviceInterfaceClassName).newInstance();
0402:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0403:                                loggingInterface.GENERALSTATUS,
0404:                                "ServiceInterface class loaded-> "
0405:                                        + serviceInterface);
0406:                        serviceAdapterFound = true;
0407:                    }
0408:                } catch (Exception e) {
0409:                    loggingInterface.debugMsg(loggingInterface.WARNING,
0410:                            loggingInterface.GENERALSTATUS,
0411:                            "Problem when trying to load ServiceInterface class-> "
0412:                                    + serviceInterfaceClassName + "\n" + e);
0413:                    //e.printStackTrace();
0414:                    serviceAdapterFound = false;
0415:                } finally {
0416:                    if (!serviceAdapterFound) // otherwise, leave follow values as-is
0417:                    {
0418:                        // not sure what to disable
0419:                    }
0420:                }
0421:
0422:                // log in interface
0423:                try {
0424:                    if (logInInterfaceClassName != null
0425:                            && !logInInterfaceClassName.equals("")) {
0426:                        final ClassLoader cl = getClass().getClassLoader();
0427:                        logInInterface = (LogInInterface) cl.loadClass(
0428:                                logInInterfaceClassName).newInstance();
0429:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0430:                                loggingInterface.GENERALSTATUS,
0431:                                "LogInInterface class loaded-> "
0432:                                        + logInInterface);
0433:                        logInAdapterFound = true;
0434:                    } else
0435:                        authenticatingClients = false;
0436:                } catch (Exception e) {
0437:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
0438:                            loggingInterface.GENERALSTATUS,
0439:                            "Problem when trying to load LogInInterface class-> "
0440:                                    + logInInterfaceClassName + "\n" + e);
0441:                    e.printStackTrace();
0442:                    logInAdapterFound = false;
0443:                    authenticatingClients = false;
0444:                }
0445:            }
0446:
0447:            /**
0448:             * give default values to properties
0449:             */
0450:            void initializeValues(String args[]) {
0451:                // order for properties is default, file, system, (ads), commandLine)
0452:                // Note that all these key values should have a attribute by the same name!!!!,
0453:                // i.e. there is an attribute named 'persistenceInterfaceClassName' (that may be overwritten by the properties manager)
0454:
0455:                // (note that ADS implementation will prepend "k2.datashare." to all these values in their configuration files)
0456:                // The first value is the attribute names that we want to be initialized!!!
0457:                // The second value is the type of the attribute (boolean, String, or int)
0458:                // The third value is the default, may be overidden by PropertiesManager
0459:                String propertiesStrings[][] = {
0460:                        { "persistenceInterfaceClassName", "String", "" },
0461:                        { "loggingInterfaceClassName", "String", "" }, // default value is in code, value here will override it
0462:                        { "logInInterfaceClassName", "String", "" },
0463:                        { "serviceInterfaceClassName", "String", "" },
0464:                        { "propertiesInterfaceClassName", "String", "" }, // default value is in code, value here will override it
0465:                        { "persistData", "boolean", "true" },
0466:                        { "useDatabase", "boolean", "true" },
0467:                        { "authenticatingClients", "boolean", "true" },
0468:                        { "firstPort", "int", "9000" },
0469:                        { "lastPort", "int", "10000" },
0470:                        { "debug", "boolean", "true" },
0471:                        { "commandStatusPort", "int", "42422" },
0472:                        { "multiCastIPaddress", "String", "228.6.6.6" },
0473:                        { "TCPSocketReadTimeout", "int", "0" }, // if non-zero, TCP sockets will timeout after this many milliseconds of inactivity and send KeepAlive packets
0474:                        { "showArchivedSessionsToAdmin", "boolean", "false" },
0475:                        {
0476:                                "serverVersion",
0477:                                "String",
0478:                                "DataShareServer\n"
0479:                                        + "February 21, 2002\n"
0480:                                        + "Version 1.09a\n"
0481:                                        + "Copyright Ball Aerospace & Technologies Corp, 2002 Fairborn, Ohio" }, // symbol causes CVS import problems!!!
0482:                        {
0483:                                "serverVersionHtml",
0484:                                "String",
0485:                                "DataShareServer<br>"
0486:                                        + "February 21, 2002<br>"
0487:                                        + "Version 1.09a<br>"
0488:                                        + "Copyright (c) Ball Aerospace & Technologies Corp, 2002<br>Fairborn, Ohio" }, // symbol causes CVS import problems!!!
0489:                        { "myClientKeyValue", "String", "DataShareServer" },
0490:                        { "propertiesFile", "String", "DataShare2.properties" }, // put additional properties here
0491:                        { "channelTypesFile", "String", "Rendezvous.cfg" } };
0492:
0493:                // put the default values into our table
0494:                for (int x = 0; x < propertiesStrings.length; x++)
0495:                    properties.put(propertiesStrings[x][0],
0496:                            propertiesStrings[x][2]);
0497:
0498:                // try to get a PropertiesManager loaded and run...
0499:
0500:                // properties manager is a unique problem because we want to be able to run different adapters,
0501:                // and it is the class that would tell us about a different adapter... So we run it the first
0502:                // time with the generic propertiesManagerAdapter, and if it returns with a non-default value for
0503:                // the propertiesAdapter value, we will run the new class.
0504:
0505:                // first we use the built in properties manager as our propertiesInterface
0506:                propertiesInterface = new PropertiesManagerAdapter();
0507:                propertiesInterface.setParameters(properties);
0508:                propertiesInterface.setCommandLineArgs(args);
0509:                properties = propertiesInterface.updateProperties();
0510:
0511:                // now see if the propertiesInterface is to be replaced...
0512:                String propertiesAdapterClassName = (String) properties
0513:                        .get("propertiesInterfaceClassName");
0514:                if (propertiesAdapterClassName != null
0515:                        && !propertiesAdapterClassName.equals("")) {
0516:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
0517:                            loggingInterface.GENERALSTATUS,
0518:                            "New PropertiesInterface class specified-> "
0519:                                    + propertiesAdapterClassName);
0520:                    try {
0521:                        final ClassLoader cl = getClass().getClassLoader();
0522:                        propertiesInterface = (PropertiesInterface) cl
0523:                                .loadClass(propertiesAdapterClassName)
0524:                                .newInstance();
0525:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0526:                                loggingInterface.GENERALSTATUS,
0527:                                "New PropertiesInterface class loaded-> "
0528:                                        + propertiesInterface);
0529:                        propertiesInterface.setParameters(properties);
0530:                        propertiesInterface.setCommandLineArgs(args);
0531:                        properties = propertiesInterface.updateProperties();
0532:                    } catch (Exception e) {
0533:                        loggingInterface.debugMsg(loggingInterface.WARNING,
0534:                                loggingInterface.GENERALSTATUS,
0535:                                "Problem when trying to load PropertiesInterface class ("
0536:                                        + propertiesAdapterClassName + ")->\n"
0537:                                        + e);
0538:                        //e.printStackTrace();
0539:                    }
0540:                }
0541:
0542:                // now we convert the (updated) properties values into attribute values...
0543:                // wanted to use Class.getClass().getDeclaredField(fieldName), but it doesn't support Strings!
0544:                for (int x = 0; x < propertiesStrings.length; x++) {
0545:                    String fieldName = propertiesStrings[x][0];
0546:                    String value = (String) properties.get(fieldName);
0547:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
0548:                            loggingInterface.GENERALSTATUS, "Field/Value-> "
0549:                                    + fieldName + "=" + value);
0550:                    try {
0551:                        Field field = this .getClass().getDeclaredField(
0552:                                fieldName);
0553:                        if (propertiesStrings[x][1].equals("int")) {
0554:                            int intValue = new Integer(value).intValue();
0555:                            field.setInt(this , intValue);
0556:                        } else if (propertiesStrings[x][1].equals("String")) {
0557:                            field.set(this , value);
0558:                        } else if (propertiesStrings[x][1].equals("boolean")) {
0559:                            // value must be "true" or "false" or value not used
0560:                            if (value.toLowerCase().equals("true"))
0561:                                field.setBoolean(this , true);
0562:                            else if (value.toLowerCase().equals("false"))
0563:                                field.setBoolean(this , false);
0564:                        }
0565:                    } catch (Exception e) {
0566:                        //e.printStackTrace();
0567:                    }
0568:                }
0569:                currentPort = firstPort; // this one value is based on another value (that may have just been changed)
0570:
0571:                // must be a better way to do this, need to get a parameter to SessionUtilities' static values
0572:                SessionUtilities.setTCPSocketReadTimeout(TCPSocketReadTimeout);
0573:            }
0574:
0575:            /**
0576:             * Creates the CommandStatus Channel for communicating with Clients
0577:             */
0578:            public void initialize() {
0579:                // create the descriptor for our CommandStatus Channel Connection
0580:                commandStatusDescriptor = new DataShareConnectionDescriptor("",
0581:                        new ChannelDescription("commandStatus", "",
0582:                                "used to communicate with server",
0583:                                ChannelDescription.TCP, "dummy.jar", false,
0584:                                false, false, 0, 0), myIPAddress,
0585:                        commandStatusPort);
0586:
0587:                try {
0588:                    if (!useDatabase) {
0589:                        // cannot persist data or authenticate clients without a database
0590:                        persistData = false;
0591:                        authenticatingClients = false; // we don't currently authenticate, but for later on...
0592:                        showArchivedSessionsToAdmin = false;
0593:                    }
0594:
0595:                    if (persistData) // already checked against useDatabase
0596:                    {
0597:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0598:                                loggingInterface.DATABASE,
0599:                                "We will be using a Database...");
0600:                        // create a Queue that will store then create our data for us
0601:                        persistDataQueue = new FifoQueue();
0602:                        persistDataQueue.setConsumer(this );
0603:                    } else {
0604:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0605:                                loggingInterface.DATABASE,
0606:                                "We will NOT be using a Database...");
0607:                    }
0608:
0609:                    // create the CommandStatus Channel socket listener thread
0610:                    commandStatusServerThread = new TcpSocketServer(
0611:                            (DataReceiverInterface) this , commandStatusPort,
0612:                            SessionUtilities.SocketRcvCmdPriority);
0613:                    treeView = new TreeView((TreeViewServerInterface) this );
0614:                    createSessions(treeView.oldSessionsTable);
0615:                    treeView = new TreeView((TreeViewServerInterface) this );
0616:                    // activate it so it will establish sockets for every connection
0617:                    commandStatusServerThread.start();
0618:                    serverInfoString = "<tr><td>Server version</td><td>"
0619:                            + serverVersionHtml + "</td></tr>"
0620:                            + "<tr><td>Server persistance</td><td>"
0621:                            + (persistData ? "Is " : "Is not ")
0622:                            + "saving data to a database" + "</td></tr>"
0623:                            + "<tr><td>Server up since</td><td>"
0624:                            + serverStartTime + "</td></tr>"
0625:                            + "<tr><td>Machine name</td><td> "
0626:                            + myIPAddress.getHostName() + "</td></tr>"
0627:                            + "<tr><td>Machine IP</td><td>"
0628:                            + myIPAddress.getHostAddress() + "</td></tr>"
0629:                            + "<tr><td>Command/Status port</td><td>"
0630:                            + commandStatusPort + "</td></tr>";
0631:                } catch (Exception e) {
0632:                    loggingInterface.debugMsg(loggingInterface.ERROR,
0633:                            loggingInterface.GENERALSTATUS,
0634:                            "Not able to initialize DataShareServer");
0635:                    loggingInterface.logException(LoggingInterface.ERROR, e);
0636:                    this .shutDownConnectionsAndThreads();
0637:                }
0638:            }
0639:
0640:            // what follows are event driven by network data on the CommandStatus Channel...
0641:
0642:            static int objectCount = 0; // used to count each object received from a client over the commandStatusConnection
0643:
0644:            /**
0645:             * All DataShare connections require that the user 'register' on the channel before it
0646:             * will be made 'active' by the server.  this is so the server can associate a unique client
0647:             * name with each socket.  The client must register with the server before it will
0648:             * be added as a Client that other Clients can see.  The data received here is from the
0649:             * clients commandStatusConnection channel.  Note that when we call ts.sendData() here,
0650:             * the object sent goes to client the message was received from only. Also note that
0651:             * calls to this method come from the Thread of the Socket from which the data was received.
0652:             */
0653:            public/* synchronized */void clientDataReceived(
0654:                    DataShareObject dsObject, SocketAdapter ts) {
0655:                objectCount++;
0656:                try {
0657:                    Object object = SessionUtilities
0658:                            .retrieveObject(dsObject.objectBytes);
0659:
0660:                    if (object instanceof  RegistrationInfo) {
0661:                        RegistrationInfo ri = (RegistrationInfo) object;
0662:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0663:                                loggingInterface.CLIENT,
0664:                                "Received RegistrationInfo object from "
0665:                                        + ri.clientUserName);
0666:                        // put client into client table and clientmachines table and create ServerInfo  that has clients unique name
0667:                        ServerInfo si = addClient(ri, ts);
0668:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0669:                                loggingInterface.CLIENT,
0670:                                "Sending ServerInfo to "
0671:                                        + (si.clientRegistered ? ts
0672:                                                .getClientKey()
0673:                                                : ri.clientUserName));
0674:                        ts.sendData(new DataShareObject(SessionUtilities
0675:                                .convertObjectToByteArray(si), ts.getType(),
0676:                                myClientKeyValue));
0677:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0678:                                loggingInterface.GENERALSTATUS,
0679:                                "Free Memory - "
0680:                                        + Runtime.getRuntime().freeMemory()
0681:                                        / 1024 + " (Kbytes)");
0682:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0683:                                loggingInterface.GENERALSTATUS,
0684:                                "Used Memory - "
0685:                                        + Runtime.getRuntime().totalMemory()
0686:                                        / 1024 + " (Kbytes)");
0687:                    } else if (object instanceof  RequestFunctionInfo) {
0688:                        // send new client a list of possible Channel types
0689:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0690:                                loggingInterface.CLIENT,
0691:                                "Sending ChannelDescriptionArray to "
0692:                                        + ts.getClientKey());
0693:                        ts
0694:                                .sendData(new DataShareObject(
0695:                                        SessionUtilities
0696:                                                .convertObjectToByteArray(channelDescriptionArray),
0697:                                        ts.getType(), myClientKeyValue));
0698:                    } else if (object instanceof  CreateSessionRequest) {
0699:                        CreateSessionRequest csr = (CreateSessionRequest) object;
0700:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0701:                                loggingInterface.CLIENT,
0702:                                "Received CreateSessionRequest object from "
0703:                                        + ts.getClientKey());
0704:                        // create the session, and all its channels, taking care to do all the recording
0705:                        ClientSessionInfo csi = createSession(ts, csr);
0706:                        // send info to requesting client so it will join the session
0707:                        if (csi != null) {
0708:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
0709:                                    loggingInterface.CLIENT,
0710:                                    "Sending ClientSessionInfo to "
0711:                                            + ts.getClientKey());
0712:                            ts.sendData(new DataShareObject(SessionUtilities
0713:                                    .convertObjectToByteArray(csi), ts
0714:                                    .getType(), myClientKeyValue));
0715:                            //               // add an inactive consumer to every channel that client will try to join
0716:                            //               for(int x=0; x<csi.dsConnDescriptor.length; x++)
0717:                            //                  {
0718:                            //                  this.addConsumer(ts.getClientKey(), csi.sessionName, csi.dsConnDescriptor[x].channelDescription.channelName,false);
0719:                            //                  }
0720:                        }
0721:                    } else if (object instanceof  JoinSession) {
0722:                        // any client that sends us a JoinSession object will be sent the corresponding ClientSessionInfo object
0723:                        JoinSession sessionToJoin = (JoinSession) object;
0724:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0725:                                loggingInterface.CLIENT,
0726:                                "Received JoinSession object from "
0727:                                        + ts.getClientKey());
0728:                        // find the session
0729:                        if (sessionTable
0730:                                .containsKey(sessionToJoin.sessionKeyValue)) {
0731:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
0732:                                    loggingInterface.CLIENT,
0733:                                    "Found JoinSession Session "
0734:                                            + sessionToJoin.sessionKeyValue);
0735:                            SessionInfo sessionInfo = (SessionInfo) sessionTable
0736:                                    .get(sessionToJoin.sessionKeyValue);
0737:                            ClientSessionInfo csi = new ClientSessionInfo(
0738:                                    sessionInfo.getName(), sessionInfo
0739:                                            .getSessionDescription(),
0740:                                    sessionInfo.getKeyValue(), sessionInfo
0741:                                            .getChannelConnectionDescriptors(),
0742:                                    false, false); // not new session, not private
0743:                            // send info to requesting client so it will join the session
0744:                            if (csi != null) {
0745:                                loggingInterface.debugMsg(
0746:                                        loggingInterface.DEBUG,
0747:                                        loggingInterface.CLIENT,
0748:                                        "Sending ClientSessionInfo to "
0749:                                                + ts.getClientKey());
0750:                                ts.sendData(new DataShareObject(
0751:                                        SessionUtilities
0752:                                                .convertObjectToByteArray(csi),
0753:                                        ts.getType(), myClientKeyValue));
0754:                                //                  // add an inactive consumer to every channel that client will try to join
0755:                                //                  for(int x=0; x<csi.dsConnDescriptor.length; x++)
0756:                                //                     {
0757:                                //                     this.addConsumer(ts.getClientKey(), csi.sessionName, csi.dsConnDescriptor[x].channelDescription.channelName,false);
0758:                                //                     }
0759:                            }
0760:                        } else {
0761:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
0762:                                    loggingInterface.CLIENT,
0763:                                    "Client requested to join a session that could not be found->\nClient: "
0764:                                            + ts.getClientKey() + " Session: "
0765:                                            + sessionToJoin.sessionKeyValue);
0766:                        }
0767:                    } else if (object instanceof  RequestSessionNames) {
0768:                        RequestSessionNames rsn = (RequestSessionNames) object;
0769:                        Vector vec = new Vector();
0770:                        for (Enumeration e = sessionTable.elements(); e
0771:                                .hasMoreElements();) {
0772:                            SessionInfo this SessionInfo = (SessionInfo) e
0773:                                    .nextElement();
0774:                            if (ts.getClientClass().equals(
0775:                                    this SessionInfo.getClientClass())) // session class same as requested class?
0776:                                vec.add(this SessionInfo.getName());
0777:                        }
0778:                        String[] retValue = new String[vec.size()];
0779:                        for (int x = 0; x < retValue.length; x++)
0780:                            retValue[x] = (String) vec.elementAt(x);
0781:                        SessionNames sn = new SessionNames(retValue);
0782:                        ts.sendData(new DataShareObject(SessionUtilities
0783:                                .convertObjectToByteArray(sn), ts.getType(),
0784:                                myClientKeyValue));
0785:                    } else if (object instanceof  RequestFunctionsInSession) {
0786:                        RequestFunctionsInSession rfis = (RequestFunctionsInSession) object;
0787:                        FunctionsInSession fis = new FunctionsInSession(
0788:                                rfis.sessionName);
0789:                        if (sessionTable.containsKey(rfis.sessionName)) {
0790:                            Vector vec = new Vector();
0791:                            SessionInfo si = (SessionInfo) sessionTable
0792:                                    .get(rfis.sessionName);
0793:                            for (Enumeration e = si.getChannelTable()
0794:                                    .elements(); e.hasMoreElements();) {
0795:                                ChannelInfo ci = (ChannelInfo) e.nextElement();
0796:                                String functionName = ci
0797:                                        .getConnectionDescriptor().channelDescription.channelName;
0798:                                vec.add(functionName);
0799:                            }
0800:                            String[] retValue = new String[vec.size()];
0801:                            for (int x = 0; x < retValue.length; x++)
0802:                                retValue[x] = (String) vec.elementAt(x);
0803:                            fis.setFunctionsInSession(retValue);
0804:                        }
0805:                        ts.sendData(new DataShareObject(SessionUtilities
0806:                                .convertObjectToByteArray(fis), ts.getType(),
0807:                                myClientKeyValue));
0808:                    } else if (object instanceof  RequestTree) {
0809:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0810:                                loggingInterface.CLIENT,
0811:                                "Received RequestTree object from "
0812:                                        + ts.getClientKey());
0813:                        // let treeView create a tree customized for this Client
0814:                        TreeObject tree = new TreeObject(treeView
0815:                                .getExternalTreeNode(this .getClientInfo(ts
0816:                                        .getClientKey())));
0817:                        // if we are showing archived sessions, and this client is admin, add archived sessions to tree
0818:                        if (showArchivedSessionsToAdmin && ts.getAdmin())
0819:                            tree.allNodes.add(treeView
0820:                                    .getExternalArchivedNode());
0821:                        // send the tree!
0822:                        ts.sendData(new DataShareObject(SessionUtilities
0823:                                .convertObjectToByteArray(tree), ts.getType(),
0824:                                myClientKeyValue));
0825:                    } else if (object instanceof  RegisterTreeListener) {
0826:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0827:                                loggingInterface.CLIENT,
0828:                                "Received RegisterTreeListener object from "
0829:                                        + ts.getClientKey());
0830:                        RegisterTreeListener rtl = (RegisterTreeListener) object;
0831:                        // set ClientInfo to reflect what type of clients this client will see in its tree
0832:                        ClientInfo clientInfo = this .getClientInfo(ts
0833:                                .getClientKey());
0834:                        clientInfo.setSeeAllTreeObjects(rtl.allChanges);
0835:                        treeView.addTreeListener(clientInfo, ts);
0836:                    } else if (object instanceof  DeleteSession) {
0837:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0838:                                loggingInterface.CLIENT,
0839:                                "Received DeleteSession object from "
0840:                                        + ts.getClientKey());
0841:                        DeleteSession ds = (DeleteSession) object;
0842:                        deleteSession(ts, ds);
0843:                    } else if (object instanceof  RequestHistory) {
0844:                        // we assume that clients do not ask for history if the server is not using beans
0845:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0846:                                loggingInterface.CLIENT,
0847:                                "Received RequestHistory object from "
0848:                                        + ts.getClientKey());
0849:                        RequestHistory rh = (RequestHistory) object;
0850:                        if (rh.typeOfRequest == RequestHistory.COUNT) {
0851:                            int numberOfBeans = 0;
0852:                            HistoryCountObject ho = null;
0853:                            // put consumer in tree with active=false before we get the count...
0854:                            this .addConsumer(ts.getClientKey(), rh.sessionName,
0855:                                    rh.channelName, false);
0856:                            // use the provided ADSKey for the Channel to get the beans...
0857:                            // this is a blocking call, but we don't care because it is in the thread for the client commandStatusSocket
0858:                            numberOfBeans = RetreiveDataBeans
0859:                                    .getDataCount(persistenceInterface,
0860:                                            rh.channelDatabaseKey);
0861:                            ho = new HistoryCountObject(rh.sessionName,
0862:                                    rh.channelDatabaseKey, numberOfBeans);
0863:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
0864:                                    loggingInterface.CLIENT,
0865:                                    "Sending HistoryCountObject for channel "
0866:                                            + rh.channelDatabaseKey
0867:                                            + ", objects found: "
0868:                                            + numberOfBeans);
0869:                            ts.sendData(new DataShareObject(SessionUtilities
0870:                                    .convertObjectToByteArray(ho),
0871:                                    ts.getType(), myClientKeyValue));
0872:                        } else if (rh.typeOfRequest == RequestHistory.DATA
0873:                                || rh.typeOfRequest == RequestHistory.CANCEL) {
0874:                            loggingInterface
0875:                                    .debugMsg(
0876:                                            loggingInterface.ERROR,
0877:                                            loggingInterface.CLIENT,
0878:                                            "*** received RequestHistory for Data/Cancel in commandStatus channel, should be in Data Channel!!");
0879:                        }
0880:                    } else if (object instanceof  DisconnectConsumer) {
0881:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0882:                                loggingInterface.CLIENT,
0883:                                "Received DisconnectConsumer object from "
0884:                                        + ts.getClientKey());
0885:                        DisconnectConsumer dc = (DisconnectConsumer) object;
0886:                        if (ts.getClientKey().equals(dc.clientKey)) // can only remove yourself
0887:                        {
0888:                            this .removeAndDisconnectConsumer(dc.clientKey,
0889:                                    dc.sessionKey, dc.channelKey);
0890:                        } else {
0891:                            loggingInterface.debugMsg(loggingInterface.ERROR,
0892:                                    loggingInterface.CLIENT,
0893:                                    "DisconnectConsumer incorrect client!! "
0894:                                            + ts.getClientKey()
0895:                                            + " disconnecting " + dc.clientKey);
0896:                        }
0897:                    } else if (object instanceof  TokenRequestObject) {
0898:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0899:                                loggingInterface.CLIENT,
0900:                                "Received TokenRequestObject from "
0901:                                        + ts.getClientKey());
0902:                        TokenRequestObject tro = (TokenRequestObject) object;
0903:                        tokenRequestReceived(tro, ts);
0904:                    } else if (object instanceof  InstantMsgData) {
0905:                        // forward this IM
0906:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0907:                                loggingInterface.CLIENT,
0908:                                "Received InstantMsg object from "
0909:                                        + ts.getClientKey());
0910:                        InstantMsgData imd = (InstantMsgData) object;
0911:
0912:                        // loop for each client this message goes to
0913:                        for (int x = 0; x < imd.destinationClientKeyValue.length; x++) {
0914:                            // send data to one socket at a time...
0915:                            SocketAdapter tsDestinationClient = (SocketAdapter) commandStatusSocketHandlers
0916:                                    .get(imd.destinationClientKeyValue[x]);
0917:                            if (tsDestinationClient != null) {
0918:                                tsDestinationClient.sendData(dsObject); // send same object
0919:                                loggingInterface
0920:                                        .debugMsg(
0921:                                                loggingInterface.DEBUG,
0922:                                                loggingInterface.CLIENT,
0923:                                                "Sent an IM to "
0924:                                                        + imd.destinationClientKeyValue[x]);
0925:                            } else {
0926:                                loggingInterface
0927:                                        .debugMsg(
0928:                                                loggingInterface.WARNING,
0929:                                                loggingInterface.CLIENT,
0930:                                                "Could not find this client to send the IM to-> "
0931:                                                        + imd.destinationClientKeyValue[x]);
0932:                            }
0933:                        }
0934:                    } else if (object instanceof  ControlServerObject) {
0935:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
0936:                                loggingInterface.GENERALSTATUS,
0937:                                "Received ControlServerObject from "
0938:                                        + ts.getClientKey());
0939:                        ControlServerObject cso = (ControlServerObject) object;
0940:                        if (cso.serviceType == ControlServerObject.VERBOSEserviceType) {
0941:                            if (cso.serviceValueInt == ControlServerObject.ONserviceValue) {
0942:                                loggingInterface
0943:                                        .debugMsg(
0944:                                                loggingInterface.DEBUG,
0945:                                                loggingInterface.GENERALSTATUS,
0946:                                                "Admin Client "
0947:                                                        + ts.getClientKey()
0948:                                                        + " has requested that Verbose be turned on");
0949:                                debug = true;
0950:                            } else if (cso.serviceValueInt == ControlServerObject.OFFserviceValue) {
0951:                                loggingInterface
0952:                                        .debugMsg(
0953:                                                loggingInterface.DEBUG,
0954:                                                loggingInterface.GENERALSTATUS,
0955:                                                "Admin Client "
0956:                                                        + ts.getClientKey()
0957:                                                        + " has requested that Verbose be turned off");
0958:                                debug = false;
0959:                            }
0960:                        }
0961:                        SessionUtilities.setVerbose(debug);
0962:                        ServerStatusObject sso = new ServerStatusObject(debug);
0963:                        // so all clients get it, not just the one that sent this object
0964:                        sendToAllCommandStatusClients(sso);
0965:                    } else {
0966:                        String objectClass = "unknown";
0967:                        try {
0968:                            objectClass = object.getClass().toString();
0969:                        } catch (Exception e) {
0970:                        }
0971:                        loggingInterface
0972:                                .debugMsg(loggingInterface.WARNING,
0973:                                        loggingInterface.GENERALSTATUS,
0974:                                        "unknown object type received-> "
0975:                                                + objectClass);
0976:                    }
0977:                } catch (Exception e) {
0978:                    loggingInterface.debugMsg(loggingInterface.ERROR,
0979:                            loggingInterface.CLIENT,
0980:                            "Problems with received data from client ("
0981:                                    + ts.getClientKey() + ")");
0982:                    loggingInterface.logException(LoggingInterface.ERROR, e);
0983:                    //e.printStackTrace();
0984:                }
0985:            }
0986:
0987:            /**
0988:             * this will take a hashtable of SessionInfo objects (which contain ChannelInfo objects), and try
0989:             * to create the Sessions/Channels specified.
0990:             */
0991:            private void createSessions(Hashtable sessions) {
0992:                for (Enumeration enumS = sessions.elements(); enumS
0993:                        .hasMoreElements();) {
0994:                    try {
0995:                        SessionInfo si = (SessionInfo) enumS.nextElement();
0996:                        System.out.println("Re-opening Session named -> "
0997:                                + si.getName());
0998:                        sessionTable.put(si.getKeyValue(), si);
0999:                        // tell clients about new session...
1000:                        treeView.addSession(si);
1001:
1002:                        for (Enumeration enumC = si.getChannelTable()
1003:                                .elements(); enumC.hasMoreElements();) {
1004:                            ChannelInfo ci = (ChannelInfo) enumC.nextElement();
1005:                            // make sure we still have a Channel of that type...
1006:                            boolean found = false;
1007:                            for (int x = 0; x < channelDescriptionArray.channelDescriptions.length; x++) {
1008:                                // channelName must match
1009:                                if (channelDescriptionArray.channelDescriptions[x].channelName
1010:                                        .equals(ci.getConnectionDescriptor().channelDescription.channelName))
1011:                                    if (channelDescriptionArray.channelDescriptions[x].type == ci
1012:                                            .getConnectionDescriptor().channelDescription.type)
1013:                                        if (channelDescriptionArray.channelDescriptions[x].channelClass
1014:                                                .equals(ci
1015:                                                        .getConnectionDescriptor().channelDescription.channelClass)) {
1016:                                            found = true;
1017:                                            System.out
1018:                                                    .println("Re-opening Session with channel named -> "
1019:                                                            + ci
1020:                                                                    .getConnectionDescriptor().channelDescription.channelName);
1021:                                        }
1022:                            }
1023:                            if (found) // then we can create this channel
1024:                            {
1025:                                ChannelInfo this Channel = createChannel(
1026:                                        ci.getConnectionDescriptor().channelDescription,
1027:                                        si, false); // false so we don't create si/ci EJB again
1028:
1029:                                this Channel.setSaveDataForThisChannel(ci
1030:                                        .getSaveDataForThisChannel()
1031:                                        && this .persistData);
1032:                                if (this Channel.getSaveDataForThisChannel()) {
1033:                                    String key = ci.getDatabaseID();
1034:                                    System.out
1035:                                            .println("Re-opening saved Session found Channel database ID of "
1036:                                                    + key);
1037:                                    this Channel.setDatabaseID(key);
1038:                                    this Channel.getConnectionDescriptor().databaseID = key;
1039:                                    this Channel.getDataReceiverAdapter()
1040:                                            .setChannelInfo(this Channel);
1041:                                    this Channel.getDataReceiverAdapter()
1042:                                            .setChannelDatabaseKey(key);
1043:                                    this Channel.getDataReceiverAdapter().sequence = RetreiveDataBeans
1044:                                            .getDataCount(persistenceInterface,
1045:                                                    key);
1046:                                } else
1047:                                    System.out
1048:                                            .println("Re-opening saved Session found Channel that is not saving data -> "
1049:                                                    + ci.getName());
1050:
1051:                                ChannelInfo removedChannelInfo = (ChannelInfo) si
1052:                                        .getChannelTable().remove(
1053:                                                ci.getKeyValue());
1054:                                if (removedChannelInfo == null)
1055:                                    System.out
1056:                                            .println("OH NO!!! Did not remove channel ("
1057:                                                    + ci.getKeyValue()
1058:                                                    + ") from re-opened Session!!!");
1059:                                si.addChannel(this Channel); // save new one that may have new ports, etc.
1060:                                treeView.addChannel(this Channel);
1061:                            } else
1062:                                System.out
1063:                                        .println("Re-opening saved Session could not find ChannelDescription -> "
1064:                                                + " name="
1065:                                                + ci.getConnectionDescriptor().channelDescription.channelName
1066:                                                + ",type="
1067:                                                + ChannelDescription.validTypes[ci
1068:                                                        .getConnectionDescriptor().channelDescription.type]
1069:                                                + ",class="
1070:                                                + ci.getConnectionDescriptor().channelDescription.channelClass);
1071:
1072:                        }
1073:                    } catch (Exception e) {
1074:                        /***/
1075:                        e.printStackTrace(); // need to change to new logging methods 
1076:                    }
1077:                }
1078:                System.out.println("Re-opening Sessions completed");
1079:            }
1080:
1081:            /**
1082:             * this is used when it is necessary to send an object to all clients over their
1083:             * commandStatusConnection.
1084:             */
1085:            private void
1086:   sendToAllCommandStatusClients(Object object)
1087:      {
1088:      for(Enumeration enum = this .commandStatusSocketHandlers.elements(); enum.hasMoreElements();)
1089:         {
1090:         SocketAdapter sa = null;
1091:         try{
1092:            sa = (SocketAdapter)enum.nextElement();
1093:            sa.sendData((new DataShareObject(SessionUtilities.convertObjectToByteArray(object), sa.getType(), myClientKeyValue)));
1094:            }
1095:         catch(Exception e)
1096:            {
1097:            loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.CLIENT,
1098:               "Problem sending data to client ("+ (sa==null?null:sa.getClientKey()) +")");
1099:            loggingInterface.logException(LoggingInterface.ERROR, e);
1100:            }
1101:         }
1102:      }
1103:
1104:            /**
1105:             * Processes the object from a client that is requesting Session be deleted from the
1106:             * Server.  The Session must have no clients, and the requester must be the owner, or
1107:             * an admin client.  A check will also be made to see if the data was persisted and
1108:             * the methods to archive it are provided in it's ChannelData information.
1109:             */
1110:            private void deleteSession(SocketAdapter ts, DeleteSession ds) {
1111:                boolean sessionIsInArchives = false;
1112:                // is requestor owner or admin?
1113:                SessionInfo si = (SessionInfo) sessionTable
1114:                        .get(ds.sessionKeyValue);
1115:                if (si == null) {
1116:                    loggingInterface.debugMsg(loggingInterface.WARNING,
1117:                            loggingInterface.SESSION, "did not find session ("
1118:                                    + ds.sessionKeyValue
1119:                                    + ") to delete in active table...");
1120:                    // if session is from archives, sessionKeyValue will be ADSKey string instead of sessionName...
1121:                    si = (SessionInfo) treeView.oldSessionsTable
1122:                            .get(ds.sessionKeyValue);
1123:                    if (si != null) {
1124:                        sessionIsInArchives = true;
1125:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
1126:                                loggingInterface.SESSION, "found session ("
1127:                                        + ds.sessionKeyValue
1128:                                        + ") to delete in the archives");
1129:                    }
1130:                }
1131:                ClientInfo ci = (ClientInfo) specialClientTable.get(ts
1132:                        .getClientKey().toLowerCase());
1133:                if (si != null && ci != null) {
1134:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1135:                            loggingInterface.SESSION, "Client "
1136:                                    + ts.getClientKey()
1137:                                    + " is requesting Session " + si.getName()
1138:                                    + " be deleted");
1139:                    // make sure session owner is client, or client is admin
1140:                    if (si.getOwnerName().equals(ci.getName()) || ci.getAdmin()) {
1141:                        // first, check that we are not being spoofed...
1142:                        SocketAdapter registeredSocketData = (SocketAdapter) commandStatusSocketHandlers
1143:                                .get(ts.getClientKey());
1144:                        if (ts.getRemoteIP() != registeredSocketData
1145:                                .getRemoteIP()) {
1146:                            // ignore data from Client whose IP address has 'changed' since registration
1147:                            loggingInterface.debugMsg(loggingInterface.WARNING,
1148:                                    loggingInterface.GENERALSTATUS,
1149:                                    "+++Someone is spoofing us:"
1150:                                            + ts.getRemoteIP().toString()
1151:                                            + " says they are "
1152:                                            + registeredSocketData
1153:                                                    .getRemoteIP().toString());
1154:                        } else {
1155:                            boolean empty = true;
1156:                            // ensure there are no clients in the channel
1157:                            for (Enumeration channelEnum = si.getChannelTable()
1158:                                    .elements(); channelEnum.hasMoreElements();) {
1159:                                ChannelInfo chan = (ChannelInfo) channelEnum
1160:                                        .nextElement();
1161:                                Hashtable consumers = chan.getConsumerTable();
1162:                                if (consumers != null && !consumers.isEmpty()) {
1163:                                    empty = false;
1164:                                    break;
1165:                                }
1166:                            }
1167:                            if (empty) // proceed only if all Channels in this Session have no Consumers...
1168:                            {
1169:                                if (!sessionIsInArchives) {
1170:                                    // remove Session from our tree, notify all clients, shutdown all Channel Sockets...
1171:                                    loggingInterface
1172:                                            .debugMsg(loggingInterface.DEBUG,
1173:                                                    loggingInterface.SESSION,
1174:                                                    "Delete Session found active session, testing for archivability...");
1175:                                    treeView.removeSession(si);
1176:                                    si.setActive(false);
1177:                                    sessionTable.remove(ds.sessionKeyValue);
1178:
1179:                                    //// need special test for BroadCastClient Session removal because it exists outside
1180:                                    //// of sessionTable too...
1181:                                    //if(ds.sessionKeyValue.equals(broadCastClientSessionName))
1182:                                    //   this.broadCastSessionInfo = null;
1183:
1184:                                    for (Enumeration channelEnum = si
1185:                                            .getChannelTable().elements(); channelEnum
1186:                                            .hasMoreElements();) {
1187:                                        ChannelInfo chan = (ChannelInfo) channelEnum
1188:                                                .nextElement();
1189:                                        chan.setActive(false);
1190:                                        chan.shutDown();
1191:                                        loggingInterface
1192:                                                .debugMsg(
1193:                                                        loggingInterface.DEBUG,
1194:                                                        loggingInterface.SESSION,
1195:                                                        "Delete Session found channel {"
1196:                                                                + chan
1197:                                                                        .getName()
1198:                                                                + "}, testing for archivability...");
1199:                                        // decide if data from the Channel should be archived to DocumentKonnect...
1200:                                        if (si.saveData
1201:                                                && chan
1202:                                                        .getSaveDataForThisChannel()) // was data archived?
1203:                                        {
1204:                                            loggingInterface
1205:                                                    .debugMsg(
1206:                                                            loggingInterface.DEBUG,
1207:                                                            loggingInterface.SESSION,
1208:                                                            "Archivable data should be found for channel {"
1209:                                                                    + chan
1210:                                                                            .getName()
1211:                                                                    + "}, testing for archive classes");
1212:                                            ChannelDescription cd = chan
1213:                                                    .getConnectionDescriptor().channelDescription;
1214:                                            if (cd.archiveChannelClass != null
1215:                                                    && !cd.archiveChannelClass
1216:                                                            .equals("")) // does the function in this Channel support archiving?
1217:                                            {
1218:                                                try {
1219:                                                    // String ownerKey = ci.getUserProxy().getID();
1220:                                                    archiveData(si, chan, si
1221:                                                            .getOwnerName()); // check to see if data should be saved to DK
1222:                                                } catch (Exception e) {
1223:                                                    loggingInterface
1224:                                                            .debugMsg(
1225:                                                                    loggingInterface.ERROR,
1226:                                                                    loggingInterface.SESSION,
1227:                                                                    "Problem in archiveData for class "
1228:                                                                            + cd.archiveChannelClass);
1229:                                                    loggingInterface
1230:                                                            .logException(
1231:                                                                    LoggingInterface.ERROR,
1232:                                                                    e);
1233:                                                }
1234:                                            } else {
1235:                                                loggingInterface
1236:                                                        .debugMsg(
1237:                                                                loggingInterface.DEBUG,
1238:                                                                loggingInterface.SESSION,
1239:                                                                "Archivable data for channel {"
1240:                                                                        + chan
1241:                                                                                .getName()
1242:                                                                        + "} could not find archive classes");
1243:                                            }
1244:                                        } else {
1245:                                            loggingInterface
1246:                                                    .debugMsg(
1247:                                                            loggingInterface.DEBUG,
1248:                                                            loggingInterface.SESSION,
1249:                                                            "Channel "
1250:                                                                    + chan
1251:                                                                            .getName()
1252:                                                                    + " not able to archive");
1253:                                        }
1254:                                    } // end of for loop, looping on channels
1255:                                    loggingInterface
1256:                                            .debugMsg(loggingInterface.DEBUG,
1257:                                                    loggingInterface.SESSION,
1258:                                                    "Delete Session has processed all Channels for archivable data");
1259:                                    if (si.saveData)
1260:                                        deleteSessionData(si.getDatabaseID());
1261:                                } else // session is in archives
1262:                                {
1263:                                    // now remove all references to this Session from the database
1264:                                    deleteSessionData(si.getDatabaseID());
1265:                                }
1266:                            } else {
1267:                                // Session is not empty
1268:                                loggingInterface
1269:                                        .debugMsg(loggingInterface.DEBUG,
1270:                                                loggingInterface.SESSION,
1271:                                                "deleteSession called for Session that still has at least one Consumer");
1272:                            }
1273:                        }
1274:                    } else {
1275:                        // session owner is not client, or client is not admin
1276:                        loggingInterface
1277:                                .debugMsg(loggingInterface.WARNING,
1278:                                        loggingInterface.SESSION,
1279:                                        "deleteSession was called by client that is not owner and not admin.");
1280:                    }
1281:                } else {
1282:                    // cannot find Session or Channel
1283:                    loggingInterface
1284:                            .debugMsg(
1285:                                    loggingInterface.WARNING,
1286:                                    loggingInterface.SESSION,
1287:                                    "deleteSession could not find Session ("
1288:                                            + (si == null ? null : si.getName())
1289:                                            + ") and/or requesting Client ("
1290:                                            + ci == null ? null : ci
1291:                                            .getKeyValue()
1292:                                            + ")");
1293:                }
1294:            }
1295:
1296:            /**
1297:             * gets the archived data for this Channel, puts it back through its Function, takes output
1298:             * byte[] and archives it into DK.  It already should have been determined that this channel should
1299:             * be archived and it supports archiving.
1300:             */
1301:            private void archiveData(SessionInfo si, ChannelInfo ci,
1302:                    String ownerKey) {
1303:                loggingInterface.debugMsg(loggingInterface.DEBUG,
1304:                        loggingInterface.SESSION,
1305:                        "archiveData() called for Session/Channel: "
1306:                                + si.getName() + "/" + ci.getName());
1307:                try {
1308:                    final ChannelDescription cd = ci.getConnectionDescriptor().channelDescription;
1309:                    Object archiveClass = null; // the class from the Function we will use to generate the byte[] to archive
1310:
1311:                    // find the class files for Channel function
1312:                    // first look locally
1313:                    try {
1314:                        final ClassLoader cl = this .getClass().getClassLoader();
1315:                        archiveClass = cl.loadClass(cd.archiveChannelClass)
1316:                                .newInstance();
1317:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
1318:                                loggingInterface.SESSION, cd.channelName
1319:                                        + "'s archive class loaded");
1320:                    } catch (Exception e) {
1321:                        loggingInterface.debugMsg(loggingInterface.ERROR,
1322:                                loggingInterface.SESSION, "Problem-> "
1323:                                        + e.getMessage()
1324:                                        + " when trying to load archive class");
1325:                    }
1326:
1327:                    if (archiveClass != null) // then we have our class loaded, find the method we need to put data into it...
1328:                    {
1329:                        final SessionInfo si2 = si;
1330:                        final ChannelInfo ci2 = ci;
1331:                        final String ownerKey2 = ownerKey;
1332:                        final Object archiveClass2 = archiveClass;
1333:                        // run the archiving from its own thread so we don't tie up the server's connection to this client
1334:                        final Runnable archiveTheData = new Runnable() {
1335:                            public void run() {
1336:                                Thread.currentThread().setName(
1337:                                        "ArchiveTheDataThread");
1338:                                archiveDataLoop(si2, ci2, cd, ownerKey2,
1339:                                        archiveClass2);
1340:                            }
1341:                        };
1342:                        Thread shortLivedThread = new Thread(archiveTheData);
1343:                        shortLivedThread.start();
1344:                        Thread.currentThread().yield();
1345:                    }
1346:                } catch (Exception e) {
1347:                    loggingInterface.debugMsg(loggingInterface.ERROR,
1348:                            loggingInterface.SESSION,
1349:                            "Problem in archiveData()...");
1350:                    loggingInterface.logException(loggingInterface.ERROR, e);
1351:                }
1352:            }
1353:
1354:            /**
1355:             * this method should only be called by the above method, and the only reason this is
1356:             * a method at all is because it needed to be run in a Thread of its own.
1357:             */
1358:            private void archiveDataLoop(SessionInfo si, ChannelInfo ci,
1359:                    ChannelDescription cd, String ownerKey, Object archiveClass) {
1360:                try {
1361:                    RetreiveDataBeans retreiveDataBeans = new RetreiveDataBeans();
1362:                    Class[] parameter = { new DataShareObject().getClass() };
1363:                    Method setDataMethod = archiveClass.getClass().getMethod(
1364:                            cd.archiveChannelSetDataMethod, parameter);
1365:                    // loop on this method for all of the DataShareObjects that exists in our persisted data...
1366:                    int count = RetreiveDataBeans.getDataCount(
1367:                            persistenceInterface, ci.getDatabaseID());
1368:                    // get all the data
1369:                    retreiveDataBeans.retrieveAllData(persistenceInterface, ci
1370:                            .getDatabaseID()); // could take a while
1371:                    DataShareObject[] dsArray = retreiveDataBeans
1372:                            .getNextData(count);
1373:                    if (dsArray != null) {
1374:                        for (int x = 0; x < dsArray.length; x++) {
1375:                            Object[] dsParameter = { (Object) dsArray[x] };
1376:                            setDataMethod.invoke(archiveClass, dsParameter);
1377:                        }
1378:                        Method getDataMethod = archiveClass
1379:                                .getClass()
1380:                                .getMethod(cd.archiveChannelGetDataMethod, null); // no parameter
1381:                        byte[] fileData = (byte[]) getDataMethod.invoke(
1382:                                archiveClass, null);
1383:
1384:                        persistenceInterface
1385:                                .saveFunctionDataToDisk(ownerKey, si, ci,
1386:                                        cd.fileExtension, fileData, cd.mimeType);
1387:                        loggingInterface
1388:                                .debugMsg(loggingInterface.DEBUG,
1389:                                        loggingInterface.SESSION,
1390:                                        "!!!!Successfully save this Functions data into DK!!!!!");
1391:                    } else {
1392:                        loggingInterface
1393:                                .debugMsg(loggingInterface.DEBUG,
1394:                                        loggingInterface.SESSION,
1395:                                        "There was no data to archive for this Channel");
1396:                    }
1397:                } catch (Exception e) {
1398:                    loggingInterface.debugMsg(loggingInterface.ERROR,
1399:                            loggingInterface.SESSION,
1400:                            "Problem in archiveDataLoop...");
1401:                    loggingInterface.logException(LoggingInterface.ERROR, e);
1402:                }
1403:            }
1404:
1405:            boolean dataLoopFinished;
1406:
1407:            /**
1408:             * this method will attempt to delete (remove from the database) all the data associated
1409:             * with a Session.  The databaseID String for the Session is all that is needed, and because
1410:             * it can take a while to find and remove all the data, a new Thread is spawned to actually
1411:             * do the task.  This method should not be called if the server is not using beans.
1412:             */
1413:            private synchronized void deleteSessionData(String sessionDatabaseID) {
1414:                if (this .getPersistData()) {
1415:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1416:                            loggingInterface.SESSION,
1417:                            "deleting data for Session " + sessionDatabaseID);
1418:                    final String sessionDatabaseID2 = sessionDatabaseID;
1419:                    // run the archiving from its own thread so we don't tie up the server's connection to this client
1420:                    final Runnable deleteTheData = new Runnable() {
1421:                        public void run() {
1422:                            Thread.currentThread().setName(
1423:                                    "deleteTheDataThread");
1424:                            deleteSessionDataLoop(sessionDatabaseID2);
1425:                        }
1426:                    };
1427:                    Thread shortLivedThread = new Thread(deleteTheData);
1428:                    dataLoopFinished = false;
1429:                    shortLivedThread.start();
1430:                    if (treeView.oldSessionsTable
1431:                            .containsKey(sessionDatabaseID))
1432:                        treeView.oldSessionsTable.remove(sessionDatabaseID);
1433:                    Thread.currentThread().yield();
1434:                    // don't return until finished, we can exit DataShare before thread finished otherwise
1435:                    while (!dataLoopFinished)
1436:                        SessionUtilities.delay(200);
1437:                }
1438:            }
1439:
1440:            /**
1441:             * this method should only be called from the above method, the only reason this is a method
1442:             * is so that it may be called from its own thread.
1443:             */
1444:            private void
1445:   deleteSessionDataLoop(String sessionDatabaseID)
1446:      {
1447:      try{
1448:         //ADSKey key = new ADSKey(sessionDatabaseID);
1449:         //Enumeration enum = EjbUtil.findByQuery("DSSessionHome", "getID()='"+key+"'" );
1450:         Enumeration enum = persistenceInterface.searchForUserObjects("DSSession3Home","getID()='"+sessionDatabaseID+"'");
1451:         SessionInfo sessionInfo = (SessionInfo)enum.nextElement();  // should only be one session returned
1452:         try{
1453:            Enumeration enum2 = persistenceInterface.searchForUserObjects("DSChannel3Home", "getSessionKey()='"+sessionDatabaseID+"'" );
1454:            // loop on all channels
1455:            for( ; enum2.hasMoreElements(); )
1456:               {
1457:               try{
1458:                  ChannelInfo channelInfo = (ChannelInfo)enum2.nextElement();
1459:                  persistenceInterface.delete("DSData3Home", "getChannelKey()='"+channelInfo.getDatabaseID()+"'");
1460:                  persistenceInterface.delete("DSChannel3Home", "getID()='"+channelInfo.getDatabaseID()+"'");
1461:                  }
1462:               catch(Exception e2)
1463:                  {
1464:                  loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.DATABASE,
1465:                     "Problem with a channel in deleteSessionDataLoop...");
1466:                  loggingInterface.logException(LoggingInterface.ERROR, e2);
1467:                  }
1468:               }
1469:            }
1470:         catch(Exception e)
1471:            {
1472:            loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.DATABASE,
1473:               "Problem in deleteSessionDataLoop...");
1474:            loggingInterface.logException(LoggingInterface.ERROR, e);
1475:            }
1476:         persistenceInterface.delete("DSSession3Home","getID()='"+sessionDatabaseID+"'");
1477:         }
1478:      catch(Exception e3)
1479:         {
1480:         loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.DATABASE,
1481:            "Problem in deleteSessionDataLoop...");
1482:         loggingInterface.logException(LoggingInterface.ERROR, e3);
1483:         }
1484:      dataLoopFinished = true;
1485:      }
1486:
1487:            /**
1488:             * this method will delete any sessions that do not have saved data.  If data
1489:             * is not being saved (i.e. no database, etc.), no action is taken.  This method 
1490:             * should not be called if there are active consumers in any of the channels as it
1491:             * will not gracefully remove them (call shutdownConnectionsAndThreads first).  Also
1492:             * note that this method will not clean up the sessionTable by removing the sessions
1493:             * whose data has been deleted.  This method is designed to be called at shutdown to
1494:             * clean up the database prior to the next startup of the DataShare server.
1495:             */
1496:            void deleteEmptySessions() {
1497:                if (useDatabase) {
1498:                    loggingInterface
1499:                            .debugMsg(loggingInterface.DEBUG,
1500:                                    loggingInterface.CLIENT,
1501:                                    "Removing Sessions from database if no data was saved...");
1502:                    for (Enumeration enumS = sessionTable.elements(); enumS
1503:                            .hasMoreElements();) {
1504:                        boolean isSavingData = false; // until we find a channel that saves data
1505:                        SessionInfo si = (SessionInfo) enumS.nextElement();
1506:                        Hashtable channelTable = si.getChannelTable();
1507:                        for (Enumeration enumC = channelTable.elements(); enumC
1508:                                .hasMoreElements();) {
1509:                            ChannelInfo ci = (ChannelInfo) enumC.nextElement();
1510:                            if (ci.getSaveDataForThisChannel()) {
1511:                                isSavingData = true;
1512:                                break;
1513:                            }
1514:                        }
1515:                        if (!isSavingData) // then we delete it
1516:                        {
1517:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
1518:                                    loggingInterface.CLIENT,
1519:                                    "Deleting database data for Session -> "
1520:                                            + si.getName());
1521:                            deleteSessionData(si.getDatabaseID());
1522:                        }
1523:                    }
1524:                }
1525:            }
1526:
1527:            /**
1528:             * This is called when we lose a client's commandStatus connection to our server
1529:             */
1530:            public void connectionLost(SocketAdapter ts) {
1531:                loggingInterface.debugMsg(loggingInterface.DEBUG,
1532:                        loggingInterface.CLIENT,
1533:                        "Lost the commandStatus connection to "
1534:                                + ts.getKeyValue());
1535:
1536:                // do all the paperwork associated with loosing this client from the commandStatus Channel
1537:                if (connections.containsKey(ts.getKeyValue())) {
1538:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1539:                            loggingInterface.CLIENT, "Removing connection for "
1540:                                    + ts.getKeyValue()
1541:                                    + " from connections table");
1542:                    connections.remove(ts.getKeyValue());
1543:                }
1544:
1545:                if (ts.getClientKey() != null) {
1546:                    removeClient(ts.getClientKey());
1547:                } else {
1548:                    loggingInterface
1549:                            .debugMsg(loggingInterface.DEBUG,
1550:                                    loggingInterface.CLIENT,
1551:                                    "Could not remove client from our tables, socket had no clientKey!");
1552:                }
1553:
1554:            }
1555:
1556:            /**
1557:             * called when we need to shutdown all client connections and threads (i.e. we are exiting)
1558:             */
1559:            public void
1560:   shutDownConnectionsAndThreads()
1561:      {
1562:      if(!alreadyShuttingDown)
1563:         {
1564:         alreadyShuttingDown = true;
1565:         loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.GENERALSTATUS,
1566:            "Shutting down all connections and Threads...");
1567:         // first close all CommandStatus connections that have not been activated
1568:         for(Enumeration enum = connections.elements(); enum.hasMoreElements(); )
1569:            {
1570:            SocketAdapter sa = null;
1571:            try{
1572:               sa = (SocketAdapter)enum.nextElement();
1573:               sa.close();
1574:               }
1575:            catch(Exception e)
1576:               {
1577:               loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
1578:                  "Problem shutting down un-activated connection -> " +  sa.getKeyValue());
1579:               loggingInterface.logException(LoggingInterface.ERROR, e);
1580:               }
1581:            }
1582:
1583:         for(Enumeration enum = allDataReceiverAdapters.elements(); enum.hasMoreElements(); )
1584:            {
1585:            DataReceiverAdapter dra = null;
1586:            try{
1587:               dra = (DataReceiverAdapter)enum.nextElement();
1588:               // now close all activated CommandStatus connections
1589:               dra.stopAllConnectionsAndThreads();
1590:               }
1591:            catch(Exception e)
1592:               {
1593:               loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
1594:                  "Problem shutting down data connection -> " + dra.getChannelKey());
1595:               loggingInterface.logException(LoggingInterface.ERROR, e);
1596:               }
1597:            }
1598:
1599:         for(Enumeration enum = commandStatusSocketHandlers.elements(); enum.hasMoreElements(); )
1600:            {
1601:            SocketAdapter sa = null;
1602:            try{
1603:               sa = (SocketAdapter)enum.nextElement();
1604:               sa.close();
1605:               }
1606:            catch(Exception e)
1607:               {
1608:               loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
1609:                  "Problem shutting down command/status connection -> " + sa.getKeyValue());
1610:               loggingInterface.logException(LoggingInterface.ERROR, e);
1611:               }
1612:            }
1613:
1614:         // now close our CommandStatus Server Thread
1615:         if(commandStatusServerThread != null)
1616:            commandStatusServerThread.close();
1617:         deleteEmptySessions();   
1618:         }
1619:      }
1620:
1621:            /**
1622:             * This is called when we lose our serverSocket, we can no longer make new connections,
1623:             * and may have lost the ability to use old ones for this socket.  This particular serverSocket
1624:             * is the overall commandStatusPort connection socket.
1625:             */
1626:            public void lostServerSocket(String keyValue) {
1627:                loggingInterface
1628:                        .debugMsg(loggingInterface.ERROR,
1629:                                loggingInterface.GENERALSTATUS,
1630:                                "******* DataShareServer:Lost our commandStatusPort listening socket!!!!!!");
1631:                this .shutDownConnectionsAndThreads();
1632:            }
1633:
1634:            /**
1635:             * called when someone new connects to our commandStatus Connection.
1636:             * At this point, we know IP and port, but not who is using it.
1637:             * ThreadedSocket is saved in Hashtable keyed by clientKey (unique Client name)
1638:             */
1639:            public void newConnection(SocketAdapter ts) {
1640:                loggingInterface.debugMsg(loggingInterface.DEBUG,
1641:                        loggingInterface.NETWORK,
1642:                        "New CommandStatus Connection-> " + ts.getKeyValue());
1643:                connections.put(ts.getKeyValue(), ts);
1644:            }
1645:
1646:            /**
1647:             * Takes client username, makes it unique, puts client's unique name into our
1648:             * Hashtable of clients, keeps a copy of what machine IP they registered from,
1649:             * and sends back to the client information about their unique name and server info.
1650:             * Note that all clients must have unique clientKey, even clients of dissimilar classes/types
1651:             */
1652:            public ServerInfo addClient(RegistrationInfo ri, SocketAdapter ts) {
1653:                //UserProxy userproxy = null;
1654:                StringBuffer errorMsg = new StringBuffer("");
1655:                //String uniqueName;
1656:                //boolean admin = false;
1657:                ServerInfo serverInfo = null; // sent back to client
1658:                boolean localUseBeans = persistData;
1659:                UserInfo userInfo = null;
1660:
1661:                if (logInAdapterFound && authenticatingClients) // we have a way for users to log in and we are authenticating
1662:                    userInfo = logInInterface.getUserInfo(ri, ts);
1663:                else { // for some reason, we will not ask clients to login
1664:                    userInfo = new UserInfo(ri); // user gets default values for everything
1665:                    if (!authenticatingClients) // everybody that finds us is considered authenticated!
1666:                        userInfo.authenticated = true;
1667:                }
1668:
1669:                if (userInfo.authenticated) {
1670:                    // client is OK to register
1671:                    userInfo.uniqueName = getUniqueName(ri.clientUserName);
1672:
1673:                    // create description of this client's commandStatus connection
1674:                    DataShareConnectionDescriptor dscd = new DataShareConnectionDescriptor(
1675:                            "", commandStatusDescriptor.channelDescription,
1676:                            userInfo.uniqueName, myIPAddress,
1677:                            this .commandStatusPort, ts.getRemoteIP(), ts
1678:                                    .getRemotePort());
1679:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1680:                            loggingInterface.CLIENT, "Authorizing client "
1681:                                    + userInfo.uniqueName + " with"
1682:                                    + (userInfo.admin ? "" : "out")
1683:                                    + " admin privileges");
1684:                    connections.remove(ts.getKeyValue());
1685:
1686:                    ts.setClientKey(userInfo.uniqueName);
1687:                    ts.setClientClass(userInfo.getClientClass());
1688:                    ts.setAdmin(userInfo.admin);
1689:                    ts.setActive(true);
1690:
1691:                    ClientInfo clientInfo = new ClientInfo(dscd, userInfo,
1692:                            localUseBeans);
1693:
1694:                    if (localUseBeans) {
1695:                        // save data for this client
1696:                        try {
1697:                            Hashtable props = new Hashtable();
1698:                            props.put("clientName", userInfo.uniqueName);
1699:                            props.put("userObject", clientInfo);
1700:                            saveDataToDatabase("DSClient3Home", props,
1701:                                    clientInfo);
1702:                        } catch (Exception e) {
1703:                            loggingInterface.debugMsg(loggingInterface.ERROR,
1704:                                    loggingInterface.CLIENT,
1705:                                    "Problems creating Client data for "
1706:                                            + userInfo.uniqueName);
1707:                            loggingInterface.logException(
1708:                                    loggingInterface.ERROR, e);
1709:                        }
1710:                    }
1711:
1712:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1713:                            loggingInterface.CLIENT, "Adding this client ("
1714:                                    + userInfo.uniqueName
1715:                                    + ") to our specialClientTable");
1716:                    specialClientTable.put(userInfo.uniqueName.toLowerCase(),
1717:                            clientInfo);
1718:
1719:                    treeView.addSpecialClient(clientInfo);
1720:
1721:                    loggingInterface
1722:                            .debugMsg(loggingInterface.DEBUG,
1723:                                    loggingInterface.CLIENT,
1724:                                    "Adding this clients ThreadedSocket to our list of commandStatus clients...");
1725:                    commandStatusSocketHandlers.put(userInfo.uniqueName, ts);
1726:                    serverInfo = new ServerInfo(true, userInfo.admin,
1727:                            userInfo.uniqueName, persistData, serverVersion,
1728:                            serverStartTime, myIPAddress, this .debug);
1729:                } else {
1730:                    loggingInterface.debugMsg(loggingInterface.WARNING,
1731:                            loggingInterface.CLIENT,
1732:                            "Client cannot be authenticated!!!-> "
1733:                                    + ri.clientUserName);
1734:                    // client is NOT OK to register
1735:                    serverInfo = new ServerInfo(
1736:                            false,
1737:                            false,
1738:                            "",
1739:                            false,
1740:                            "Client "
1741:                                    + ri.clientUserName
1742:                                    + " not known to server\nServer refuses connection.",
1743:                            serverStartTime, myIPAddress, this .debug);
1744:                }
1745:                return serverInfo;
1746:            }
1747:
1748:            /**
1749:             * Returns the InetAddress as a String
1750:             */
1751:            private String getTheMachineName(InetAddress clientIP) {
1752:                String machineName = "";
1753:                try {
1754:                    machineName = clientIP.getHostAddress();
1755:                } catch (Exception e) {
1756:                    loggingInterface.debugMsg(loggingInterface.ERROR,
1757:                            loggingInterface.CLIENT,
1758:                            "Problems getting IP address of a client");
1759:                    loggingInterface.logException(loggingInterface.ERROR, e);
1760:                }
1761:                return machineName;
1762:            }
1763:
1764:            /**
1765:             * removes all references to a Client, takes care of closing its connections and
1766:             * notifying other Clients.
1767:             */
1768:            public void removeClient(String clientKeyValue) {
1769:                loggingInterface.debugMsg(loggingInterface.DEBUG,
1770:                        loggingInterface.CLIENT, "Removing client "
1771:                                + clientKeyValue + " from all our Hashtables");
1772:
1773:                if (specialClientTable
1774:                        .containsKey(clientKeyValue.toLowerCase())) {
1775:                    ClientInfo clientInfo = (ClientInfo) specialClientTable
1776:                            .get(clientKeyValue.toLowerCase());
1777:
1778:                    if (commandStatusSocketHandlers.containsKey(clientKeyValue)) {
1779:                        SocketAdapter ts = (SocketAdapter) commandStatusSocketHandlers
1780:                                .get(clientKeyValue);
1781:                        treeView.removeTreeListener(ts);
1782:                        commandStatusSocketHandlers.remove(clientKeyValue); // remove client's handler for commandStatus connection
1783:                    } else {
1784:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
1785:                                loggingInterface.CLIENT,
1786:                                "no commandStatus table client entry with key of "
1787:                                        + clientKeyValue);
1788:                    }
1789:
1790:                    specialClientTable.remove(clientKeyValue.toLowerCase());
1791:                    treeView.removeSpecialClient(clientInfo);
1792:
1793:                    // need to find all the Channels this client is in and remove client
1794:                    if (sessionTable != null) {
1795:                        for (Enumeration e = sessionTable.elements(); e
1796:                                .hasMoreElements();) {
1797:                            SessionInfo this SessionInfo = (SessionInfo) e
1798:                                    .nextElement();
1799:                            if (this SessionInfo.getChannelTable() != null) {
1800:                                for (Enumeration channelEnum = this SessionInfo
1801:                                        .getChannelTable().elements(); channelEnum
1802:                                        .hasMoreElements();) {
1803:                                    ChannelInfo this ChannelInfo = (ChannelInfo) channelEnum
1804:                                            .nextElement();
1805:                                    if (this ChannelInfo.getConsumerTable() != null) {
1806:                                        for (Enumeration consumerEnum = this ChannelInfo
1807:                                                .getConsumerTable().elements(); consumerEnum
1808:                                                .hasMoreElements();) {
1809:                                            ConsumerInfo consumerInfo = (ConsumerInfo) consumerEnum
1810:                                                    .nextElement();
1811:                                            if (consumerInfo.getKeyValue()
1812:                                                    .equals(clientKeyValue)) {
1813:                                                // we found our client as a consumer...
1814:                                                this .removeConsumer(
1815:                                                        clientKeyValue,
1816:                                                        this SessionInfo
1817:                                                                .getKeyValue(),
1818:                                                        this ChannelInfo
1819:                                                                .getKeyValue());
1820:                                            }
1821:                                        }
1822:                                    }
1823:                                }
1824:                            }
1825:                        }
1826:                    }
1827:                } else {
1828:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1829:                            loggingInterface.CLIENT,
1830:                            "no client in SpecialClientTable with key of "
1831:                                    + clientKeyValue);
1832:                }
1833:            }
1834:
1835:            /**
1836:             * Called when a new consumer had been detected on a ThreadedServer socket (this is called
1837:             * from DataReceiverAdapter instances via the TreeViewServerInterface), puts the consumer in
1838:             * the list of consumers for the channel, notifies all registered clients, and creates the
1839:             * consumer EJB if not already created.
1840:             */
1841:            public void addConsumer(String clientKey, String sessionKey,
1842:                    String channelKey, boolean channelActive) {
1843:                loggingInterface.debugMsg(loggingInterface.DEBUG,
1844:                        loggingInterface.CLIENT, "addConsumer(" + clientKey
1845:                                + "," + sessionKey + "," + channelKey + ")");
1846:                ClientInfo clientInfo = (ClientInfo) specialClientTable
1847:                        .get(clientKey.toLowerCase());
1848:                if (clientInfo == null) {
1849:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
1850:                            loggingInterface.CLIENT,
1851:                            "addConsumer() could not add consumer->"
1852:                                    + clientKey
1853:                                    + " because specialClient not found!");
1854:                } else {
1855:                    // now we have a reference to the ClientInfo...
1856:                    SessionInfo sessionInfo = (SessionInfo) sessionTable
1857:                            .get(sessionKey);
1858:                    if (sessionInfo == null) {
1859:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
1860:                                loggingInterface.CLIENT,
1861:                                "addConsumer() could not add consumer->"
1862:                                        + clientKey
1863:                                        + " because Session not found!");
1864:                    } else {
1865:                        // now we have a reference to the clientInfo and the sessionInfo...
1866:                        Hashtable channelTable = sessionInfo.getChannelTable();
1867:                        if (channelTable == null) {
1868:                            loggingInterface
1869:                                    .debugMsg(
1870:                                            loggingInterface.DEBUG,
1871:                                            loggingInterface.CLIENT,
1872:                                            "addConsumer() could not add consumer->"
1873:                                                    + clientKey
1874:                                                    + " because no Channels in Session!");
1875:                        } else {
1876:                            ChannelInfo channelInfo = (ChannelInfo) channelTable
1877:                                    .get(channelKey);
1878:                            // now we have reference to the Channels...
1879:                            if (channelInfo == null) {
1880:                                loggingInterface
1881:                                        .debugMsg(
1882:                                                loggingInterface.DEBUG,
1883:                                                loggingInterface.CLIENT,
1884:                                                "addConsumer() could not add consumer->"
1885:                                                        + clientKey
1886:                                                        + " because could not find the Channel!");
1887:                            } else {
1888:                                // now we have a reference to the specific channel...
1889:                                ConsumerInfo consumerInfo = new ConsumerInfo(
1890:                                        clientInfo, sessionInfo, channelInfo);
1891:                                consumerInfo.setActive(channelActive);
1892:
1893:                                // add or overwrite channel table and tree entries
1894:                                loggingInterface
1895:                                        .debugMsg(
1896:                                                loggingInterface.DEBUG,
1897:                                                loggingInterface.CLIENT,
1898:                                                "server.addConsumer() adding "
1899:                                                        + consumerInfo
1900:                                                                .getKeyValue()
1901:                                                        + " as "
1902:                                                        + (consumerInfo
1903:                                                                .getActive() ? "active"
1904:                                                                : "inactive")
1905:                                                        + " to Session ("
1906:                                                        + sessionInfo.getName()
1907:                                                        + "), Channel ("
1908:                                                        + channelInfo.getName()
1909:                                                        + ")");
1910:                                channelInfo.addConsumerClient(consumerInfo);
1911:                                treeView.addConsumer(consumerInfo); // notifies clients so they update their trees
1912:                            }
1913:                        }
1914:                    }
1915:                }
1916:            }
1917:
1918:            /**
1919:             * Called when a consumer closes a Channel connection for which the server cannot
1920:             * detect that the connection is closed (i.e. UDP), this will remove the consumer from
1921:             * our tables, our tree, and cause the connection to close for that client in that channel
1922:             */
1923:            public void removeAndDisconnectConsumer(String clientKey,
1924:                    String sessionKey, String channelKey) {
1925:                SessionInfo sessionInfo = (SessionInfo) sessionTable
1926:                        .get(sessionKey);
1927:                if (sessionInfo == null) {
1928:                    loggingInterface
1929:                            .debugMsg(
1930:                                    loggingInterface.DEBUG,
1931:                                    loggingInterface.CLIENT,
1932:                                    "removeAndDisconnectConsumer() could not remove consumer because Session not found!");
1933:                } else {
1934:                    // now we have a reference to the clientInfo and the sessionInfo...
1935:                    Hashtable channelTable = sessionInfo.getChannelTable();
1936:                    if (channelTable == null) {
1937:                        loggingInterface
1938:                                .debugMsg(
1939:                                        loggingInterface.DEBUG,
1940:                                        loggingInterface.CLIENT,
1941:                                        "removeAndDisconnectConsumer() could not remove consumer because no Channels in Session!");
1942:                    } else {
1943:                        ChannelInfo channelInfo = (ChannelInfo) channelTable
1944:                                .get(channelKey);
1945:                        // now we have reference to the Channels...
1946:                        if (channelInfo == null) {
1947:                            loggingInterface
1948:                                    .debugMsg(
1949:                                            loggingInterface.DEBUG,
1950:                                            loggingInterface.CLIENT,
1951:                                            "removeAndDisconnectConsumer() could not remove consumer because could not find the Channel!");
1952:                        } else {
1953:                            // now we have a reference to the specific channel...
1954:                            Hashtable consumerTable = channelInfo
1955:                                    .getConsumerTable();
1956:                            if (consumerTable == null) {
1957:                                loggingInterface
1958:                                        .debugMsg(
1959:                                                loggingInterface.DEBUG,
1960:                                                loggingInterface.CLIENT,
1961:                                                "removeAndDisconnectConsumer() could not remove consumer because channel has no consumers!");
1962:                            } else {
1963:                                ConsumerInfo consumerInfo = (ConsumerInfo) consumerTable
1964:                                        .get(clientKey);
1965:                                if (consumerInfo != null) {
1966:                                    channelInfo
1967:                                            .removeConsumerClient(consumerInfo);
1968:                                    treeView.removeConsumer(consumerInfo);
1969:                                    // if no more consumers and this is a channel in an 'autoDelete' Session,
1970:                                    // the channel is deleted from the database and the Session
1971:                                    if (consumerTable.isEmpty()
1972:                                            && sessionInfo.getAutoDelete()) {
1973:                                        loggingInterface
1974:                                                .debugMsg(
1975:                                                        loggingInterface.DEBUG,
1976:                                                        loggingInterface.SESSION,
1977:                                                        "Channel ("
1978:                                                                + channelInfo
1979:                                                                        .getName()
1980:                                                                + ") is empty in autoDelete Session ("
1981:                                                                + sessionInfo
1982:                                                                        .getName()
1983:                                                                + "), removing it...");
1984:                                        channelTable.remove(channelKey);
1985:                                        channelInfo.shutDown();
1986:                                        treeView.removeChannel(channelInfo);
1987:                                    }
1988:                                } else {
1989:                                    loggingInterface
1990:                                            .debugMsg(
1991:                                                    loggingInterface.DEBUG,
1992:                                                    loggingInterface.SESSION,
1993:                                                    "removeAndDisconnectConsumer("
1994:                                                            + clientKey
1995:                                                            + ") could not remove consumer because this consumer was not in Channel ("
1996:                                                            + channelInfo
1997:                                                                    .getName()
1998:                                                            + ")");
1999:                                }
2000:                            }
2001:                        }
2002:                    }
2003:                }
2004:            }
2005:
2006:            /**
2007:             * Called when a consumer had closed a Channel connection (this is called
2008:             * from DataReceiverAdapter instances via the TreeViewServerInterface)
2009:             */
2010:            public void removeConsumer(String clientKey, String sessionKey,
2011:                    String channelKey) {
2012:                // get a reference to the SessionInfo...
2013:                SessionInfo sessionInfo = (SessionInfo) sessionTable
2014:                        .get(sessionKey);
2015:                if (sessionInfo == null) {
2016:                    loggingInterface
2017:                            .debugMsg(
2018:                                    loggingInterface.DEBUG,
2019:                                    loggingInterface.CLIENT,
2020:                                    "removeConsumer("
2021:                                            + clientKey
2022:                                            + ") could not remove consumer because Session ("
2023:                                            + sessionKey + ") not found!");
2024:                } else {
2025:                    // now find a reference to the ChannelInfo...
2026:                    Hashtable channelTable = sessionInfo.getChannelTable();
2027:                    if (channelTable == null) {
2028:                        loggingInterface
2029:                                .debugMsg(
2030:                                        loggingInterface.DEBUG,
2031:                                        loggingInterface.CLIENT,
2032:                                        "removeConsumer("
2033:                                                + clientKey
2034:                                                + ") could not remove consumer because no Channels in Session!");
2035:                    } else {
2036:                        ChannelInfo channelInfo = (ChannelInfo) channelTable
2037:                                .get(channelKey);
2038:                        // now we have reference to the Channels...
2039:                        if (channelInfo == null) {
2040:                            loggingInterface
2041:                                    .debugMsg(
2042:                                            loggingInterface.DEBUG,
2043:                                            loggingInterface.CLIENT,
2044:                                            "removeConsumer("
2045:                                                    + clientKey
2046:                                                    + ") could not remove consumer because could not find the Channel!");
2047:                        } else {
2048:                            // now we have a reference to the specific channel...
2049:                            Hashtable consumerTable = channelInfo
2050:                                    .getConsumerTable();
2051:                            if (consumerTable == null
2052:                                    || consumerTable.isEmpty()) {
2053:                                loggingInterface
2054:                                        .debugMsg(
2055:                                                loggingInterface.DEBUG,
2056:                                                loggingInterface.CLIENT,
2057:                                                "removeConsumer("
2058:                                                        + clientKey
2059:                                                        + ") could not remove consumer because channel has no conusmers!");
2060:                            } else {
2061:                                ConsumerInfo consumerInfo = (ConsumerInfo) consumerTable
2062:                                        .get(clientKey);
2063:                                if (consumerInfo != null) {
2064:                                    loggingInterface
2065:                                            .debugMsg(
2066:                                                    loggingInterface.DEBUG,
2067:                                                    loggingInterface.CLIENT,
2068:                                                    "Removing consumer "
2069:                                                            + clientKey
2070:                                                            + " from server table for Session/Channel of "
2071:                                                            + sessionKey + "/"
2072:                                                            + channelKey);
2073:                                    consumerTable.remove(clientKey);
2074:                                    treeView.removeConsumer(consumerInfo); // send updates to clients
2075:
2076:                                    // if no more consumers and this is a channel in an autoDelete Session,
2077:                                    // remove the channel from the session
2078:                                    if (channelInfo.getConsumerTable()
2079:                                            .isEmpty()
2080:                                            && sessionInfo.getAutoDelete()) {
2081:                                        loggingInterface
2082:                                                .debugMsg(
2083:                                                        loggingInterface.DEBUG,
2084:                                                        loggingInterface.SESSION,
2085:                                                        "Channel("
2086:                                                                + channelKey
2087:                                                                + ") in autoDelete Session("
2088:                                                                + sessionKey
2089:                                                                + ") is now empty, removing it...");
2090:                                        sessionInfo.getChannelTable().remove(
2091:                                                channelInfo.getKeyValue());
2092:                                        channelInfo.shutDown();
2093:                                        treeView.removeChannel(channelInfo);
2094:                                    }
2095:
2096:                                    // just to make double sure, tell the client to remove the function on it's end,
2097:                                    // just in case an error was detected on this server and not on the client end also.
2098:                                    if (this .commandStatusSocketHandlers
2099:                                            .containsKey(clientKey)) {
2100:                                        // find the command/status connection for this client
2101:                                        SocketAdapter ts = (SocketAdapter) commandStatusSocketHandlers
2102:                                                .get(clientKey);
2103:                                        if (ts != null) {
2104:                                            // create and send the disconnect command to the client for this session/channel/consumer
2105:                                            try {
2106:                                                DisconnectConsumer dc = new DisconnectConsumer(
2107:                                                        clientKey, sessionInfo
2108:                                                                .getName(),
2109:                                                        channelInfo.getName());
2110:                                                DataShareObject dso = new DataShareObject(
2111:                                                        SessionUtilities
2112:                                                                .convertObjectToByteArray(dc),
2113:                                                        DataShareObject.SENDTOALL,
2114:                                                        this .myClientKeyValue);
2115:                                                ts.sendData(dso); // use this client's commandStatusConnection
2116:                                            } catch (Exception e) {
2117:                                            }
2118:                                        }
2119:                                    }
2120:                                } else {
2121:                                    loggingInterface
2122:                                            .debugMsg(
2123:                                                    loggingInterface.DEBUG,
2124:                                                    loggingInterface.CLIENT,
2125:                                                    "removeConsumer("
2126:                                                            + clientKey
2127:                                                            + ") could not remove consumer because session/channel("
2128:                                                            + sessionKey
2129:                                                            + "/"
2130:                                                            + channelKey
2131:                                                            + ") had no such consumer!");
2132:                                }
2133:                            }
2134:                        }
2135:                    }
2136:                }
2137:            }
2138:
2139:            /**
2140:             * Used to create a Session that contains the Channels described by the CreateSessionRequest object.
2141:             */
2142:            public ClientSessionInfo
2143:   createSession(SocketAdapter ts, CreateSessionRequest csr)
2144:      {
2145:      loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2146:         "Creating Session " + csr.sessionName);
2147:
2148:      boolean validClient = false;
2149:      String clientName = "";  // this is the client userName (chuck), not the unique name (chuck-2), so they can go back later and delete the session no matter how they log-in
2150:      String clientKeyValue = ts.getClientKey();
2151:      InetAddress clientAddress = ts.getRemoteIP(); // address of client
2152:      ClientSessionInfo clientSessionInfo = null;
2153:      SessionInfo sessionInfo = null;
2154:      boolean foundSession = false;
2155:
2156:      // make sure clientKey has registered and is calling from same machine...
2157:      ClientInfo clientInfo = (ClientInfo)specialClientTable.get(clientKeyValue.toLowerCase());
2158:
2159:      if(clientInfo != null)
2160:         {
2161:         InetAddress clientInet = clientInfo.getHostMachine();
2162:         clientName = clientInfo.getName();
2163:
2164:         // check to see if the IP address client registered from is the one sending this request...
2165:         if(clientInet.getHostAddress().equals(ts.getRemoteIP().getHostAddress()))
2166:            validClient = true;
2167:         else
2168:            loggingInterface.debugMsg(loggingInterface.WARNING,loggingInterface.GENERALSTATUS,
2169:               "createSession() aborting: client on different IP, was ("+clientInet.getHostAddress()+"), now ("+ts.getRemoteIP().getHostAddress()+")");
2170:         }
2171:      else
2172:         loggingInterface.debugMsg(loggingInterface.WARNING,loggingInterface.SESSION,
2173:            "createSession() will not create session, could not find the requesting client("+clientName+")!");
2174:
2175:      if(validClient)
2176:         {
2177:         loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.CLIENT,
2178:            "Client("+clientInfo.getName()+") is valid");
2179:         loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2180:            "Client("+clientInfo.getName()+") requested the following channels: ");
2181:         for(int x=0; x< csr.desiredChannels.channelDescriptions.length; x++)
2182:            loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2183:               "  - " + csr.desiredChannels.channelDescriptions[x].channelName);
2184:
2185:         if(csr.joinIfAlreadyExists) // then we should go look for a session like the csr session
2186:            {
2187:            // if we find a Session like the one to be created, save it in sessionInfo attribute
2188:
2189:            // create temporary SessionInfo like one we want to create
2190:            // except that it has no Channels!!!!!!
2191:            SessionInfo si = new SessionInfo(csr.sessionName,  // may need to check for unique session names here, i.e. check if we match -01, -02, etc.
2192:                                          csr.sessionDescription,
2193:                                          clientName,
2194:                                          clientInfo.getClientClass(),
2195:                                          persistData);
2196:            SessionInfo si2 = null;
2197:
2198:            // try to find a Session like the one we are asked to create...
2199:            // need to set sessionInfo to correct value and foundSession to true
2200:            for(Enumeration enum = getSessionTable().elements(); enum.hasMoreElements();)
2201:               {
2202:               si2 = (SessionInfo)enum.nextElement();
2203:               if(si2.isSubSet(si))  // see if si is subset of si2
2204:                  {
2205:                  sessionInfo = si2;
2206:                  foundSession = true;
2207:                  break;
2208:                  }
2209:               }
2210:            if(sessionInfo != null)
2211:               {
2212:               // now check that all channel names already exists, otherwise we will need to create the channel
2213:               for(int x=0; x< csr.desiredChannels.channelDescriptions.length; x++)
2214:                  {
2215:                  if(!sessionInfo.getChannelTable().containsKey(csr.desiredChannels.channelDescriptions[x].channelName))
2216:                     {
2217:                     loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2218:                        "creating missing channel: ");
2219:                     loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2220:                        "     channelName=" + csr.desiredChannels.channelDescriptions[x].channelName);
2221:                     ChannelInfo this Channel = createChannel(csr.desiredChannels.channelDescriptions[x],
2222:                                                       sessionInfo);
2223:                     sessionInfo.addChannel(this Channel);
2224:                     treeView.addChannel(this Channel);
2225:                     }
2226:                  }
2227:               }
2228:            }
2229:
2230:         if(sessionInfo == null)
2231:            {
2232:            loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2233:               "A new unique Session will be created...");
2234:            // ensure that Session name is unique...
2235:            // Session name MUST BE UNIQUE, we use it as a Key now
2236:            // save info about this session...
2237:            sessionInfo = new SessionInfo(getUniqueSessionName(csr.sessionName),
2238:                                          csr.sessionDescription,
2239:                                          clientName,
2240:                                          clientInfo.getClientClass(),
2241:                                          persistData);
2242:            //sessionInfo.saveData = allowArchiving;
2243:            sessionInfo.privateSession = csr.sessionIsPrivate;
2244:            if(csr.autoDelete)
2245:               sessionInfo.setAutoDelete();
2246:
2247:            if(persistData)
2248:               {
2249:               try{
2250:                  Hashtable props = new Hashtable();
2251:                  props.put("sessionName", sessionInfo.getName());
2252:                  props.put("userObject", sessionInfo);
2253:                  saveDataToDatabase("DSSession3Home", props, sessionInfo); // ADSKey will evenutally get into this SessionInfo
2254:                  //  delay here until Key is filled in...this is a blocking call
2255:                  loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.DATABASE,
2256:                     "waiting for session EJB to be returned for " + sessionInfo.getName());
2257:                  String key = sessionInfo.getDatabaseID();
2258:
2259:                  }
2260:               catch(Exception e)
2261:                  {
2262:                  loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.DATABASE,
2263:                     "Problems creating Session Bean for " + sessionInfo.getName());
2264:                  loggingInterface.logException(loggingInterface.ERROR, e);
2265:                  }
2266:               }
2267:
2268:            sessionTable.put(sessionInfo.getKeyValue(),sessionInfo);
2269:            // tell clients about new session...
2270:            treeView.addSession(sessionInfo);
2271:
2272:            for(int x=0; x<csr.desiredChannels.channelDescriptions.length; x++)
2273:               {
2274:               loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2275:                  "creating channel: ");
2276:               loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2277:                  "     channelName=" + csr.desiredChannels.channelDescriptions[x].channelName);
2278:
2279:               ChannelInfo this Channel = createChannel(csr.desiredChannels.channelDescriptions[x],
2280:                                                       sessionInfo);
2281:               sessionInfo.addChannel(this Channel);
2282:               treeView.addChannel(this Channel);
2283:               }
2284:            }
2285:
2286:         // create object to send to requesting client
2287:         clientSessionInfo = new ClientSessionInfo(sessionInfo.getName(),
2288:                                                   sessionInfo.getSessionDescription(),
2289:                                                   sessionInfo.getKeyValue(),
2290:                                                   sessionInfo.getChannelConnectionDescriptors(),
2291:                                                   !foundSession, sessionInfo.getPrivate()); // new session, private type
2292:         }
2293:      else
2294:         {
2295:         loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
2296:            "Client "+clientName+" is not valid, not creating session " +  csr.sessionName);
2297:         }
2298:
2299:      return clientSessionInfo;
2300:      }
2301:
2302:            /**
2303:             * Creates the DataReceiverAdapter for this channel, so the Channel is fully up and working
2304:             * when this method returns.  We don't need to call TreeView here because it is assumed
2305:             * that this method is part of a createSession call and that the createSession call will
2306:             * take care of updating the TreeView.  If we later need a reference to the DataReceiverAdapter,
2307:             * we can use the ChannelInfo to get it.
2308:             */
2309:            private ChannelInfo createChannel(ChannelDescription cd,
2310:                    SessionInfo sessionInfo, boolean saveTheData) {
2311:                ChannelInfo channelInfo = null;
2312:                DataShareConnectionDescriptor dscd = null;
2313:
2314:                // dra won't have serverThread entry yet...
2315:                DataReceiverAdapter dra = new DataReceiverAdapter(this );
2316:                allDataReceiverAdapters.add(dra);
2317:
2318:                switch (cd.type) {
2319:                case ChannelDescription.TCP:
2320:                    // make receiving Threads a higher priority
2321:                    TcpSocketServer serverThread = new TcpSocketServer(dra,
2322:                            getNextPort(),
2323:                            SessionUtilities.SocketRcvDataPriority);
2324:                    dra.setSocketServer((SocketServerInterface) serverThread); // now dra has socket server
2325:                    dscd = new DataShareConnectionDescriptor(sessionInfo
2326:                            .getName(), cd, this .myIPAddress, serverThread
2327:                            .getLocalPort());
2328:                    serverThread.start();
2329:                    while (!serverThread.getReady()) {
2330:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2331:                                loggingInterface.NETWORK,
2332:                                "waiting for network connection to be available for session "
2333:                                        + sessionInfo.getName() + "...");
2334:                        SessionUtilities.delay(100);
2335:                    }
2336:                    break;
2337:                case ChannelDescription.UDP:
2338:                    UdpSocketServer serverThread2 = new UdpSocketServer(
2339:                            myIPAddress, (DataReceiverInterface) dra,
2340:                            getNextPort(),
2341:                            SessionUtilities.SocketRcvDataPriority);
2342:                    dra.setSocketServer(serverThread2); // now dra has socket server
2343:                    dscd = new DataShareConnectionDescriptor(sessionInfo
2344:                            .getName(), cd, this .myIPAddress, serverThread2
2345:                            .getLocalPort());
2346:                    serverThread2.start();
2347:                    while (!serverThread2.getReady()) {
2348:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2349:                                loggingInterface.NETWORK,
2350:                                "waiting for network connection to be available for session "
2351:                                        + sessionInfo.getName() + "...");
2352:                        SessionUtilities.delay(100);
2353:                    }
2354:                    break;
2355:                case ChannelDescription.MULTICAST:
2356:                    MulticastSocketServer serverThread3 = new MulticastSocketServer(
2357:                            getMulticastIPAddress(),
2358:                            (DataReceiverInterface) dra, getNextPort(),
2359:                            SessionUtilities.SocketRcvDataPriority);
2360:                    dra.setSocketServer(serverThread3); // now dra has socket server
2361:                    dscd = new DataShareConnectionDescriptor(sessionInfo
2362:                            .getName(), cd, getMulticastIPAddress(),
2363:                            serverThread3.getLocalPort());
2364:                    serverThread3.start();
2365:                    while (!serverThread3.getReady()) {
2366:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2367:                                loggingInterface.NETWORK,
2368:                                "waiting for network connection to be available for session "
2369:                                        + sessionInfo.getName() + "...");
2370:                        SessionUtilities.delay(100);
2371:                    }
2372:                    break;
2373:                }
2374:
2375:                channelInfo = new ChannelInfo(dscd, dra, sessionInfo,
2376:                        saveTheData);
2377:                dra.setChannelInfo(channelInfo);
2378:                dra.setSessionInfo(sessionInfo);
2379:
2380:                // create an EJB for this Channel (if we are using Beans)
2381:                if (saveTheData && sessionInfo.saveData) {
2382:                    try {
2383:                        Hashtable props = new Hashtable();
2384:                        props.put("sessionKey", sessionInfo.getDatabaseID()); // was ADSKey
2385:                        props.put("channelName", channelInfo
2386:                                .getConnectionDescriptor().name);
2387:                        props.put("userObject", channelInfo);
2388:                        saveDataToDatabase("DSChannel3Home", props, channelInfo);
2389:                        // wait for EJB to be created...this will block!
2390:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2391:                                loggingInterface.DATABASE,
2392:                                "waiting for channel EJB to be returned for Session/Channel ("
2393:                                        + sessionInfo.getName() + "/"
2394:                                        + channelInfo.getName() + ")");
2395:                        String key = channelInfo.getDatabaseID();
2396:                        dscd.databaseID = key;
2397:                    } catch (Exception e) {
2398:                        loggingInterface.debugMsg(loggingInterface.ERROR,
2399:                                loggingInterface.NETWORK,
2400:                                "Problems creating Channel Bean for Session/Channel ("
2401:                                        + sessionInfo.getName() + "/"
2402:                                        + channelInfo.getName() + ")");
2403:                        loggingInterface
2404:                                .logException(loggingInterface.ERROR, e);
2405:                    }
2406:                }
2407:
2408:                return channelInfo;
2409:            }
2410:
2411:            /**
2412:             * Creates the DataReceiverAdapter for this channel, so Channel is full up and working
2413:             * when this method returns.  We don't need to call TreeView here because it is assumed
2414:             * that this method is part of a createSession call and that the createSession call will
2415:             * take care of updating the TreeView.  If we later need a reference to the DataReceiverAdapter,
2416:             * we can use the ChannelInfo to get it.
2417:             */
2418:            private ChannelInfo createChannel(ChannelDescription cd,
2419:                    SessionInfo sessionInfo) {
2420:                return createChannel(cd, sessionInfo, persistData);
2421:            }
2422:
2423:            /**
2424:             * Used to retrieve a Multicast IP address, we arbitrarily just pick one
2425:             */
2426:            private InetAddress getMulticastIPAddress() {
2427:                InetAddress multicastIP = null;
2428:                try {
2429:                    multicastIP = InetAddress.getByName(multiCastIPaddress);
2430:                    if (!multicastIP.isMulticastAddress())
2431:                        loggingInterface.debugMsg(loggingInterface.ERROR,
2432:                                loggingInterface.NETWORK,
2433:                                "Problems -> not a valid multicast IP -> "
2434:                                        + multiCastIPaddress);
2435:                } catch (Exception e) {
2436:                    loggingInterface.debugMsg(loggingInterface.ERROR,
2437:                            loggingInterface.NETWORK,
2438:                            "Problems getting our multicastIP ("
2439:                                    + multiCastIPaddress + ") by name...");
2440:                    loggingInterface.logException(loggingInterface.ERROR, e);
2441:                }
2442:                return multicastIP;
2443:            }
2444:
2445:            /**
2446:             * Creates the DataReceiverAdapter for this channel, so Channel is full up and working
2447:             * when this method returns.  This method is called when a new channel is to be added to
2448:             * a Session that already exists.  NOT IMPLEMENTED YET
2449:             */
2450:            private ChannelInfo addNewChannel(ChannelDescription cd,
2451:                    SessionInfo sessionInfo) {
2452:                return (ChannelInfo) null;
2453:            }
2454:
2455:            /**
2456:             * used to provide the next port number to use for a Channel connection.  Currently, no distinction
2457:             * is made between a UDP and a TCP connection (we could have UDP and TCP use the same port for
2458:             * different sockets).
2459:             */
2460:            public synchronized int getNextPort() {
2461:                if (++currentPort > lastPort) {
2462:                    loggingInterface
2463:                            .debugMsg(
2464:                                    loggingInterface.WARNING,
2465:                                    loggingInterface.NETWORK,
2466:                                    "All Session Ports used once - You may require multiple Sessions on a port, or more ports allocated...\n"
2467:                                            + "<<<<<*>>>>>Trying to wrap around and re-use ports...");
2468:                    currentPort = firstPort;
2469:                }
2470:                return currentPort;
2471:            }
2472:
2473:            /**
2474:             * Takes a name as a parameter and returns a version of the name that is guaranteed
2475:             * to be unique in our list of Clients.  If the name is not already in our
2476:             * list, it is simply returned.  If the name is already in the Client list,
2477:             * it is modified slightly to make it unique.
2478:             *
2479:             * @param name the client name to be used as the basis for creating a
2480:             *     unique name
2481:             */
2482:            private synchronized String getUniqueName(String name) {
2483:                boolean finished = false;
2484:                String newName = name;
2485:                int counter = 2;
2486:                loggingInterface.debugMsg(loggingInterface.DEBUG,
2487:                        loggingInterface.CLIENT, "getUniqueName() called for "
2488:                                + name);
2489:                while (!finished) {
2490:                    if (specialClientTable.containsKey(newName.toLowerCase())) {
2491:                        newName = name + "-" + counter++;
2492:                    } else {
2493:                        finished = true; // name is unique
2494:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2495:                                loggingInterface.CLIENT,
2496:                                "getUniqueName(): returning-> " + newName);
2497:                    }
2498:                }
2499:                return newName;
2500:            }
2501:
2502:            /**
2503:             * Takes a name as a parameter and returns a version of the name that is guaranteed
2504:             * to be unique in our list of Sessions.  If the name is not already in our
2505:             * list, it is simply returned.  If the name is already in the Session list,
2506:             * it is modified slightly to make it unique.
2507:             *
2508:             * @param name the Session name to be used as the basis for creating a
2509:             *     unique name
2510:             */
2511:            private synchronized String getUniqueSessionName(String name) {
2512:                boolean finished = false;
2513:                String newName = name;
2514:                int counter = 2;
2515:                loggingInterface.debugMsg(loggingInterface.DEBUG,
2516:                        loggingInterface.SESSION,
2517:                        "getUniqueSessionName() called for " + name);
2518:                while (!finished) {
2519:                    if (sessionTable != null
2520:                            && sessionTable.containsKey(newName)) {
2521:                        // try another name
2522:                        newName = name + "-" + counter++;
2523:                    } else {
2524:                        finished = true; // no Sessions to look at
2525:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2526:                                loggingInterface.SESSION,
2527:                                "getUniqueSessionName() returning " + newName);
2528:                    }
2529:                }
2530:                return newName;
2531:            }
2532:
2533:            /**
2534:             * @param clientKey keyValue of client to be checked for Admin privileges
2535:             * @return true if client has Admin privileges, false otherwise
2536:             */
2537:            public boolean isClientAdmin(String clientKey) {
2538:                boolean retValue = false;
2539:                // find ClientInfo for this client...
2540:                if (specialClientTable.containsKey(clientKey.toLowerCase())) {
2541:                    ClientInfo ci = (ClientInfo) specialClientTable
2542:                            .get(clientKey.toLowerCase());
2543:                    retValue = ci.getAdmin();
2544:                } else {
2545:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
2546:                            loggingInterface.CLIENT,
2547:                            "isClientAdmin() could not find client -> "
2548:                                    + clientKey);
2549:                }
2550:                return retValue;
2551:            }
2552:
2553:            /**
2554:             * Used to determine if this server instance supports persisting data
2555:             *
2556:             * @return true if server supports persisting data, false otherwise
2557:             */
2558:            public boolean getPersistData() {
2559:                return persistData;
2560:            }
2561:
2562:            /**
2563:             * returns reference to persistence interface, should be non-null if getPersistData() returns true,
2564:             * may be null otherwise
2565:             */
2566:            public PersistenceInterface getPersistenceInterface() {
2567:                return this .persistenceInterface;
2568:            }
2569:
2570:            /**
2571:             * Returns true if this client is in the list of clients who have registered, false otherwise
2572:             */
2573:            public boolean isClientRegistered(String clientKey) {
2574:                boolean retValue = false;
2575:                if (specialClientTable.containsKey(clientKey.toLowerCase()))
2576:                    retValue = true;
2577:                return retValue;
2578:            }
2579:
2580:            /**
2581:             * Returns the ClientInfo for this client is this client is found in specialClients table,
2582:             * or null if not found
2583:             */
2584:            public ClientInfo getClientInfo(String clientKey) {
2585:                ClientInfo retValue = null;
2586:                if (specialClientTable.containsKey(clientKey.toLowerCase()))
2587:                    retValue = (ClientInfo) specialClientTable.get(clientKey
2588:                            .toLowerCase());
2589:                return retValue;
2590:            }
2591:
2592:            /**
2593:             * This method saveds the specified data to the database and puts the data's key value into the
2594:             * PersistDataCallbackInterface instance after the data is created.
2595:             *
2596:             * @param tableName the name of the table this data should be added to
2597:             * @param props describes what is to be persisted in the database
2598:             * @param callback the interface that supplies the methods used to set the Key for this data
2599:             */
2600:            public void saveDataToDatabase(String tableName, Hashtable props,
2601:                    PersistDataCallbackInterface callback) {
2602:                loggingInterface.debugMsg(loggingInterface.DEBUG,
2603:                        loggingInterface.DATABASE,
2604:                        "--saveDataToDatabase(): queueing " + tableName
2605:                                + " EJB");
2606:                persistDataQueue.write(new PersistDataQueueObject(tableName,
2607:                        props, callback));
2608:            }
2609:
2610:            /**
2611:             * called from the Fifo thread when data is available in the FIFO. Data was put into
2612:             * the FIFO by the persistDataQueue.write() method. This is called when the Fifo thread has
2613:             * finished with waiting for the previous database key to be created?
2614:             */
2615:            public void newFifoDataAvailable(Object obj) {
2616:                //ADSKey ak = null;
2617:                PersistDataQueueObject myObject = (PersistDataQueueObject) obj;
2618:                if (myObject != null) {
2619:                    if (myObject.getCallback() != null)
2620:                        myObject.getCallback().setWaitingForKey(true);
2621:
2622:                    //ADSObject ao = EjbUtil.create(myObject.tableName, myObject.getProperties());
2623:                    String newKeyString = persistenceInterface.save(myObject
2624:                            .getTableName(), myObject.getProperties());
2625:
2626:                    if (newKeyString != null) {
2627:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
2628:                                loggingInterface.DATABASE, "--data created: "
2629:                                        + myObject.getTableName() + "."
2630:                                        + newKeyString);
2631:                        if (myObject.getCallback() != null)
2632:                            myObject.getCallback().setDatabaseID(newKeyString); // save a way to get the EJB again
2633:                    } else
2634:                        loggingInterface.debugMsg(loggingInterface.WARNING,
2635:                                loggingInterface.DATABASE,
2636:                                "problems creating data, save did not return key value for "
2637:                                        + myObject.getTableName());
2638:                }
2639:            }
2640:
2641:            /**
2642:             * returns the table of clients
2643:             */
2644:            public Hashtable getSpecialClientTable() {
2645:                return this .specialClientTable;
2646:            }
2647:
2648:            /**
2649:             * returns the table of sessions
2650:             */
2651:            public Hashtable getSessionTable() {
2652:                return this .sessionTable;
2653:            }
2654:
2655:            /**
2656:             * returns the ChannelInfo specified by the supplied ADSKey String
2657:             */
2658:            private ChannelInfo getChannelInfo(String channelDatabaseID) {
2659:                ChannelInfo retValue = null;
2660:                if (this .persistData) {
2661:                    boolean found = false;
2662:                    for (Enumeration sessionsEnum = sessionTable.elements(); sessionsEnum
2663:                            .hasMoreElements()
2664:                            && !found;) {
2665:                        SessionInfo si = (SessionInfo) sessionsEnum
2666:                                .nextElement();
2667:                        Hashtable channelTable = si.getChannelTable();
2668:                        for (Enumeration channelsEnum = channelTable.elements(); channelsEnum
2669:                                .hasMoreElements();) {
2670:                            ChannelInfo ci = (ChannelInfo) channelsEnum
2671:                                    .nextElement();
2672:                            if (ci.getDatabaseID().equals(channelDatabaseID)) {
2673:                                retValue = ci;
2674:                                found = true; // causes us to exit outer loop
2675:                                break; // causes us to exit inner loop, we are done
2676:                            }
2677:                        }
2678:                    }
2679:                } else
2680:                    loggingInterface
2681:                            .debugMsg(loggingInterface.WARNING,
2682:                                    loggingInterface.DATABASE,
2683:                                    " *** cannot call getChannelInfo(databaseID) method when not saving data!!");
2684:                return retValue;
2685:            }
2686:
2687:            /// the token scheme may need synchronized tables because these methods are called from
2688:            /// many different threads (Hashtables are thread safe, right?)
2689:
2690:            /**
2691:             * TokenReqest objects indexed by tokenKey
2692:             */
2693:            Hashtable tokens = new Hashtable();
2694:
2695:            /**
2696:             * if a client has to wait for a token, their request goes into this item.
2697:             * want to use linked list so we can better manage taking items out of the
2698:             * middle and append to the end.
2699:             */
2700:            List waitingForTokens = Collections
2701:                    .synchronizedList(new LinkedList());
2702:
2703:            /**
2704:             * this is called whenever we receive a TokenRequestObject from a Client, this
2705:             * method will take care of managing the Tokens for each Channel.
2706:             * @param tro the Request
2707:             * @param ts the client's commandStatusConnection SocketAdapter
2708:             */
2709:            private synchronized void tokenRequestReceived(
2710:                    TokenRequestObject tro, SocketAdapter ts) {
2711:                DataShareObject dso = null;
2712:                try {
2713:                    loggingInterface
2714:                            .debugMsg(
2715:                                    loggingInterface.DEBUG,
2716:                                    loggingInterface.CLIENT,
2717:                                    "Client "
2718:                                            + ts.getClientKey()
2719:                                            + " sent Token "
2720:                                            + tro.tokenKey
2721:                                            + " with value of "
2722:                                            + TokenRequestObject.typeOfRequestStrings[tro.typeOfRequest]);
2723:
2724:                    switch (tro.typeOfRequest) {
2725:                    case TokenRequestObject.REQUEST:
2726:                        // determine if the client is active in the channel...only for REQUESTs
2727:                        SessionInfo si = (SessionInfo) sessionTable
2728:                                .get(tro.sessionName); // sessionName is also key for sessionTable
2729:                        SocketAdapter sa = null;
2730:                        if (si != null) {
2731:                            ChannelInfo ci = (ChannelInfo) si.getChannelTable()
2732:                                    .get(tro.channelName);
2733:                            if (ci != null) {
2734:                                ConsumerInfo consumerInfo = (ConsumerInfo) ci
2735:                                        .getConsumerTable().get(
2736:                                                ts.getClientKey());
2737:                                if (consumerInfo != null) {
2738:                                    DataReceiverAdapter dra = ci
2739:                                            .getDataReceiverAdapter();
2740:                                    sa = dra.findConsumerSocket(consumerInfo);
2741:                                } else {
2742:                                    loggingInterface.debugMsg(
2743:                                            loggingInterface.WARNING,
2744:                                            loggingInterface.CLIENT,
2745:                                            "RequestToken could not find consumer ("
2746:                                                    + ts.getClientKey()
2747:                                                    + ") to send token to");
2748:                                }
2749:                            } else {
2750:                                loggingInterface.debugMsg(
2751:                                        loggingInterface.WARNING,
2752:                                        loggingInterface.CLIENT,
2753:                                        "RequestToken could not find channel ("
2754:                                                + tro.channelName
2755:                                                + ") for client ("
2756:                                                + ts.getClientKey() + ")");
2757:                            }
2758:                        } else {
2759:                            loggingInterface.debugMsg(loggingInterface.WARNING,
2760:                                    loggingInterface.CLIENT,
2761:                                    "RequestToken could not find session ("
2762:                                            + tro.sessionName
2763:                                            + ") for client ("
2764:                                            + ts.getClientKey() + ")");
2765:                        }
2766:
2767:                        if (sa != null && sa.getActive()) {
2768:                            if (tokens.containsKey(tro.tokenKey)) {
2769:                                //  a client already has the token
2770:                                TokenRequest tr = (TokenRequest) tokens
2771:                                        .get(tro.tokenKey);
2772:                                loggingInterface.debugMsg(
2773:                                        loggingInterface.DEBUG,
2774:                                        loggingInterface.CLIENT, "Client "
2775:                                                + tr.clientKeyValue
2776:                                                + " already has Token "
2777:                                                + tro.tokenKey);
2778:                                // check to see if same client is requesting it again
2779:                                if (ts.getClientKey().equals(tr.clientKeyValue)) {
2780:                                    loggingInterface.debugMsg(
2781:                                            loggingInterface.DEBUG,
2782:                                            loggingInterface.CLIENT, "Client ("
2783:                                                    + ts.getClientKey()
2784:                                                    + ") is requesting Token ("
2785:                                                    + tro.tokenKey + ") again");
2786:                                } else // a client has the Token, and it is not requesting client
2787:                                {
2788:                                    // check to see if current client has had Token too long
2789:                                    if (tr.expireDate.before(new Date())) {
2790:                                        // we have passed the expire date, REVOKE it from one client and GRANT it to the requestor
2791:                                        loggingInterface
2792:                                                .debugMsg(
2793:                                                        loggingInterface.DEBUG,
2794:                                                        loggingInterface.CLIENT,
2795:                                                        "Token ("
2796:                                                                + tro.tokenKey
2797:                                                                + ") has been held by Client ("
2798:                                                                + tr.clientKeyValue
2799:                                                                + ") too long, Revoking it");
2800:                                        // issue REVOKE
2801:                                        dso = new DataShareObject(
2802:                                                SessionUtilities
2803:                                                        .convertObjectToByteArray(new TokenRequestObject(
2804:                                                                TokenRequestObject.REVOKE,
2805:                                                                tro.tokenKey)),
2806:                                                tr.ts.getType(),
2807:                                                tr.clientKeyValue);
2808:                                        tr.ts.sendData(dso);
2809:                                        tokens.remove(tro.tokenKey); // remove the current Token holder
2810:                                        loggingInterface.debugMsg(
2811:                                                loggingInterface.DEBUG,
2812:                                                loggingInterface.CLIENT,
2813:                                                "Granting Token "
2814:                                                        + tro.tokenKey
2815:                                                        + " to Client "
2816:                                                        + ts.getClientKey());
2817:                                        // issue GRANT
2818:                                        dso = new DataShareObject(
2819:                                                SessionUtilities
2820:                                                        .convertObjectToByteArray(new TokenRequestObject(
2821:                                                                TokenRequestObject.GRANT,
2822:                                                                tro.tokenKey)),
2823:                                                ts.getType(), ts.getClientKey());
2824:                                        ts.sendData(dso);
2825:                                        // save info about who we are giving the token to...
2826:                                        tokens.put(tro.tokenKey,
2827:                                                new TokenRequest(ts
2828:                                                        .getClientKey(), ts,
2829:                                                        tro.tokenKey));
2830:                                    } else // requesting client has to wait for current client to give up Token...
2831:                                    {
2832:                                        // make sure they are not already waiting...
2833:                                        int index = this 
2834:                                                .findWaitingRequest(
2835:                                                        tro.tokenKey, ts
2836:                                                                .getClientKey());
2837:                                        if (index >= 0) // if already waiting, update timer then put client back into waiting
2838:                                        {
2839:                                            loggingInterface
2840:                                                    .debugMsg(
2841:                                                            loggingInterface.DEBUG,
2842:                                                            loggingInterface.CLIENT,
2843:                                                            "Client "
2844:                                                                    + ts
2845:                                                                            .getClientKey()
2846:                                                                    + " was already waiting for Token "
2847:                                                                    + tro.tokenKey
2848:                                                                    + ", removing first instance...");
2849:                                            waitingForTokens.remove(index);
2850:                                        }
2851:                                        loggingInterface
2852:                                                .debugMsg(
2853:                                                        loggingInterface.DEBUG,
2854:                                                        loggingInterface.CLIENT,
2855:                                                        "Client "
2856:                                                                + ts
2857:                                                                        .getClientKey()
2858:                                                                + " will have to wait for Token "
2859:                                                                + tro.tokenKey
2860:                                                                + " add them to waiting list");
2861:                                        waitingForTokens.add(new TokenRequest(
2862:                                                ts.getClientKey(), ts,
2863:                                                tro.tokenKey));
2864:                                    }
2865:                                }
2866:                            } else {
2867:                                //  no client already has the token
2868:                                // save info about who we are giving the token to...
2869:                                loggingInterface.debugMsg(
2870:                                        loggingInterface.DEBUG,
2871:                                        loggingInterface.CLIENT,
2872:                                        "No client has Token " + tro.tokenKey
2873:                                                + ", so issuing it to "
2874:                                                + ts.getClientKey());
2875:                                tokens.put(tro.tokenKey, new TokenRequest(ts
2876:                                        .getClientKey(), ts, tro.tokenKey));
2877:                                dso = new DataShareObject(
2878:                                        SessionUtilities
2879:                                                .convertObjectToByteArray(new TokenRequestObject(
2880:                                                        TokenRequestObject.GRANT,
2881:                                                        tro.tokenKey)), ts
2882:                                                .getType(), ts.getClientKey());
2883:                                ts.sendData(dso);
2884:                            }
2885:                        } else
2886:                            loggingInterface
2887:                                    .debugMsg(loggingInterface.WARNING,
2888:                                            loggingInterface.CLIENT,
2889:                                            "Igonoring TokenRequest from Consumer whose socket is not active");
2890:                        break;
2891:                    case TokenRequestObject.CANCEL:
2892:                        // cannot assume that cancel came from client that had it!
2893:                        TokenRequest currentHolder = (TokenRequest) tokens
2894:                                .get(tro.tokenKey);
2895:                        if (currentHolder != null) {
2896:                            // test to see if CANCEL came from currentHolder...
2897:                            if (ts.getClientKey().equals(
2898:                                    currentHolder.clientKeyValue)) {
2899:                                loggingInterface.debugMsg(
2900:                                        loggingInterface.DEBUG,
2901:                                        loggingInterface.CLIENT, "Client "
2902:                                                + ts.getClientKey()
2903:                                                + " has released Token "
2904:                                                + tro.tokenKey);
2905:                                tokens.remove(tro.tokenKey); //  if a client already has the token, remove it
2906:                                // see if anybody is waiting for the Token...
2907:                                int index = this 
2908:                                        .findWaitingRequest(tro.tokenKey);
2909:                                if (index >= 0) // if a Client is waiting, give it to them
2910:                                {
2911:                                    TokenRequest tr = (TokenRequest) waitingForTokens
2912:                                            .remove(index);
2913:                                    loggingInterface.debugMsg(
2914:                                            loggingInterface.DEBUG,
2915:                                            loggingInterface.CLIENT, "Client "
2916:                                                    + tr.ts.getClientKey()
2917:                                                    + " was waiting for Token "
2918:                                                    + tro.tokenKey
2919:                                                    + ", Grant them the Token");
2920:                                    // issue GRANT
2921:                                    dso = new DataShareObject(
2922:                                            SessionUtilities
2923:                                                    .convertObjectToByteArray(new TokenRequestObject(
2924:                                                            TokenRequestObject.GRANT,
2925:                                                            tro.tokenKey)),
2926:                                            tr.ts.getType(), tr.ts
2927:                                                    .getClientKey());
2928:                                    tr.ts.sendData(dso);
2929:                                    // save info about who we are giving the token to...
2930:                                    tokens.put(tro.tokenKey, new TokenRequest(
2931:                                            tr.ts.getClientKey(), tr.ts,
2932:                                            tro.tokenKey));
2933:                                } else {
2934:                                    loggingInterface.debugMsg(
2935:                                            loggingInterface.DEBUG,
2936:                                            loggingInterface.CLIENT,
2937:                                            "No client was waiting for Token "
2938:                                                    + tro.tokenKey);
2939:                                }
2940:                            } else {
2941:                                loggingInterface
2942:                                        .debugMsg(
2943:                                                loggingInterface.DEBUG,
2944:                                                loggingInterface.CLIENT,
2945:                                                "Client "
2946:                                                        + ts.getClientKey()
2947:                                                        + " Canceled Token "
2948:                                                        + tro.tokenKey
2949:                                                        + ", is not the current Holder...");
2950:                                int index = this .findWaitingRequest(
2951:                                        tro.tokenKey, ts.getClientKey());
2952:                                if (index >= 0) // if waiting, remove client from waiting
2953:                                {
2954:                                    loggingInterface
2955:                                            .debugMsg(
2956:                                                    loggingInterface.DEBUG,
2957:                                                    loggingInterface.CLIENT,
2958:                                                    "Client "
2959:                                                            + ts.getClientKey()
2960:                                                            + " was waiting for Token "
2961:                                                            + tro.tokenKey
2962:                                                            + ", removed from waiting list");
2963:                                    waitingForTokens.remove(index);
2964:                                }
2965:                            }
2966:                        } else {
2967:                            loggingInterface.debugMsg(loggingInterface.DEBUG,
2968:                                    loggingInterface.CLIENT,
2969:                                    "No client was Granted Token "
2970:                                            + tro.tokenKey
2971:                                            + ", but we received a Cancel!!");
2972:                        }
2973:                        break;
2974:                    default:
2975:                        loggingInterface.debugMsg(loggingInterface.WARNING,
2976:                                loggingInterface.CLIENT,
2977:                                "Received incorrect typeOfRequest: "
2978:                                        + tro.typeOfRequest);
2979:                    } // end of switch
2980:                } // end of try
2981:                catch (Exception e) {
2982:                    loggingInterface.debugMsg(loggingInterface.ERROR,
2983:                            loggingInterface.CLIENT,
2984:                            "Problems in TokenRequestReceived():");
2985:                    loggingInterface.logException(LoggingInterface.ERROR, e);
2986:                }
2987:            }
2988:
2989:            /**
2990:             * looks for the specified token request in our list of waiting clients, returns
2991:             * the index into waitingForTokens if found, -1 otherwise.  This should only be
2992:             * called from the synchronized method tokenRequestReceived.
2993:             */
2994:            private int findWaitingRequest(String tokenKey) {
2995:                loggingInterface.debugMsg(loggingInterface.DEBUG,
2996:                        loggingInterface.CLIENT,
2997:                        "Is a client waiting for Token " + tokenKey + "?");
2998:
2999:                int retValue = -1;
3000:                for (int x = 0; x < waitingForTokens.size(); x++) {
3001:                    TokenRequest tr = (TokenRequest) waitingForTokens.get(x);
3002:                    loggingInterface.debugMsg(loggingInterface.DEBUG,
3003:                            loggingInterface.CLIENT, "Found client "
3004:                                    + tr.clientKeyValue + " waiting for Token "
3005:                                    + tr.tokenKey);
3006:                    if (tr.tokenKey.equals(tokenKey)) {
3007:                        // found this request!
3008:                        retValue = x;
3009:                        loggingInterface.debugMsg(loggingInterface.DEBUG,
3010:                                loggingInterface.CLIENT,
3011:                                "Found a client waiting for this Token!");
3012:                        break;
3013:                    }
3014:                }
3015:                return retValue;
3016:            }
3017:
3018:            /**
3019:             * looks for the specified token request in our list of waiting clients, returns
3020:             * the index into waitingForTokens if this client is found to be waiting for this Token,
3021:             * -1 otherwise.  This should only be called from the synchronized method tokenRequestReceived.
3022:             */
3023:            private int findWaitingRequest(String tokenKey,
3024:                    String clientKeyValue) {
3025:                int retValue = -1;
3026:                for (int x = 0; x < waitingForTokens.size(); x++) {
3027:                    TokenRequest tr = (TokenRequest) waitingForTokens.get(x);
3028:                    if (tr.clientKeyValue.equals(clientKeyValue)
3029:                            && tr.tokenKey.equals(tokenKey)) {
3030:                        // found this request!
3031:                        retValue = x;
3032:                        break;
3033:                    }
3034:                }
3035:                return retValue;
3036:            }
3037:
3038:            /**
3039:             * This method loads the ChannelDescription array that we use to tell the clients
3040:             * what functions they are allowed to use in Sessions.  We try to load
3041:             * our functions file name from a property in the normal system config file.
3042:             */
3043:            private void
3044:   getChannelDescriptionsFromConfigFile()
3045:      {
3046:      Vector channels = new Vector();
3047:      ChannelDescription cd = null;
3048:      ChannelDescription channelDescriptions[] = null;
3049:      try{
3050:         loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
3051:            "Retrieving our function descriptions from a file...");
3052:         String fn = channelTypesFile;  // value set by default or PropertiesManager
3053:         if(fn.length() == 0 || fn.equals(""))
3054:            loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
3055:               "No file specified for the channel descriptions, only BroadCastClients will work, not Rendezvous");
3056:         else
3057:            {
3058:            loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
3059:               "Trying to read channel description file " + fn );
3060:            FileReader fr = null;
3061:            try{
3062:               fr = new FileReader(fn);
3063:               }
3064:            catch(FileNotFoundException fnfe)
3065:               {
3066:               // see if the classloader can find it
3067:               fn = this .getClass().getClassLoader().getResource(fn).getFile();
3068:               if(fn == null)
3069:                  {
3070:                  loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
3071:                     "No file specified for channel descriptions");
3072:                  Enumeration enum = this .getClass().getClassLoader().getResources(fn);
3073:                  while(enum.hasMoreElements())
3074:                     loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,
3075:                        "Found resource " + enum.nextElement());
3076:                  }
3077:
3078:               // next line will generate an error and kick us out if we still cannot find the file
3079:               loggingInterface.debugMsg(loggingInterface.WARNING,loggingInterface.SESSION,
3080:                  "Now trying to read channel description file " + fn );
3081:               fr = new FileReader(fn);
3082:               }
3083:
3084:            BufferedReader din = new BufferedReader(fr);
3085:            String line;
3086:            int tokenCount =0;
3087:            while ((line=din.readLine())!= null)
3088:               {
3089:               try{
3090:                  // skip any lines that start with #
3091:                  if(!line.trim().startsWith("#"))
3092:                     {
3093:                     StringTokenizer st = new StringTokenizer(line, ";");
3094:                     tokenCount = st.countTokens();
3095:                     if (tokenCount < 10)  // must be at least 10 tokens or it is a comment line
3096:                        continue;
3097:                     // after here must be 10 or more
3098:                     String name             = st.nextToken().trim();  // name must be unique among all channels
3099:                     String className        = st.nextToken().trim();
3100:                     String description      = st.nextToken().trim();
3101:                     String connectionType   = st.nextToken().trim();
3102:                     String jarFile          = st.nextToken().trim();
3103:                     boolean allowPersistSelection = new Boolean( st.nextToken().toLowerCase().trim()).booleanValue();
3104:                     boolean persistPreSet         = new Boolean( st.nextToken().toLowerCase().trim()).booleanValue();
3105:                     boolean selectionPreSet       = new Boolean( st.nextToken().toLowerCase().trim()).booleanValue();
3106:                     int historyDelay              = Integer.parseInt(st.nextToken().trim());
3107:                     int historyCountInc           = Integer.parseInt(st.nextToken().trim());
3108:
3109:                     if(!persistData)
3110:                        allowPersistSelection = false;  // no more archiving!!!
3111:
3112:                     StringBuffer sb = new StringBuffer();
3113:                     sb.append("name-"+name+ "\n class-" + className + "\n description-" + description + "\n type-" + connectionType + "\n jar-" + jarFile +
3114:                               "\n allowHistory-" + allowPersistSelection + "\n persist-" + persistPreSet + "\n selection-" + selectionPreSet +
3115:                               "\n historyDelay-" + historyDelay + "\n historyCountIncrement-" + historyCountInc);
3116:
3117:                     if (tokenCount > 10)  // does this entry contain optional MIME information for archiving?
3118:                        {
3119:                        String mimeType      = st.nextToken().trim();
3120:                        String fileExtension = st.nextToken().trim();
3121:                        String mimeClassName = st.nextToken().trim();
3122:                        String setMethod     = st.nextToken().trim();
3123:                        String getMethod     = st.nextToken().trim();
3124:                        cd = new ChannelDescription(name,className,description,connectionType,jarFile,allowPersistSelection,persistPreSet,selectionPreSet,historyDelay,historyCountInc,
3125:                                                 mimeType,fileExtension,mimeClassName,setMethod,getMethod);
3126:                        sb.append(" mimeType-"+mimeType+ "\n extension-" + fileExtension + "\n className-" + mimeClassName + "\n set-" + setMethod + "\n get-" + getMethod);
3127:                        }
3128:                     else // must be == 10 (no archive support)
3129:                        {
3130:                        cd = new ChannelDescription(name,className,description,connectionType,jarFile,allowPersistSelection,persistPreSet,selectionPreSet,historyDelay,historyCountInc);
3131:                        }
3132:                     loggingInterface.debugMsg(loggingInterface.DEBUG,loggingInterface.SESSION,sb.toString());
3133:                     if(cd != null)
3134:                        {
3135:                        channels.add(cd);
3136:                        }
3137:                     }
3138:                  }
3139:               catch(Exception e)
3140:                  {
3141:                  loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
3142:                     "Problems reading channel config file...");
3143:                  loggingInterface.logException(LoggingInterface.ERROR, e);
3144:                  }
3145:               }  // end of while loop
3146:            din.close();
3147:
3148:            if(channels.size() > 0)
3149:               {
3150:               channelDescriptions = new ChannelDescription[channels.size()];
3151:               for(int x=0; x<channels.size(); x++)
3152:                  {
3153:                  channelDescriptions[x] = (ChannelDescription)channels.elementAt(x);
3154:                  }
3155:               // now save it
3156:               channelDescriptionArray = new ChannelDescriptionArray(channelDescriptions);
3157:               }
3158:            else
3159:               {               
3160:               loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
3161:                  "Could not find any Channel/Functions to send to clients!!");
3162:               //this.shutDownConnectionsAndThreads();
3163:               }
3164:            }
3165:         }
3166:       catch(Exception e)
3167:         {
3168:         loggingInterface.debugMsg(loggingInterface.ERROR,loggingInterface.SESSION,
3169:            "Problems trying to get functions/channel descriptions...");
3170:         loggingInterface.logException(LoggingInterface.ERROR, e); 
3171:         }
3172:      }
3173:
3174:            public String getServerInfo() {
3175:                return serverInfoString;
3176:            }
3177:
3178:            public boolean getShowArchivedSessionsToAdmin() {
3179:                return showArchivedSessionsToAdmin;
3180:            }
3181:
3182:        } // end of class
3183:
3184:        /********************/
3185:
3186:        class TokenRequest {
3187:            final static int expireTimeInSeconds = 30;
3188:            Date currentDate = new Date();
3189:            Date expireDate = null; // the time at which this client has held the Token too long
3190:            String clientKeyValue = null;
3191:            SocketAdapter ts = null;
3192:            String tokenKey = null;
3193:
3194:            /**
3195:             * constructor, used when we grant a Token, also provides a time value used to
3196:             * determine if a Client's use of the Token, or request of a Token should expire
3197:             * @param clientKeyValue the client that we are giving the Token to
3198:             * @param ts the commandStatusConnection for the client we are giving the Token to
3199:             */
3200:            TokenRequest(String clientKeyValue, SocketAdapter ts,
3201:                    String tokenKey) {
3202:                expireDate = new Date(currentDate.getTime()
3203:                        + expireTimeInSeconds * 1000);
3204:                this.clientKeyValue = clientKeyValue;
3205:                this.ts = ts;
3206:                this.tokenKey = tokenKey;
3207:            }
3208:
3209:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.