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: SessionUtilities.java,v 1.4 2002/02/04 13:51:40 lizellaman Exp $
0025: * $Log: SessionUtilities.java,v $
0026: * Revision 1.4 2002/02/04 13:51:40 lizellaman
0027: * Remove all references to past product names (or)
0028: * Add PublicAPI for creating Rendezvous Sessions
0029: *
0030: * Revision 1.3 2002/01/29 20:50:17 lizellaman
0031: * Added LoggingInterface, modified the PropertiesInterface implementation
0032: *
0033: * Revision 1.2 2002/01/20 23:26:29 lizellaman
0034: * add command line parameter that causes an plain DataShareObject to be sent to 'inactive' TCP connections after X milliseconds on inactivity
0035: *
0036: * Revision 1.1.1.1 2001/10/23 13:37:18 lizellaman
0037: * initial sourceforge release
0038: *
0039: */
0040:
0041: package org.datashare;
0042:
0043: import org.datashare.objects.DefaultObjectInfo;
0044: import org.datashare.objects.ServerInfo;
0045: import org.datashare.client.DataShareConnection;
0046: import org.datashare.plugins.LoggingManager.LoggingAdapter;
0047:
0048: import java.applet.Applet;
0049: import java.applet.AudioClip;
0050: import javax.swing.ImageIcon;
0051: import java.awt.Image;
0052: import java.awt.Frame;
0053: import java.awt.Point;
0054: import java.awt.Container;
0055: import java.awt.MediaTracker;
0056: import java.awt.event.AdjustmentListener;
0057: import java.awt.event.AdjustmentEvent;
0058: import java.util.Enumeration;
0059: import java.util.Hashtable;
0060: import java.util.Date;
0061: import java.util.Vector;
0062: import java.text.SimpleDateFormat;
0063: import javax.swing.tree.DefaultMutableTreeNode;
0064: import javax.swing.JTree;
0065: import javax.swing.JScrollPane;
0066: import javax.swing.event.TreeSelectionListener;
0067: import javax.swing.event.TreeSelectionEvent;
0068: import javax.swing.tree.TreeSelectionModel;
0069: import javax.swing.tree.DefaultTreeCellRenderer;
0070: import javax.swing.tree.DefaultTreeModel;
0071:
0072: import java.io.InputStream;
0073: import java.io.ByteArrayInputStream;
0074: import java.io.ObjectInputStream;
0075: import java.io.ByteArrayOutputStream;
0076: import java.io.ObjectOutputStream;
0077: import java.io.BufferedInputStream;
0078: import java.io.BufferedOutputStream;
0079: import java.io.IOException;
0080:
0081: import java.awt.Toolkit;
0082: import java.awt.Component;
0083: import java.net.URL;
0084: import java.net.MalformedURLException;
0085:
0086: /**
0087: * This is the repository for the methods that represent common activities for
0088: * Rendezvous. All methods/attributes in that class are static.
0089: *
0090: * @author Charles Wood
0091: * @version 1.0
0092: */
0093: public class SessionUtilities {
0094:
0095: static {
0096: setLoggingInterface(new LoggingAdapter());
0097: }
0098:
0099: public static int SocketRcvDataPriority = Thread.NORM_PRIORITY;
0100: public static int SocketRcvCmdPriority = Thread.NORM_PRIORITY + 1;
0101: public static int SocketXmtRelativePriority = 1; // xmit thread relative to rcv thread
0102:
0103: /**
0104: * server machine name/IP-address
0105: */
0106: private static String servername;
0107:
0108: /**
0109: * default location for HC images,
0110: * should be prepended to the image name prior to retrieval.
0111: */
0112: public static String imageRoot = "/org/rendezvous/images/";
0113:
0114: /**
0115: * this is where we save a reference to the image to use when we cannot find a user's image.
0116: * A URL was choosen because the image can then be loaded like all the other user images.
0117: */
0118: public static URL missingPersonURL;
0119:
0120: /**
0121: * server machine IP-address
0122: */
0123: private static String serverIP;
0124:
0125: /**
0126: * the userName for our user (who should have gone through a password acceptance)
0127: */
0128: private static String userName; // parameter name is userName
0129:
0130: /**
0131: * our user's full name
0132: */
0133: private static String userFullName; // parameter name is userFullName
0134:
0135: /**
0136: * the user's ID that enables us to find them in the system. Note, if this value
0137: * is set to null, the userName and userFullName will not be used.
0138: */
0139: private static int userID; // parameter name is userID
0140:
0141: /**
0142: * the user's Enterprise ID that is needed so we can find them in the system. Note
0143: * that if this value is set to null, the userName and userFullName will not be
0144: * used.
0145: */
0146: private static int enterpriseID; // parameter name is enterpriseID
0147:
0148: /**
0149: * set to the initial applet instance, may be null for applications
0150: */
0151: private static Applet ourApplet = null;
0152:
0153: /**
0154: * available for HC functions that need an externally supplied width value
0155: */
0156: private static int width; // set from width parameter at run time
0157:
0158: /**
0159: * available for HC functions that need an externally supplied height value
0160: */
0161: private static int height; // set from width parameter at run time
0162:
0163: /**
0164: * set to true if the instance was started as an application, false if started
0165: * as an applet. Should be set to true my the main() method.
0166: */
0167: private static boolean isApplication = false;
0168:
0169: /**
0170: * the command status connection for our client
0171: */
0172: private static DataShareConnection commandStatusConnection = null;
0173:
0174: /**
0175: * contains all the clients we have seen for this VM, for each client we have a
0176: * String that represents the client's imageURL indexed by the clientKey
0177: */
0178: private static Hashtable clientImages = new Hashtable();
0179:
0180: private static FifoQueue fifoQueue = new FifoQueue(); // used for JScrollPane scrollBar adjustment listener timer
0181:
0182: static Hashtable scrollPaneHashtable = new Hashtable();
0183:
0184: /**
0185: * indicates if we should use lots of System.out.print (when true), or fewer (when false)
0186: */
0187: private static boolean verbose = false;
0188:
0189: private static LoggingInterface logIF;
0190:
0191: /**
0192: * sets the logging interface that we will use instead of doing System.out calls. this
0193: * will provide more control over what actually gets to the console without having to
0194: * remove all the System.out calls.
0195: */
0196: public static void setLoggingInterface(
0197: LoggingInterface loggingInterface) {
0198: logIF = loggingInterface;
0199: }
0200:
0201: /**
0202: * returns the logging interface that we will use instead of doing System.out calls.
0203: */
0204: public static LoggingInterface getLoggingInterface() {
0205: return logIF;
0206: }
0207:
0208: /**
0209: * sets the timeout value in milliseconds for all TCP connections. This is used when we have
0210: * a DataShare server that is sitting behind a firewall/router that disconnects inactive connections.
0211: * Setting it to zero means connections do not timeout. If we use a non-zero value, a timeout will
0212: * cause the server to send a KEEPALIVE packet to the connection so it is no longer inactive. The
0213: * timeout value should be less than the time the firewall/router uses to determine that connections
0214: * are inactive (or you won't send the KEEPALIVE packet before you get disconnected by the firewall)
0215: */
0216: private static int TCPSocketReadTimeout = 0; // don't timeout is default;
0217:
0218: /**
0219: * accessor for TCPSocketReadTimeout
0220: *
0221: * @return current timeout value in milliseconds
0222: */
0223: public static int getTCPSocketReadTimeout() {
0224: return TCPSocketReadTimeout;
0225: }
0226:
0227: /**
0228: * sets the TCPSocketReadTimeout attribute
0229: *
0230: * @param newTimeoutValue set into TCPSocketReadTimeout
0231: */
0232: public static void setTCPSocketReadTimeout(int newTimeoutValue) {
0233: TCPSocketReadTimeout = newTimeoutValue;
0234: getLoggingInterface().debugMsg(
0235: getLoggingInterface().DEBUG,
0236: getLoggingInterface().NETWORK,
0237: "TCPSocketReadTimeout has been set to "
0238: + newTimeoutValue);
0239: }
0240:
0241: /**
0242: * accessor for the verbose flag
0243: *
0244: * @return false if user wants fewer console printouts, true otherwise
0245: */
0246: public static boolean getVerbose() {
0247: return verbose;
0248: }
0249:
0250: /**
0251: * sets the verbose attribute
0252: *
0253: * @param newValue set to true to select lots of details on the console, false otherwise
0254: */
0255: public static void setVerbose(boolean newValue) {
0256: verbose = newValue;
0257: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0258: getLoggingInterface().GENERALSTATUS,
0259: "System verbose mode has been set to " + newValue);
0260: }
0261:
0262: /**
0263: * accessor for the server machine name
0264: *
0265: * @return name for the server machine
0266: */
0267: public static String getServername() {
0268: return servername;
0269: }
0270:
0271: /**
0272: * Sets the server name; this should be used by the class that reads the
0273: * command line parameters (for applications) or the applet code to set this
0274: * value so that all other classes will be able to use getServername() when the
0275: * server name is needed.
0276: *
0277: * @param newServername the name or IP address of the server
0278: *
0279: */
0280: public static void setServername(String newServername) {
0281: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0282: getLoggingInterface().GENERALSTATUS,
0283: "Server name set to " + newServername);
0284: servername = newServername;
0285: }
0286:
0287: /**
0288: * Serializes an object on the client side, avoids the problem we had of trying to
0289: * send a true object through the server if the server did not have a classpath to the object.
0290: * This way, the server only has to know that it is a byte[]. Convert back to an object
0291: * via the retrieveObject() method.
0292: */
0293: public static byte[] convertObjectToByteArray(Object object)
0294: throws IOException {
0295: ByteArrayOutputStream baos = new ByteArrayOutputStream(5000); // automatically extends if needed
0296: ObjectOutputStream oos = new ObjectOutputStream(
0297: new BufferedOutputStream(baos));
0298: oos.flush();
0299: oos.writeObject(object);
0300: oos.flush();
0301: return baos.toByteArray();
0302: }
0303:
0304: /**
0305: * Converts a byte[] back to an object. This method should only be used on objects that were
0306: * previously converted to the byte[] by the convertObjectToByteArray() method.
0307: */
0308: public static Object retrieveObject(byte[] objectBytes)
0309: throws IOException, ClassNotFoundException {
0310: ByteArrayInputStream bais = new ByteArrayInputStream(
0311: objectBytes);
0312: ObjectInputStream ois = new ObjectInputStream(
0313: new BufferedInputStream(bais));
0314: return ois.readObject();
0315: }
0316:
0317: /**
0318: * utility method, allows the calling method to delay the specified number of milliseconds
0319: *
0320: * @param milliseconds number of milliseconds to delay
0321: */
0322: public static void delay(int milliseconds) {
0323: try {
0324: Thread.sleep(milliseconds);
0325: } catch (Exception ee) {
0326: }
0327: }
0328:
0329: /**
0330: * returns a string for time that looks good!
0331: *
0332: *
0333: * Symbol Meaning Presentation Example
0334: * ------ ------- ------------ -------
0335: * G era designator (Text) AD
0336: * y year (Number) 1996
0337: * M month in year (Text & Number) July & 07
0338: * d day in month (Number) 10
0339: * h hour in am/pm (1~12) (Number) 12
0340: * H hour in day (0~23) (Number) 0
0341: * m minute in hour (Number) 30
0342: * s second in minute (Number) 55
0343: * S millisecond (Number) 978
0344: * E day in week (Text) Tuesday
0345: * D day in year (Number) 189
0346: * F day of week in month (Number) 2 (2nd Wed in July)
0347: * w week in year (Number) 27
0348: * W week in month (Number) 2
0349: * a am/pm marker (Text) PM
0350: * k hour in day (1~24) (Number) 24
0351: * K hour in am/pm (0~11) (Number) 0
0352: * z time zone (Text) Pacific Standard Time
0353: * ' escape for text (Delimiter)
0354: * '' single quote (Literal) '
0355: *
0356: * The count of pattern letters determine the format.
0357: *
0358: * (Text): 4 or more pattern letters--use full form, < 4--use short or abbreviated form if one exists.
0359: * (Number): the minimum number of digits. Shorter numbers are zero-padded to this amount.
0360: * Year is handled specially; that is, if the count of 'y' is 2, the Year will be truncated to 2 digits.
0361: * (Text & Number): 3 or over, use text, otherwise use number.
0362: * Any characters in the pattern that are not in the ranges of ['a'..'z'] and ['A'..'Z'] will be
0363: * treated as quoted text. For instance, characters like ':', '.', ' ', '#' and '@' will appear in the
0364: * resulting time text even they are not embraced within single quotes.
0365: */
0366: public static String getTimeString(Date date) {
0367: String timeString = "";
0368: try {
0369: // Create a SimpleDateFormat object with the time pattern specified
0370: SimpleDateFormat daytimeFormat = new SimpleDateFormat(
0371: "EE MM/dd/yyyy HH:mm:ss (zz)");
0372: // Create the special time format...
0373: timeString = daytimeFormat.format(date);
0374: } catch (Exception e) {
0375: e.printStackTrace();
0376: }
0377: return timeString;
0378: }
0379:
0380: public static String getShortTimeString(Date date) {
0381: String timeString = "";
0382: try {
0383: // Create a SimpleDateFormat object with the time pattern specified
0384: SimpleDateFormat daytimeFormat = new SimpleDateFormat(
0385: "MM/dd/yy HH:mm:ss");
0386: // Create the special time format...
0387: timeString = daytimeFormat.format(date);
0388: } catch (Exception e) {
0389: e.printStackTrace();
0390: }
0391: return timeString;
0392: }
0393:
0394: public static String getAllSessionsHelpString() {
0395: return "<p>'<i><b>All Sessions</b></i>' on the server are listed here.<br>"
0396: + "<lu><li>Expand '<i>All Sessions</i>' to see them,"
0397: + "or double click with the mouse to show/hide the sessions.</li>"
0398: + "<li>Right-click a Session name to join the session,"
0399: + "or right-click its Channels to join the Session.</li>"
0400: + "<li>Right-click '<i>All Sessions</i>' to create a new session.</li></lu>"
0401: + "";
0402: }
0403:
0404: /**
0405: * accessor for the isApplication flag
0406: *
0407: * @return false if instance started as an applet, true if started as an
0408: * application
0409: */
0410: public static boolean getIsApplication() {
0411: return isApplication;
0412: }
0413:
0414: /**
0415: * sets the isApplication attribute
0416: *
0417: * @param newValue newValue to be set into the isApplication flag
0418: */
0419: public static void setIsApplication(boolean newValue) {
0420: isApplication = newValue;
0421: }
0422:
0423: /**
0424: * accessor for the main applet instance
0425: *
0426: * @return the main applet instance
0427: */
0428: public static Applet getApplet() {
0429: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0430: getLoggingInterface().GENERALSTATUS,
0431: "Retrieving Applet (" + ourApplet + ")");
0432: return ourApplet;
0433: }
0434:
0435: /**
0436: * sets the main applet instance
0437: *
0438: * @param applet a reference to the main applet instance
0439: */
0440: public static void setApplet(Applet applet) {
0441: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0442: getLoggingInterface().GENERALSTATUS,
0443: "Applet set to " + applet);
0444: ourApplet = applet;
0445: }
0446:
0447: /**
0448: * accessor for the userName parameter value
0449: *
0450: * @return userName value
0451: */
0452: public static String getUserName() {
0453: return userName;
0454: }
0455:
0456: /**
0457: * sets the userName value
0458: *
0459: * @param newUserName userName value
0460: */
0461: public static void setUserName(String newUserName) {
0462: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0463: getLoggingInterface().GENERALSTATUS,
0464: "userName set to " + newUserName);
0465: userName = newUserName;
0466: }
0467:
0468: /**
0469: * accessor for the userFullName parameter value
0470: *
0471: * @return userFullName value
0472: */
0473: public static String getUserFullName() {
0474: return userFullName;
0475: }
0476:
0477: /**
0478: * sets the userFullName value
0479: *
0480: * @param newUserFullName userFullName value
0481: */
0482: public static void setUserFullName(String newUserFullName) {
0483: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0484: getLoggingInterface().GENERALSTATUS,
0485: "userFullName set to " + newUserFullName);
0486: userFullName = newUserFullName;
0487: }
0488:
0489: /**
0490: * accessor for the userID value (Client's unique ID number)
0491: *
0492: * @return the userID value
0493: */
0494: public static int getUserID() {
0495: return userID;
0496: }
0497:
0498: /**
0499: * sets the userID value
0500: *
0501: * @param newUserID userID value
0502: */
0503: public static void setUserID(int newUserID) {
0504: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0505: getLoggingInterface().GENERALSTATUS,
0506: "userID set to " + newUserID);
0507: userID = newUserID;
0508: }
0509:
0510: /**
0511: * accessor for the enterpriseID value (Client's enterprise ID number)
0512: *
0513: * @return the enterpriseID value
0514: */
0515: public static int getEnterpriseID() {
0516: return enterpriseID;
0517: }
0518:
0519: /**
0520: * sets the enterpriseID value
0521: *
0522: * @param newEnterpriseID enterpriseID value
0523: */
0524: public static void setEnterpriseID(int newEnterpriseID) {
0525: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0526: getLoggingInterface().GENERALSTATUS,
0527: "enterpriseID set to " + newEnterpriseID);
0528: enterpriseID = newEnterpriseID;
0529: }
0530:
0531: /**
0532: * accessor for the width value (a generic attribute)
0533: *
0534: * @return the width value
0535: */
0536: public static int getWidth() {
0537: return width;
0538: }
0539:
0540: /**
0541: * sets the width value
0542: *
0543: * @param newWidth width value
0544: */
0545: public static void setWidth(int newWidth) {
0546: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0547: getLoggingInterface().GENERALSTATUS,
0548: "width set to " + newWidth);
0549: width = newWidth;
0550: }
0551:
0552: /**
0553: * accessor for the height value (a generic attribute)
0554: *
0555: * @return the height value
0556: */
0557: public static int getHeight() {
0558: return height;
0559: }
0560:
0561: /**
0562: * sets the height value
0563: *
0564: * @param newHeight height value
0565: */
0566: public static void setHeight(int newHeight) {
0567: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0568: getLoggingInterface().GENERALSTATUS,
0569: "height set to " + newHeight);
0570: height = newHeight;
0571: }
0572:
0573: /**
0574: * accessor for the server machine IP address
0575: *
0576: * @return IP address for the server machine
0577: */
0578: public static String getServerIP() {
0579: return serverIP;
0580: }
0581:
0582: /**
0583: * Sets the server IP address; this should be used by the class that reads the
0584: * command line parameters (for applications) or the applet code to set this
0585: * value so that all other classes will be able to use getServerIP() when the
0586: * server name is needed.
0587: *
0588: * @param newServername IP address of the server
0589: *
0590: */
0591: public static void setServerIP(String newServerIP) {
0592: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0593: getLoggingInterface().GENERALSTATUS,
0594: "Server IP set to " + newServerIP);
0595: serverIP = newServerIP;
0596: }
0597:
0598: /**
0599: * Sets the command status connection for this client (used to communicate with
0600: * the server)
0601: */
0602: public static void setCommandStatusConnection(
0603: DataShareConnection this CommandStatusConnection) {
0604: commandStatusConnection = this CommandStatusConnection;
0605: }
0606:
0607: /**
0608: * Retreives the command status connection for this client
0609: */
0610: public static DataShareConnection getCommandStatusConnection() {
0611: return commandStatusConnection;
0612: }
0613:
0614: /**
0615: * returns an imageIcon (from the jar file if called from an applet)
0616: * Note that the image name should be an absolute filename, for example:
0617: * /com/ball/ads/hc/images/my.gif, and that the FILE NAMES ARE CASE SENSITIVE.
0618: *
0619: * @param container a container that is loaded so it's class loader can be used to
0620: * retrieve the image
0621: * @param name the filename of the image
0622: * @return the specified imageIcon
0623: */
0624: public static ImageIcon getImageIcon(Container container,
0625: String name) {
0626: ImageIcon imageIcon = null;
0627: Image image = null;
0628: image = getMyImage(container, name);
0629: if (image != null) {
0630: imageIcon = new ImageIcon(image);
0631: }
0632: return imageIcon;
0633: }
0634:
0635: /**
0636: * returns an imageIcon (from the jar file if called from an applet)
0637: * Note that the image name should be an absolute filename, for example:
0638: * /com/ball/ads/hc/images/my.gif, and that the FILE NAMES ARE CASE SENSITIVE.
0639: *
0640: * @param frame a frame that is loaded so it's class loader can be used to
0641: * retrieve the image
0642: * @param name the filename of the image
0643: * @return the specified imageIcon
0644: */
0645: public static ImageIcon getImageIcon(Frame frame, String name) {
0646: ImageIcon imageIcon = null;
0647: Image image = null;
0648: image = getMyImage((Container) frame, name);
0649: if (image != null) {
0650: imageIcon = new ImageIcon(image);
0651: }
0652: return imageIcon;
0653: }
0654:
0655: /**
0656: * this method will load an image from jar files (and possibly other resources
0657: * that the classloader knows about). Note that the image name should be an
0658: * absolute filename, for example: /com/ball/ads/hc/images/my.gif
0659: *
0660: * @param container used to load a resource
0661: * @param imageName the file name of the image
0662: * @return the specified image
0663: */
0664: public static Image getMyImage(Container container, String imageName) {
0665: if (imageName == null)
0666: return null;
0667: Image image = null;
0668: byte[] imageBytes = null;
0669: try {
0670: // get first file with this name...
0671: //imageName = container.getClass().getClassLoader().getResource(imageName).getFile();
0672:
0673: InputStream in = container.getClass().getResourceAsStream(
0674: imageName);
0675: int length = in.available();
0676: getLoggingInterface().debugMsg(
0677: getLoggingInterface().DEBUG,
0678: getLoggingInterface().GENERALSTATUS,
0679: "found image " + imageName + " that is " + length
0680: + " bytes long");
0681: imageBytes = new byte[length];
0682: in.read(imageBytes);
0683: Toolkit toolkit = Toolkit.getDefaultToolkit();
0684: image = toolkit.createImage(imageBytes);
0685: } catch (Exception exc) {
0686: getLoggingInterface().debugMsg(
0687: getLoggingInterface().WARNING,
0688: getLoggingInterface().GENERALSTATUS,
0689: exc + " getting resource " + imageName);
0690: // exc.printStackTrace();
0691: return null;
0692: }
0693: return image;
0694: }
0695:
0696: /**
0697: * sets the frame's Icon to our standard Icon
0698: *
0699: * @param frame
0700: */
0701: public static void setFrameIcon(Frame frame) {
0702: if (frame != null) {
0703: Image k2Icon = SessionUtilities.getMyImage(frame,
0704: SessionUtilities.imageRoot + "smallK2.gif");
0705: frame.setIconImage(k2Icon);
0706: }
0707: }
0708:
0709: /**
0710: * determines what type of object is to be inserted, then inserts it at as the last
0711: * child at the appropriate place.
0712: *
0713: * @param doi the object to be inserted into the tree
0714: */
0715: public static void insertNode(DefaultObjectInfo doi,
0716: DefaultMutableTreeNode sessionNode,
0717: DefaultMutableTreeNode clientNode, DefaultTreeModel model,
0718: String myClientClass) {
0719: if (doi.getOriginalType().equals(DefaultObjectInfo.CLIENTTYPE))
0720: addSpecialClient(doi, clientNode, model, myClientClass);
0721: else if (doi.getOriginalType().equals(
0722: DefaultObjectInfo.SESSIONTYPE))
0723: addSession(doi, sessionNode, model, myClientClass);
0724: else if (doi.getOriginalType().equals(
0725: DefaultObjectInfo.CHANNELTYPE))
0726: addChannel(doi, sessionNode, model, myClientClass);
0727: else if (doi.getOriginalType().equals(
0728: DefaultObjectInfo.CONSUMERTYPE))
0729: addConsumer(doi, sessionNode, model, myClientClass);
0730: }
0731:
0732: /**
0733: * adds a SpecialClient to our treeNode
0734: *
0735: * @param doi the client object to be inserted
0736: */
0737: protected static void addSpecialClient(DefaultObjectInfo doi,
0738: DefaultMutableTreeNode clientNode, DefaultTreeModel model,
0739: String myClientClass) {
0740: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0741: getLoggingInterface().CLIENT,
0742: "adding a client to our tree->" + doi.toString());
0743: DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(doi);
0744: if (clientNode != null) // sometimes we get updates before we get setup
0745: {
0746: // if client is our class, just stick it in the clientNode
0747: if (doi.getClientClass().equals(myClientClass)) {
0748: insertNodeInto(newNode, clientNode, clientNode
0749: .getChildCount(), model);
0750: } else // we must put client into the clientClass sub node...
0751: {
0752: // first find if we have a subnode of the correct clientClass...
0753: DefaultMutableTreeNode clientClassNode = clientNode
0754: .getNextNode();
0755: while (clientClassNode != null) {
0756: // is this node the correct one?
0757: DefaultObjectInfo oi = (DefaultObjectInfo) clientClassNode
0758: .getUserObject();
0759: if (oi.getClientClass()
0760: .equals(doi.getClientClass())) // may also need to test if subclient type
0761: {
0762: // found the node we want to add the client to
0763: insertNodeInto(newNode, clientClassNode,
0764: clientClassNode.getChildCount(), model);
0765: break;
0766: } else
0767: clientClassNode = clientClassNode
0768: .getNextSibling(); // try the next node
0769: }
0770: if (clientClassNode == null) // did not already exist in our tree, so create it
0771: {
0772: // not our class and we have not subclient nodes, create one!
0773: DefaultObjectInfo newDoi = new DefaultObjectInfo(
0774: doi.getClientClass(),
0775: DefaultObjectInfo.SUBCLIENTTYPE, doi
0776: .getClientClass(), doi
0777: .getClientClass()
0778: + " clients");
0779: DefaultMutableTreeNode newClientNode = new DefaultMutableTreeNode(
0780: newDoi);
0781: insertNodeInto(newNode, newClientNode, 0, model);
0782: insertNodeInto(newClientNode, clientNode,
0783: clientNode.getChildCount(), model);
0784: }
0785: }
0786: }
0787:
0788: // save a possibly new client imageURL in our table
0789: if (doi.getOriginalType().equals(DefaultObjectInfo.CLIENTTYPE)) {
0790: SessionUtilities.setUserImageURL(doi.getKeyValue(), doi
0791: .getName(), doi.getImageURL());
0792: } else {
0793: getLoggingInterface().debugMsg(
0794: getLoggingInterface().DEBUG,
0795: getLoggingInterface().CLIENT,
0796: "AddSpecialClient()-> Found something other than a client in our clientNode->"
0797: + doi.getOriginalType());
0798: }
0799: }
0800:
0801: /**
0802: * adds a Session to our treeNode
0803: *
0804: * @param doi the object to be inserted
0805: */
0806: protected static void
0807: addSession(DefaultObjectInfo doi, DefaultMutableTreeNode sessionNode, DefaultTreeModel model, String myClientClass)
0808: {
0809: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0810: getLoggingInterface().SESSION,
0811: "adding a Session to our tree->" + doi.toString());
0812: DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(doi);
0813: if(sessionNode != null) // sometimes we get updates before we get setup
0814: {
0815: if(doi.getClientClass().equals(myClientClass))
0816: insertNodeInto(newNode,sessionNode,sessionNode.getChildCount(),model);
0817: else // we must put session into the clientClass sub node...
0818: {
0819: // first find if we have a subnode of the correct clientClass...
0820: DefaultMutableTreeNode clientClassNode = null;
0821: for(Enumeration enum = sessionNode.children(); enum.hasMoreElements();)
0822: {
0823: DefaultMutableTreeNode nextNode = (DefaultMutableTreeNode)enum.nextElement();
0824: DefaultObjectInfo oi = (DefaultObjectInfo)nextNode.getUserObject();
0825: // is this node the correct one?
0826: if(oi.getOriginalType().equals(DefaultObjectInfo.SUBSESSIONTYPE) &&
0827: oi.getClientClass().equals(doi.getClientClass()))
0828: {
0829: // found the node we want to add the client to
0830: insertNodeInto(newNode, nextNode, nextNode.getChildCount(), model);
0831: clientClassNode = nextNode; // indicate that we found the correct node
0832: }
0833: }
0834: if(clientClassNode == null) // did not already exist in our tree, so create it
0835: {
0836: // not our class and we have not subclient nodes, create one!
0837: DefaultObjectInfo newDoi = new DefaultObjectInfo(doi.getClientClass(), DefaultObjectInfo.SUBSESSIONTYPE, doi.getClientClass(), doi.getClientClass() + " clients");
0838: DefaultMutableTreeNode newSessionNode = new DefaultMutableTreeNode(newDoi);
0839: insertNodeInto(newNode, newSessionNode, 0, model);
0840: insertNodeInto(newSessionNode, sessionNode, sessionNode.getChildCount(), model);
0841: }
0842: }
0843: }
0844: }
0845:
0846: /**
0847: * adds a Channel to a Session in our treeNode
0848: *
0849: * @param doi the object to be inserted
0850: */
0851: protected static void addChannel(DefaultObjectInfo doi,
0852: DefaultMutableTreeNode sessionNode, DefaultTreeModel model,
0853: String clientClass) {
0854: getLoggingInterface().debugMsg(
0855: getLoggingInterface().DEBUG,
0856: getLoggingInterface().SESSION,
0857: "adding Channel " + doi.getKeyValue() + " to Session "
0858: + doi.getParentKeyValue());
0859: // first determine the session...
0860: if (doi.getParentKeyValue() != null) // make sure the parent session is provided
0861: {
0862: DefaultMutableTreeNode dmtn = searchForSessionInTree(doi
0863: .getParentKeyValue(), sessionNode);
0864: if (dmtn != null) {
0865: // insert this channel as the Session's last child
0866: insertNodeInto(new DefaultMutableTreeNode(doi), dmtn,
0867: dmtn.getChildCount(), model);
0868: } else {
0869: getLoggingInterface()
0870: .debugMsg(getLoggingInterface().DEBUG,
0871: getLoggingInterface().SESSION,
0872: "Could not locate a Channel's Session in our tree: time to View/Refresh");
0873: }
0874: } else {
0875: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0876: getLoggingInterface().SESSION,
0877: "This Channel has no parent Session value");
0878: }
0879: }
0880:
0881: /**
0882: * adds a Consumer to a Channel that is in a Session in our treeNode
0883: *
0884: * @param doi the object to be inserted
0885: */
0886: protected static void addConsumer(DefaultObjectInfo consumer,
0887: DefaultMutableTreeNode sessionNode, DefaultTreeModel model,
0888: String myClientClass) {
0889: // first find our Session, then the Channel, then add the Consumer
0890: if (consumer.getGrandParentKeyValue() != null) // make sure the parent session is provided
0891: {
0892: DefaultMutableTreeNode sessiondmtn = searchForSessionInTree(
0893: consumer.getGrandParentKeyValue(), sessionNode);
0894: if (sessiondmtn != null) {
0895: DefaultMutableTreeNode channeldmtn = searchForChannelInTree(
0896: consumer.getGrandParentKeyValue(), consumer
0897: .getParentKeyValue(), sessionNode);
0898: if (channeldmtn != null) {
0899: // determine if consumer already in tree...
0900: DefaultMutableTreeNode consumerDmtn = searchForConsumerInTree(
0901: consumer.getGrandParentKeyValue(), consumer
0902: .getParentKeyValue(), consumer
0903: .getKeyValue(), sessionNode);
0904: if (consumerDmtn != null) {
0905: DefaultObjectInfo oldConsumer = (DefaultObjectInfo) consumerDmtn
0906: .getUserObject();
0907:
0908: getLoggingInterface()
0909: .debugMsg(
0910: getLoggingInterface().DEBUG,
0911: getLoggingInterface().CLIENT,
0912: "Removing "
0913: + (oldConsumer
0914: .getActive() ? "active"
0915: : "inactive")
0916: + " Consumer "
0917: + consumer
0918: .getKeyValue());
0919: // overwrite entry in tree with replacement, so first remove previous entry...
0920: removeConsumer(oldConsumer, sessionNode, model);
0921: }
0922: getLoggingInterface().debugMsg(
0923: getLoggingInterface().DEBUG,
0924: getLoggingInterface().CLIENT,
0925: "Adding "
0926: + (consumer.getActive() ? "active"
0927: : "inactive")
0928: + " Consumer "
0929: + consumer.getKeyValue());
0930: // insert this Consumer as the Channel's last child
0931: insertNodeInto(
0932: new DefaultMutableTreeNode(consumer),
0933: channeldmtn, channeldmtn.getChildCount(),
0934: model);
0935: } else {
0936: getLoggingInterface()
0937: .debugMsg(getLoggingInterface().WARNING,
0938: getLoggingInterface().CLIENT,
0939: "Could not locate a Consumer's Channel in our tree: time to View/Refresh");
0940: }
0941: } else {
0942: getLoggingInterface()
0943: .debugMsg(getLoggingInterface().DEBUG,
0944: getLoggingInterface().CLIENT,
0945: "Could not locate a Consumer's Session in our tree: time to View/Refresh");
0946: }
0947: } else {
0948: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
0949: getLoggingInterface().CLIENT,
0950: "This Consumer has no parent Session value");
0951: }
0952: }
0953:
0954: /**
0955: * finds a Session with the same keyValue as the one specified,
0956: * returns null otherwise.
0957: *
0958: * @param sessionKeyValue key value for the Session, all Session names must be unique
0959: * @param sessionNode the top level of all Sessions, used as the starting point for the search
0960: * @return the node that corresponds to the requested Session
0961: */
0962: public static DefaultMutableTreeNode searchForSessionInTree(
0963: String sessionKeyValue, DefaultMutableTreeNode sessionNode) {
0964: DefaultMutableTreeNode retValue = null;
0965: if (sessionNode != null) // starts out empty, so check for it
0966: {
0967: // need to check all nodes, not just children because other client's Sessions will be in subsessiontype folders
0968: for (Enumeration sessions = sessionNode
0969: .depthFirstEnumeration(); sessions
0970: .hasMoreElements();) {
0971: DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) sessions
0972: .nextElement();
0973: DefaultObjectInfo session = (DefaultObjectInfo) dmtn
0974: .getUserObject();
0975: // skip subsessiontype folders...
0976: if (session.getOriginalType().equals(
0977: DefaultObjectInfo.SESSIONTYPE)
0978: && session.getKeyValue()
0979: .equals(sessionKeyValue)) {
0980: retValue = dmtn;
0981: break; // stop the for-loop
0982: }
0983: }
0984: }
0985: if (retValue == null) {
0986: getLoggingInterface().debugMsg(
0987: getLoggingInterface().DEBUG,
0988: getLoggingInterface().SESSION,
0989: "searchForSessionInTree unable to find Session->"
0990: + sessionKeyValue);
0991: }
0992: return retValue;
0993: }
0994:
0995: /**
0996: * finds a Client with the same keyValue as the one specified,
0997: * returns null otherwise.
0998: *
0999: * @param clientKeyValue the key value for the Client
1000: * @return the node for the requested Client
1001: */
1002: protected static DefaultMutableTreeNode searchForClientInTree(
1003: String clientKeyValue, DefaultMutableTreeNode clientNode) {
1004: DefaultMutableTreeNode retValue = null;
1005: if (clientNode != null) {
1006: // need to look at all nodes, not just children because some clients will be in their clientClass folders
1007: for (Enumeration clients = clientNode
1008: .depthFirstEnumeration(); clients.hasMoreElements();) {
1009: DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) clients
1010: .nextElement();
1011: DefaultObjectInfo client = (DefaultObjectInfo) dmtn
1012: .getUserObject();
1013: // skip over the subclienttype nodes
1014: if (client.getOriginalType().equals(
1015: DefaultObjectInfo.CLIENTTYPE)
1016: && client.getKeyValue().equals(clientKeyValue)) {
1017: retValue = dmtn;
1018: break; // stop the for-loop
1019: }
1020: }
1021: }
1022: if (retValue == null) {
1023: getLoggingInterface().debugMsg(
1024: getLoggingInterface().DEBUG,
1025: getLoggingInterface().CLIENT,
1026: "searchForClientInTree unable to find Client->"
1027: + clientKeyValue);
1028: }
1029: return retValue;
1030: }
1031:
1032: /**
1033: * finds a Channel with the same keyValue as the one specified by looking in the
1034: * Session with the same keyValue as the one specified as the parentSession.
1035: * returns null otherwise.
1036: *
1037: * @param sessionKeyValue key value for the Session for this Channel
1038: * @param channelKeyValue key value for the Channel
1039: * @return the node for the requested Channel
1040: */
1041: public static DefaultMutableTreeNode searchForChannelInTree(
1042: String sessionKeyValue, String channelKeyValue,
1043: DefaultMutableTreeNode sessionNode) {
1044: DefaultMutableTreeNode retValue = null;
1045: DefaultMutableTreeNode session = null;
1046: session = searchForSessionInTree(sessionKeyValue, sessionNode);
1047: if (session != null) {
1048: for (Enumeration channels = session.children(); channels
1049: .hasMoreElements();) {
1050: DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) channels
1051: .nextElement();
1052: DefaultObjectInfo channel = (DefaultObjectInfo) dmtn
1053: .getUserObject();
1054: if (channel.getKeyValue().equals(channelKeyValue)) {
1055: retValue = dmtn;
1056: break; // stop the for-loop
1057: }
1058: }
1059: if (retValue == null) {
1060: getLoggingInterface()
1061: .debugMsg(getLoggingInterface().DEBUG,
1062: getLoggingInterface().SESSION,
1063: "could not find the specified Channel in our tree");
1064: }
1065: } else {
1066: getLoggingInterface().debugMsg(
1067: getLoggingInterface().DEBUG,
1068: getLoggingInterface().SESSION,
1069: "searchForChannelInTree unable to find parent Session->"
1070: + sessionKeyValue);
1071: }
1072: return retValue;
1073: }
1074:
1075: /**
1076: * finds all Channels in the parentSession.
1077: * returns null otherwise.
1078: *
1079: * @param sessionKeyValue key value for the Session
1080: * @param sessionNode treeNode that contains all the Sessions
1081: * @return the channelKeyValues for all Channels in the Session
1082: */
1083: public static DefaultMutableTreeNode[] getAllChannelsInSession(
1084: String sessionKeyValue, DefaultMutableTreeNode sessionNode) {
1085: DefaultMutableTreeNode[] retValue = new DefaultMutableTreeNode[0];
1086: DefaultMutableTreeNode session = null;
1087: Vector channelVec = new Vector();
1088: session = searchForSessionInTree(sessionKeyValue, sessionNode);
1089: if (session != null) {
1090: for (Enumeration channels = session.children(); channels
1091: .hasMoreElements();) {
1092: DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) channels
1093: .nextElement();
1094: channelVec.add(dmtn);
1095: }
1096: if (channelVec.size() > 0) {
1097: retValue = new DefaultMutableTreeNode[channelVec.size()];
1098: for (int x = 0; x < channelVec.size(); x++)
1099: retValue[x] = (DefaultMutableTreeNode) channelVec
1100: .elementAt(x);
1101: } else {
1102: getLoggingInterface().debugMsg(
1103: getLoggingInterface().DEBUG,
1104: getLoggingInterface().SESSION,
1105: "could not find any Channels in our tree");
1106: }
1107: } else {
1108: getLoggingInterface().debugMsg(
1109: getLoggingInterface().DEBUG,
1110: getLoggingInterface().SESSION,
1111: "searchForAllChanneslInTree unable to find parent Session->"
1112: + sessionKeyValue);
1113: }
1114: return retValue;
1115: }
1116:
1117: /**
1118: * finds a Consumer with the same keyValue as the one specified by looking in the
1119: * Session with the same keyValue as the one specified by the sessionKeyValue
1120: * and the Channel with the same keyValue as the one specified by the enteKeyValue.
1121: * returns null otherwise.
1122: *
1123: * @param sessionKeyValue key value for the Session to look in
1124: * @param channelKeyValue key value for the Channel to look in
1125: * @param consumerKeyValue key value for the Consumer to find
1126: * @return the node for the requested Consumer
1127: */
1128: public static DefaultMutableTreeNode searchForConsumerInTree(
1129: String sessionKeyValue, String channelKeyValue,
1130: String consumerKeyValue, DefaultMutableTreeNode sessionNode) {
1131: DefaultMutableTreeNode retValue = null;
1132: DefaultMutableTreeNode channel = null;
1133: channel = searchForChannelInTree(sessionKeyValue,
1134: channelKeyValue, sessionNode);
1135: if (channel != null) {
1136: for (Enumeration consumers = channel.children(); consumers
1137: .hasMoreElements();) {
1138: DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) consumers
1139: .nextElement();
1140: DefaultObjectInfo consumer = (DefaultObjectInfo) dmtn
1141: .getUserObject();
1142: if (consumer.getKeyValue().equals(consumerKeyValue)) {
1143: retValue = dmtn;
1144: break; // stop the for-loop
1145: }
1146: }
1147: if (retValue == null) {
1148: getLoggingInterface()
1149: .debugMsg(getLoggingInterface().DEBUG,
1150: getLoggingInterface().CLIENT,
1151: "could not find the specified Consumer in our tree");
1152: }
1153: } else {
1154: getLoggingInterface().debugMsg(
1155: getLoggingInterface().DEBUG,
1156: getLoggingInterface().CLIENT,
1157: "searchForConsumerInTree unable to find parent Session/Channel->"
1158: + sessionKeyValue + "/" + channelKeyValue);
1159: }
1160: return retValue;
1161: }
1162:
1163: /**
1164: * removes a specialClient from our treeNode.
1165: *
1166: * @param doi contains info about the SpecialClient to remove
1167: */
1168: protected static void
1169: removeSpecialClient(DefaultObjectInfo doi, DefaultMutableTreeNode clientNode, DefaultTreeModel model)
1170: {
1171: DefaultMutableTreeNode dmtn = searchForClientInTree(doi.getKeyValue(), clientNode);
1172: if(dmtn != null)
1173: {
1174: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
1175: getLoggingInterface().CLIENT,
1176: "now removing special client " + doi.getKeyValue());
1177: model.removeNodeFromParent(dmtn);
1178:
1179: // now look at all of the clientNode to see if there are any SUBCLIENTTYPE folder that are empty
1180: for(Enumeration enum = clientNode.children(); enum.hasMoreElements(); )
1181: {
1182: DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)enum.nextElement();
1183: DefaultObjectInfo doi2 = (DefaultObjectInfo)childNode.getUserObject();
1184: // is it a subclienttype node?
1185: if(doi2.getOriginalType().equals(DefaultObjectInfo.SUBCLIENTTYPE))
1186: {
1187: // is it empty
1188: if(childNode.isLeaf())
1189: {
1190: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
1191: getLoggingInterface().CLIENT,
1192: "removing empty node-> " + childNode.toString());
1193: model.removeNodeFromParent(childNode);
1194: }
1195: }
1196: }
1197: }
1198: }
1199:
1200: /**
1201: * removes a Session from our treeNode.
1202: *
1203: * @param doi contains info about the Sesison to remove
1204: */
1205: protected static void
1206: removeSession(DefaultObjectInfo doi, DefaultMutableTreeNode sessionNode, DefaultTreeModel model)
1207: {
1208: DefaultMutableTreeNode dmtn = searchForSessionInTree(doi.getKeyValue(), sessionNode);
1209: if(dmtn != null)
1210: {
1211: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
1212: getLoggingInterface().SESSION,
1213: "now removing Session " + doi.getKeyValue());
1214: model.removeNodeFromParent(dmtn);
1215: // now look at all of the sessionNode to see if there are any SUBSESSIONTYPE folder that are empty
1216: for(Enumeration enum = sessionNode.children(); enum.hasMoreElements(); )
1217: {
1218: DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)enum.nextElement();
1219: DefaultObjectInfo doi2 = (DefaultObjectInfo)childNode.getUserObject();
1220: // is it a subsessiontype node?
1221: if(doi2.getOriginalType().equals(DefaultObjectInfo.SUBSESSIONTYPE))
1222: {
1223: // is it empty
1224: if(childNode.isLeaf())
1225: {
1226: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
1227: getLoggingInterface().SESSION,
1228: "removing empty node-> " + childNode.toString());
1229: model.removeNodeFromParent(childNode);
1230: }
1231: }
1232: }
1233: }
1234: else
1235: {
1236: getLoggingInterface().debugMsg(getLoggingInterface().DEBUG,
1237: getLoggingInterface().SESSION,
1238: "removeSession() was unable to find the Session to remove it");
1239: }
1240: }
1241:
1242: /**
1243: * removes a Consumer from our treeNode
1244: *
1245: * @param doi contains info about the Consumer to remove
1246: */
1247: protected static void removeConsumer(DefaultObjectInfo doi,
1248: DefaultMutableTreeNode sessionNode, DefaultTreeModel model) {
1249: // first we must find the Session, then the Channel, then the Consumer...
1250: DefaultMutableTreeNode dmtn = searchForConsumerInTree(doi
1251: .getGrandParentKeyValue(), doi.getParentKeyValue(), doi
1252: .getKeyValue(), sessionNode);
1253: if (dmtn != null) {
1254: getLoggingInterface().debugMsg(
1255: getLoggingInterface().DEBUG,
1256: getLoggingInterface().CLIENT,
1257: "Removing Consumer " + doi.getKeyValue()
1258: + " from Session "
1259: + doi.getGrandParentKeyValue()
1260: + ", Channel " + doi.getParentKeyValue());
1261: model.removeNodeFromParent(dmtn);
1262: }
1263: }
1264:
1265: /**
1266: * removes a Channel from our treeNode
1267: *
1268: * @param doi contains info about the Channel to remove
1269: */
1270: protected static void removeChannel(DefaultObjectInfo doi,
1271: DefaultMutableTreeNode sessionNode, DefaultTreeModel model) {
1272: DefaultMutableTreeNode dmtn = searchForChannelInTree(doi
1273: .getParentKeyValue(), doi.getKeyValue(), sessionNode);
1274: if (dmtn != null) {
1275: getLoggingInterface().debugMsg(
1276: getLoggingInterface().DEBUG,
1277: getLoggingInterface().SESSION,
1278: "Removing Channel " + doi.getKeyValue()
1279: + " from Session "
1280: + doi.getParentKeyValue());
1281: model.removeNodeFromParent(dmtn);
1282: } else {
1283: getLoggingInterface()
1284: .debugMsg(getLoggingInterface().DEBUG,
1285: getLoggingInterface().SESSION,
1286: "removeChannel() was unable to find the Channel to remove it");
1287: }
1288: }
1289:
1290: /**
1291: * removes the specified node from our tree
1292: *
1293: * @param doi contains info about the node to remove
1294: */
1295: public static void removeNode(DefaultObjectInfo doi,
1296: DefaultMutableTreeNode sessionNode,
1297: DefaultMutableTreeNode clientNode, DefaultTreeModel model,
1298: String myClientClass) {
1299: // do logic to this node in our tree...may need to use parent and grandparent
1300: if (doi.getOriginalType().equals(DefaultObjectInfo.CLIENTTYPE))
1301: removeSpecialClient(doi, clientNode, model);
1302: else if (doi.getOriginalType().equals(
1303: DefaultObjectInfo.SESSIONTYPE))
1304: removeSession(doi, sessionNode, model);
1305: else if (doi.getOriginalType().equals(
1306: DefaultObjectInfo.CHANNELTYPE))
1307: removeChannel(doi, sessionNode, model);
1308: else if (doi.getOriginalType().equals(
1309: DefaultObjectInfo.CONSUMERTYPE))
1310: removeConsumer(doi, sessionNode, model);
1311: }
1312:
1313: /**
1314: * inserts the specified node into the specified parent node at the specified index
1315: *
1316: * @param node node to be inserted
1317: * @param parentNode node which will receive the node
1318: * @param index location in parentNode at which to insert the new node
1319: */
1320: protected static void insertNodeInto(DefaultMutableTreeNode node,
1321: DefaultMutableTreeNode parentNode, int index,
1322: DefaultTreeModel model) {
1323: model.insertNodeInto(node, parentNode, index);
1324: }
1325:
1326: /**
1327: * returns true if Consumer is found in any Channel in this Session
1328: */
1329: public static boolean isConsumerInSession(
1330: DefaultMutableTreeNode sessionNode, String consumerKey) {
1331: boolean finished = false;
1332: boolean retValue = false;
1333: try {
1334: for (Enumeration channels = sessionNode.children(); channels
1335: .hasMoreElements()
1336: && !finished;) {
1337: DefaultMutableTreeNode channelNode = (DefaultMutableTreeNode) channels
1338: .nextElement();
1339: for (Enumeration consumers = channelNode.children(); consumers
1340: .hasMoreElements();) {
1341: DefaultMutableTreeNode consumerNode = (DefaultMutableTreeNode) consumers
1342: .nextElement();
1343: DefaultObjectInfo consumer = (DefaultObjectInfo) consumerNode
1344: .getUserObject();
1345: if (consumer.getKeyValue().equals(consumerKey)) {
1346: retValue = true;
1347: finished = true;
1348: break;
1349: }
1350: }
1351: }
1352: } catch (Exception e) {
1353: e.printStackTrace();
1354: }
1355: return retValue;
1356: }
1357:
1358: /**
1359: * used when an image for a user is to be saved
1360: */
1361: public static void setUserImageURL(String clientUniqueName,
1362: String clientName, String url) {
1363: clientUniqueName = clientUniqueName.toLowerCase();
1364: clientName = clientName.toLowerCase();
1365:
1366: // don't put a client into our table more than once by same name
1367: if (!clientImages.containsKey(clientUniqueName)) {
1368: // sometimes people don't like to put in the full URL name...
1369: if (!url.equals("")
1370: && !url.toLowerCase().startsWith("http:"))
1371: url = "http://" + getServerIP() + url;
1372: getLoggingInterface().debugMsg(
1373: getLoggingInterface().DEBUG,
1374: getLoggingInterface().CLIENT,
1375: "Adding imageURL for " + clientUniqueName + " --> "
1376: + url);
1377: clientImages.put(clientUniqueName, url);
1378: }
1379: if (!clientImages.containsKey(clientName)) {
1380: // sometimes people don't like to put in the full URL name...
1381: if (!url.equals("")
1382: && !url.toLowerCase().startsWith("http:"))
1383: url = "http://" + getServerIP() + url;
1384: getLoggingInterface()
1385: .debugMsg(
1386: getLoggingInterface().DEBUG,
1387: getLoggingInterface().CLIENT,
1388: "Adding imageURL for " + clientName
1389: + " --> " + url);
1390: clientImages.put(clientName, url);
1391: }
1392: }
1393:
1394: /**
1395: * used to retrieve the URL for a client's image, we must have had the client in our tree
1396: * and they must have an image loaded on the server;
1397: * @return URL string for image or empty string if URL not available
1398: */
1399: public static String getUserImageURL(String clientName) {
1400: clientName = clientName.toLowerCase();
1401: String url = "";
1402: if (clientImages.containsKey(clientName))
1403: url = (String) clientImages.get(clientName);
1404: return url;
1405: }
1406:
1407: /**
1408: * used to retrieve the Image of a client, we must have had the client in our tree and they
1409: * must have an imgage loaded on the server;
1410: */
1411: public static Image getUserImage(String clientName) {
1412: clientName = clientName.toLowerCase();
1413: Image image = null;
1414: String imageURL = "";
1415: Toolkit toolkit = Toolkit.getDefaultToolkit();
1416: try {
1417: imageURL = getUserImageURL(clientName); // look in list of collaborants...
1418: if (!imageURL.equals("")) {
1419: getLoggingInterface().debugMsg(
1420: getLoggingInterface().DEBUG,
1421: getLoggingInterface().CLIENT,
1422: "Image for " + clientName + " is at "
1423: + imageURL);
1424: image = toolkit.getImage(new URL(imageURL));
1425: } else {
1426: getLoggingInterface().debugMsg(
1427: getLoggingInterface().DEBUG,
1428: getLoggingInterface().CLIENT,
1429: "getUserImage() could not find the image for "
1430: + clientName);
1431: image = toolkit
1432: .getImage(SessionUtilities.missingPersonURL);
1433: }
1434: } catch (MalformedURLException e) {
1435: System.err.println("getUserImage(" + clientName
1436: + ") URL no good: " + imageURL);
1437: image = toolkit.getImage(SessionUtilities.missingPersonURL);
1438: }
1439:
1440: return image;
1441: }
1442:
1443: /**
1444: * finds clientName from clientKey
1445: * @param clientKey the clientKeyValue of a client
1446: * @param clientNode the node that contains all SpecialClients
1447: * @return the clientName that corresponds to the specified clientKeyValue, or empty string if not found
1448: */
1449: public static String findClientName(String clientKey,
1450: DefaultMutableTreeNode clientNode) {
1451: DefaultMutableTreeNode dmtn = searchForClientInTree(clientKey,
1452: clientNode);
1453: DefaultObjectInfo doi = (DefaultObjectInfo) dmtn
1454: .getUserObject();
1455: String clientName = doi.getName();
1456: return clientName;
1457: }
1458:
1459: /**
1460: * finds the first Frame going back through a Container's ancestry, returns null if
1461: * no Frame is found. Useful when we need a modal dialog and have no reference to a parent frame.
1462: */
1463: public static Frame getParentFrame(Container container) {
1464: Frame retValue = null;
1465: boolean finished = false;
1466: while (!finished) {
1467: try {
1468: retValue = (Frame) container;
1469: finished = true;
1470: } catch (ClassCastException cce) {
1471: container = container.getParent();
1472: } catch (Exception e) {
1473: finished = true;
1474: }
1475: }
1476: return retValue;
1477: }
1478:
1479: /**
1480: * This method will allow any JScrollPane to repaint 250 mseconds after scrollBar adjustments
1481: * made by a user have stopped. This is done so that the artifacts of scrolling (garbled text/images)
1482: * gets cleaned up after every scroll pane is moved (adjusted)
1483: */
1484: public static void scrollPaneDroppingsFixer(JScrollPane scrollPane) {
1485: final JScrollPane pane = scrollPane;
1486:
1487: pane.getHorizontalScrollBar().addAdjustmentListener(
1488: new AdjustmentListener() {
1489: // Invoked when the value of the adjustable (JScrollBar) has changed.
1490: public void adjustmentValueChanged(AdjustmentEvent e) {
1491: if (pane.getHorizontalScrollBar().isShowing())
1492: fifoQueue.write(pane);
1493: }
1494: });
1495: pane.getVerticalScrollBar().addAdjustmentListener(
1496: new AdjustmentListener() {
1497: // Invoked when the value of the adjustable (JScrollBar) has changed.
1498: public void adjustmentValueChanged(AdjustmentEvent e) {
1499: if (pane.getVerticalScrollBar().isShowing())
1500: fifoQueue.write(pane);
1501: }
1502: });
1503: }
1504:
1505: /**
1506: * makes fifoQueue a thread and provides a consumer method for any objects put into
1507: * the FIFO. Used here to provide a way to determine when a user has stopped making
1508: * JScrollBar adjustments on any JScrollPane for which scrollPaneDroppingsFixer was called.
1509: */
1510: static {
1511: fifoQueue.setConsumer(new FifoConsumer() {
1512: /**
1513: * called when data is available from the FIFO
1514: */
1515: public void newFifoDataAvailable(Object object) {
1516: handleNewScrollBarAdjustment((JScrollPane) object);
1517: }
1518: });
1519: }
1520:
1521: /**
1522: * called when a scrollBar adjustment has been made on a JScrollPane for which
1523: * scrollPaneDroppingsFixer was called.
1524: */
1525: synchronized private static void handleNewScrollBarAdjustment(
1526: JScrollPane pane) {
1527: // check to see if we already have a timer thread for this scrollPane
1528: JScrollBarTimerThread jsbtt = (JScrollBarTimerThread) scrollPaneHashtable
1529: .get(pane);
1530:
1531: if (jsbtt != null) {
1532: jsbtt.anotherAdjustmentMade(); // cancel any scheduled GUI update if it has not happened yet
1533: }
1534: scrollPaneHashtable.put(pane, new JScrollBarTimerThread(pane)); // schedule a GUI update...
1535: }
1536: }
1537:
1538: /////////////////////////////////////////////////
1539:
1540: /**
1541: * A one-shot timer, releases after .250 seconds, checks to see if it was stopped
1542: * (by calling the anotherAdjustmentMade method), if not, it updates the JScrollPane.
1543: */
1544: class JScrollBarTimerThread extends Thread {
1545: boolean running = true;
1546: JScrollPane pane;
1547:
1548: public JScrollBarTimerThread(JScrollPane pane) {
1549: this .pane = pane;
1550: this .setName("JScrollBarTimerThread");
1551: this .start();
1552: }
1553:
1554: /**
1555: * should be called when another adjustment is made so we can cancel the update
1556: * for the prior adjustment
1557: */
1558: public void anotherAdjustmentMade() {
1559: running = false;
1560: }
1561:
1562: public void run() {
1563: SessionUtilities.delay(250); // wait 1/4 second
1564: if (running) {
1565: pane.repaint(); // cause JScrollPane to update
1566: }
1567: }
1568:
1569: }
|