Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Lotus Instant Messaging and Web Conferencing ® Java Toolkit Version 6.5.1 Developer’s Guide G210-1729-00 Copyright and Trademark Information Disclaimer THE INFORMATION CONTAINED IN THIS DOCUMENTATION IS PROVIDED FOR INFORMATIONAL PURPOSES ONLY. WHILE EFFORTS WERE MADE TO VERIFY THE COMPLETENESS AND ACCURACY OF THE INFORMATION CONTAINED IN THIS DOCUMENTATION, IT IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. IN ADDITION, THIS INFORMATION IS BASED ON IBM’S CURRENT PRODUCT PLANS AND STRATEGY, WHICH ARE SUBJECT TO CHANGE BY IBM WITHOUT NOTICE. IBM SHALL NOT BE RESPONSIBLE FOR ANY DAMAGES ARISING OUT OF THE USE OF, OR OTHERWISE RELATED TO, THIS DOCUMENTATION OR ANY OTHER DOCUMENTATION. NOTHING CONTAINED IN THIS DOCUMENTATION IS INTENDED TO, NOR SHALL HAVE THE EFFECT OF, CREATING ANY WARRANTIES OR REPRESENTATIONS FROM IBM (OR ITS SUPPLIERS OR LICENSORS), OR ALTERING THE TERMS AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT GOVERNING THE USE OF IBM SOFTWARE. Licensed Materials - Property of IBM ©Copyright IBM Corporation 1998, 2004 All rights reserved. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GS ADP Schedule Contract with IBM Corp. Lotus Software IBM Software Group One Rogers Street Cambridge, MA 02142 List of Trademarks IBM, the IBM logo, 1-2-3, AIX, AS/400, DB2, Domino, Domino Designer, iNotes, iSeries, Lotus, Lotus Notes, MQSeries, Netfinity, Notes, QuickPlace, Sametime, SmartSuite, S/390, Tivoli, WebSphere, and Word Pro are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. Pentium is a trademark of Intel Corporation in the United States, other countries, or both. Microsoft, Windows, and Windows NT are registered trademarks of Microsoft Corporation in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others. Third Party Notices For the XSL and XML Parser and Processor The Apache Software License, Version 1.1 Copyright (c) 1999-2000 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Xerces" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [email protected]. 5. Products derived from this software may not be called "Apache," nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally based on software copyright (c) 1999, International Business Machines, Inc., http://www.ibm.com. For more information on the Apache Software Foundation, please see http://www.apache.org/. For DSIG base64 COPYRIGHT 1995 BY: MASSACHUSETTS INSTITUTE OF TECHNOLOGY (MIT), INRIA This W3C software is being provided by the copyright holders under the following license. By obtaining, using and/or copying this software, you agree that you have read, understood, and will comply with the following terms and conditions: Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee or royalty is hereby granted, provided that the full text of this NOTICE appears on ALL copies of the software and documentation or portions thereof, including modifications, that you make. THIS SOFTWARE IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE OR DOCUMENTATION. The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. For STLport License Agreement Boris Fomitchev grants Licensee a non-exclusive, non-transferable, royalty-free license to use STLport and its documentation without fee. By downloading, using, or copying STLport or any portion thereof, Licensee agrees to abide by the intellectual property laws and all other applicable laws of the United States of America, and to all of the terms and conditions of this Agreement. Licensee shall maintain the following copyright and permissionnotices on STLport sources and its documentation unchanged : Copyright 1999,2000 Boris Fomitchev This material is provided "as is", with absolutely no warranty expressed or implied. Any use is at your own risk. Permission to use or copy this software for any purpose is hereby granted without fee, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyright notice. The Licensee may distribute binaries compiled with STLport (whether original or modified) without any royalties or restrictions. The Licensee may distribute original or modified STLport sources, provided that: The conditions indicated in the above permission notice are met; The following copyright notices are retained when present, and conditions provided in accompanying permission notices are met : Copyright 1994 Hewlett-Packard Company Copyright 1996,97 Silicon Graphics Computer Systems, Inc. Copyright 1997 Moscow Center for SPARC Technology. Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Hewlett-Packard Company makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Silicon Graphics makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. Moscow Center for SPARC Technology makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. Copyright 2001 by STLport For MD5 hash Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. For Log4J Logging The Apache Software License, Version 1.1 at http://www.apache.org/LICENSE, 24 May 2002 The Apache Software License, Version 1.1 Copyright (c) 2000 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [email protected]. 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. Portions of this software are based upon public domain software originally written at the National Center for Supercomputing Applications, University of Illinois, Urbana-Champaign. Table of Contents Chapter 1 Introduction.............................................................................................. 1 Intended Audience .............................................................................................. 1 Requirements ...................................................................................................... 1 Accessing the Toolkit Page on the Web ........................................................... 2 How to Use This Guide ....................................................................................... 2 Related Documents............................................................................................. 3 Additional Information ........................................................................................ 4 Chapter 2 Sametime-Enabled AWT Components .................................................. 5 Introduction ......................................................................................................... 5 Add Dialog ........................................................................................................... 6 Awareness List .................................................................................................. 11 Directory Panel .................................................................................................. 16 Place Awareness List........................................................................................ 22 Privacy Panel ..................................................................................................... 28 Resolve Panel .................................................................................................... 34 Chapter 3. Community UI Components ...................................................................... 39 Introduction ....................................................................................................... 39 Announcement UI Component......................................................................... 40 Chat UI Component........................................................................................... 42 Community UI Component ............................................................................... 58 FileTransfer UI Component .............................................................................. 60 Chapter 4. Community Services .................................................................................. 69 Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide i Table of Contents Introduction ....................................................................................................... 69 Announcement Service .................................................................................... 70 Awareness Service............................................................................................ 71 Buddy List Service ............................................................................................ 80 Community Service........................................................................................... 83 Directory Service............................................................................................... 86 FileTransfer Service .......................................................................................... 89 Instant Messaging Service ............................................................................. 100 Lookup Service................................................................................................ 109 Names Service................................................................................................. 111 Places Service ................................................................................................. 112 Post Service..................................................................................................... 127 Storage Service ............................................................................................... 129 Token Service .................................................................................................. 132 Chapter 5. Meeting Services ...................................................................................... 133 Introduction ..................................................................................................... 133 Meeting Factory Services ............................................................................... 134 Application Sharing Service........................................................................... 140 Whiteboard Service......................................................................................... 146 Streamed Media Service ................................................................................. 151 Meeting Moderation and Permissions........................................................... 166 Sizeable Interface ............................................................................................ 172 Appendix A. Enabling Your Domino Applications ................................................. 177 Using Tokens................................................................................................... 177 Locating the Sametime Server....................................................................... 178 Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide ii Table of Contents Using the Sample Domino Application ......................................................... 179 Enabling Your Template ................................................................................. 179 Appendix B. Component Dependencies for Loading and Packaging .................. 184 Methods of Loading Components ................................................................. 184 Restrictions...................................................................................................... 185 Available Components.................................................................................... 186 Component Dependencies ............................................................................. 187 Appendix C. Meeting Services and PAC Support Deployment Issues................. 188 Supplied Files .................................................................................................. 188 File Names and Version Numbers ................................................................. 190 Native Code Dependencies ............................................................................ 192 Installing Java Code for Internet Explorer (Microsoft Native VM) .............. 195 Considerations when Obfuscating Classes ................................................. 196 Signing Java Archives .................................................................................... 196 Proxy Auto Configuration (PAC) Support Issues......................................... 196 Resource File Usage and Deployment .......................................................... 197 Summary of Recommended Applet Deployment Steps .............................. 197 Appendix D. Proxy Auto Configuration (PAC) Support ......................................... 199 Obtaining a PACService Object ..................................................................... 199 Enabling PAC Support with the Community Services................................. 200 Enabling PAC Support with the Meeting Services ....................................... 202 PAC Support Deployment Issues .................................................................. 202 Appendix E. Sametime Identifiers ........................................................................... 203 Awareness Service.......................................................................................... 203 Instant Messaging Service ............................................................................. 205 Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide iii Table of Contents Storage Service ............................................................................................... 205 User In Place Attributes.................................................................................. 208 Place Activity Types........................................................................................ 208 Post Service..................................................................................................... 208 Appendix F. Representing External Users ............................................................. 209 Overview .......................................................................................................... 209 Appendix G. Sametime Connectivity ....................................................................... 211 Overview .......................................................................................................... 211 The HybridPollingConnection class .............................................................. 211 The connectivity agent framework ................................................................ 212 Appendix H. Core Types ........................................................................................... 219 Overview .......................................................................................................... 219 Sametime ID Types ......................................................................................... 219 Sametime Object Types.................................................................................. 220 Appendix I. Multiple Language Support ................................................................ 221 Appendix J. Signing Applets ................................................................................... 222 Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide iv Chapter 1 Introduction Intended Audience This guide is intended for Java developers who have read the IBM® Lotus® Instant Messaging and Web Conferencing (Lotus Sametime®) Java Toolkit Tutorial and need a more in-depth understanding of the Sametime toolkit in order to create their own Sametime-enabled Java applications and applets. The guide is written to provide quick and easy reference to the different components of the toolkit and related subjects. Note Throughout this guide, IBM Lotus Instant Messaging and Web Conferencing is referred to as “Sametime,” and this and other toolkits are referred to as “Sametime” toolkits. This guide does not include information about general Java programming. For more information on the Java language and Java programming, please go to http://www.java.sun.com. This guide does not cover some of the general topics related to Sametime programming that are covered in the Tutorial. Requirements The Sametime Java Toolkit can be used in any JDK 1.1.8 or higher Java development environment. Applications created with this toolkit run on Windows 2000 or Windows XP, with the Sun Java Runtime Environment 1.4.1 installed. Applets created with this toolkit run in the following environments: • Windows 2000 Professional – Microsoft Internet Explorer 5.5 with Java 1.1 plugin, Microsoft Internet Explorer 6 and above with Java 1.1 or 1.4.1 plugin, Mozilla 1.4.1 with Java 1.4.1 plugin • Windows XP Professional – Microsoft Internet Explorer 6 and above with Java 1.1 or 1.4.1 plugin, Mozilla 1.4.1 with Java 1.4.1 plugin The toolkit is targeted for use with the following Sametime servers: • Windows and iSeries – 2.5 and above. • AIX and Solaris – 3.1 and 6.5.1 Although applications developed with this toolkit will work when run on Sametime 2.x or later servers, toolkit services that require features new to this release will not function. In particular, the code examples should be run on the latest version of the Sametime server. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 1 Chapter 1. Introduction Accessing the Toolkit Page on the Web To install the toolkit, visit http://www.ibm.com/developerworks/lotus/products/. On the Products page, click “Lotus Instant Messaging and Web Conferencing (Sametime)”. The Lotus Instant Messaging and Web Conferencing (Sametime) page contains links to all the documentation and downloads. You can extract the files for this toolkit either on your local machine or (to make it available to other users and run the samples) on your Sametime server. How to Use This Guide Chapters and appendices This manual is an in-depth reference to the Sametime Java Toolkit. Besides this introductory chapter, it contains four chapters: • Chapter 2 – Sametime-Enabled AWT Components • Chapter 3 – Community UI Components • Chapter 4 – Community Services • Chapter 5 – Meeting Services Each chapter follows the same format, divided into sections that cover each of the toolkit services or components. The possible headings within each section are: • Overview – A high-level description of the service or component and its uses • Diagram – A Unified Modeling Language (UML) diagram that provides a high-level graphic description of the service or component • Description – An in-depth description of how to use the service or component • Platform Dependencies – A description of any platform limitations of the service or component • Package – The Java package name of the service or component in the toolkit hierarchy • See Also – Additional samples and/or sections that are related to this service or component • Example – A code sample that shows how this service or component is used Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 2 Chapter 1. Introduction Nine appendices cover additional subjects and issues: • Appendix A – Enabling Your Domino Applications • Appendix B – Component Dependencies for Loading and Packaging • Appendix C – Meeting Services and PAC Support Deployment Issues • Appendix D – Proxy Auto Configuration (PAC) Support • Appendix E – Sametime Identifiers • Appendix F – Representing External Users • Appendix G – Sametime Connectivity • Appendix H – Core Types • Appendix I – Multiple Language Support • Appendix J – Signing Applets Samples Many of the examples found in this guide can be run directly from the toolkit Samples page. For instructions on accessing and running the samples, refer to Chapter 3 of the Sametime Java Toolkit Tutorial. Guide Conventions The following conventions are used in this guide: • Sample code is in Courier New • Sample code that has been added to a previous sample step is in bold Courier New. • New terms and emphasis are in italics. Related Documents • Sametime Java Toolkit Javadoc Reference • Sametime Java Toolkit Tutorial • Introducing the Sametime Client Toolkits (white paper) Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 3 Chapter 1. Introduction Additional Information Additional information can be found at the following Web sites: http://www.lotus.com/sametime http://www.ibm.com/developerworks/lotus You may also want to read “Working with the Sametime Client Toolkits,” available at the IBM Redbooks site (http://www.redbooks.ibm.com). Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 4 Chapter 2 Sametime-Enabled AWT Components Introduction These components extend a Java AWT component and provide Sametime-specific UI behavior. They can be created and destroyed at any time independent of the Sametime session object lifecycle. The components that inherit from the Java AWT Component class can be embedded like any other component inside any AWT Container. The available Sametime-Enabled AWT components are: • Add Dialog • Awareness List • Directory Panel • Place Awareness List • Privacy Panel • Resolve Panel Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 5 Chapter 2. Sametime-Enabled AWT Components Add Dialog Overview The Add dialog component provides the ability to retrieve user and group details. When opened, the dialog window is in search mode, expecting a user name to be typed in. The window is extended to display a list of matches in the event that more than one match is found for a user name. The user can also browse the Sametime directory by clicking the “Directory” button, which uses a directory-browsing Add dialog instead of a search Add dialog. Description When the Add dialog opens in search mode, it appears as follows: The dialog extends when more than one matching name is found (also known as resolve conflict). In the following dialog, more than one occurrence of “admin” was found: Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 6 Chapter 2. Sametime-Enabled AWT Components Click the “Directory” button to launch the Directory dialog. The Add to Invitation List dialog window displays (as shown below). The list of people available depends on the chosen directory. The Add dialog is a Sametime-enabled UI component that uses both the Lookup Service and the Directory Service when performing search and browse operations. To use the Add dialog, follow these steps: 1. Create and display the Add dialog. For example: AddDialog addDialog = new AddDialog((Frame)getParent(), m_session, "Select Users"); addDialog.setVisible(true); 2. Listen to events that occur in the dialog by calling the addResolveViewListener() method and passing an object that implements ResolveViewListener or extends ResolveViewAdapter. 3. After the listener is registered, you can receive the following event notifications: • Resolved() – Notification that a unique user was found and selected by the end user. You can receive this event after a successful search (also known as “resolve”) operation or after browsing the directory and selecting a user. You will also receive this event for each user inside a group if a group is selected when browsing the directory. • ResolveFailed() – Notification of a failed search operation. No match was found for the user name entered by the end user. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 7 Chapter 2. Sametime-Enabled AWT Components Package com.lotus.sametime.commui See Also com.lotus.sametime.commui.CommUI in the Sametime Java Toolkit Reference. The Resolve Panel section of this guide Example The following example contains an applet that logs on to the Sametime community. The applet contains a button that launches the Add dialog. Event notifications from the dialog are recorded in the text area displayed in the applet’s area. You can run the Add Dialog sample from the Java Toolkit Samples page. import import import import java.applet.*; java.awt.*; java.awt.event.*; java.util.*; import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.commui.*; /** * Add Dialog Sample. */ public class AddDialogApplet extends Applet implements LoginListener, ResolveViewListener, ActionListener { /** * Our session. */ private STSession m_session; /** * Text area for displaying messages. */ private TextArea m_textArea; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 8 Chapter 2. Sametime-Enabled AWT Components /** * String message displayed within the text area. */ private StringBuffer m_msg = new StringBuffer(); /** * The entry point for the applet. */ public void init() { try { // generate a new session with a unique name m_session = new STSession("AddDialog Applet " + this); // Call the session to load all available components m_session.loadAllComponents(); m_session.start(); setLayout(new BorderLayout()); Panel btnsPanel = new Panel(new GridBagLayout()); Button openDialog = new Button("Open Add Dialog"); openDialog.addActionListener(this); btnsPanel.add(openDialog); add(btnsPanel, BorderLayout.NORTH); m_textArea = new TextArea(); add(m_textArea, BorderLayout.CENTER); // login to the community login(); } catch(DuplicateObjectException e) { // This exception is thrown if an STSession with the // same name has already been created. e.printStackTrace(); } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { // get a reference to the community service. We use the session // object which contains a reference to all the components that // were loaded to get a reference to the community service. CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); // register a listener to the login/logout events. comm.addLoginListener(this); // login to the community comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 9 Chapter 2. Sametime-Enabled AWT Components getParameter("password")); } /** * Login event. */ public void loggedIn(LoginEvent event) { m_msg.append("Logged In"); m_textArea.setText(m_msg.toString()); } /** * Logout event */ public void loggedOut(LoginEvent event) { m_msg.append("Logged Out"); m_textArea.setText(m_msg.toString()); } /** * Notification of a successful resolve operation. */ public void resolved(ResolveViewEvent event) { m_msg.append("**** Resolved ****\n"); m_msg.append(event.getResolvedName() + " : " + event.getUser().getName() + "\n"); m_textArea.setText(m_msg.toString()); } /** * Notification of a failed resolve operation. */ public void resolveFailed(ResolveViewEvent event) { m_msg.append("**** Resolved Failed****\n"); m_msg.append(event.getResolvedName() + ", Reason:" + Integer.toHexString(event.getReason()) + "\n"); m_textArea.setText(m_msg.toString()); } /** * Action Performed. The button was clicked open the dialog. */ public void actionPerformed(ActionEvent e) { AddDialog d = new AddDialog((Frame) getParent(), m_session, "Select Users"); d.addResolveViewListener(this); d.setVisible(true); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 10 Chapter 2. Sametime-Enabled AWT Components Awareness List Overview The Awareness List is an embeddable Sametime-enabled Abstract Windowing Toolkit (AWT) component that allows you to display a list of users in the Sametime community with their online status and attributes. The list reflects the user’s current status. It is updated whenever a change in the user’s status or attribute occurs. Awareness Lists display the names of online users in green text. Instant messages and instant meetings can be started directly from the Awareness List by double-clicking on the online user’s name, or by right-clicking on a selection of online user names and choosing any of the available meeting types. File transfers and announcements can also be initiated by right-clicking. However, note that if you want to support file transfer in an applet, you must sign the applet, to allow local file access. For more information, see “Restrictions” in Appendix B. Description An Awareness List with a list of three user names appears as follows: The Awareness List extends java.awt.Panel and can therefore be embedded inside any Java AWT Container. Follow these steps to use the Awareness List: 1. Create the Awareness List: m_awarenessList = new AwarenessList(m_session, AwarenessList.CHECKED_BORDER); 2. Add the list to any AWT Container: add(m_awarenessList, BorderLayout.CENTER); 3. Add users to be watched by calling the addUser() method: m_awarenessList.addUser(stUser); The Awareness List also provides a simple API to remove a user from a list, get the currently selected items, or get all items in the list. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 11 Chapter 2. Sametime-Enabled AWT Components 4. Listen to events that occur in the list by calling the addAwarenessViewListener() method and passing a class that implements AwarenessViewListener or extends AwarenessViewAdapter. 5. After the listener is registered, you can receive the following event notifications: • StatusChanged() – Indicates a change in a user’s status • SelectionChanged() – Indicates that the user modified his selection in the list (mainly used for enabling/disabling menu items) • UsersAdded() – Indicates that users were added to the list • UsersRemoved() – Indicates that users were removed from the list • AddUserFailed() – Indicates that a user failed to be added to the list • ServiceUnavailable() – Indicates that the Awareness Service is currently unavailable (all users appear offline) • ServiceAvailable() – Indicates that the Awareness Service is currently available 6. (Optional) Set right-click behavior of the list. By default, the lists’ right-click menu allows you to initiate only one type of meeting (Chat) with one or more online users. You can modify this behavior to allow any kind of Sametime meeting by replacing the list’s controller and implementing some listeners of the Chat UI component. For more information, see the Chat UI Component section in Chapter 3. To change the list’s controller: AVController avController = new AVController(m_awarenessList.getModel()); m_awarenessList.setController(avController); Package com.lotus.sametime.awarenessui.list See Also The Place Awareness List section of this guide The Live Names and Extended Live Names samples (Chapters 5 and 6) in the Sametime Java Toolkit Tutorial Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 12 Chapter 2. Sametime-Enabled AWT Components Example The following example is the Live Names sample from the Sametime Java Tutorial that shows how to use the Awareness List. You can run the Live Names sample from the Java Toolkit Samples page. import java.awt.*; import java.applet.*; import java.util.*; import import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.STUser; com.lotus.sametime.community.*; com.lotus.sametime.lookup.*; com.lotus.sametime.awarenessui.list.AwarenessList; /** * Sample applet that displays a list of live user names. */ public class LiveNamesApplet extends Applet implements LoginListener, ResolveListener { private STSession m_session; private CommunityService m_comm; private AwarenessList m_awarenessList; /** * Applet initalized. Create the session, load all components, * start the session and then login. */ public void init() { try { m_session = new STSession("LiveNamesApplet " + this); m_session.loadAllComponents(); m_session.start(); setLayout(new BorderLayout()); m_awarenessList = new AwarenessList(m_session, true); add(m_awarenessList, BorderLayout.CENTER); login(); } catch(DuplicateObjectException e) { e.printStackTrace(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 13 Chapter 2. Sametime-Enabled AWT Components } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); m_comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), getParameter("password")); } /** * Logged in event. Print logged in msg to console. * Resolve the users to add to the awareness list. */ public void loggedIn(LoginEvent event) { System.out.println("Logged In"); LookupService lookup = (LookupService) m_session.getCompApi(LookupService.COMP_NAME); Resolver resolver = lookup.createResolver(false, // Return all matches. false, // Non-exhaustive lookup. true, // Return resolved users. false); // Do not return resolved groups. resolver.addResolveListener(this); String[] userNames = getUserNames(); resolver.resolve(userNames); } /** * Helper method to read a list of user names from the html * parameter 'watchedNames'. */ String[] getUserNames() { String users = getParameter("watchedNames"); StringTokenizer tokenizer = new StringTokenizer(users, ","); String[] userNames = new String[tokenizer.countTokens()]; int i = 0; while(tokenizer.hasMoreTokens()) { userNames[i++] = tokenizer.nextToken(); } return userNames; } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 14 Chapter 2. Sametime-Enabled AWT Components /** * Users resolved succesfuly event. An event will be generated for * each resolved user. Add the resolved user to the awareness list. */ public void resolved(ResolveEvent event) { m_awarenessList.addUser((STUser) event.getResolved()); } /** * Handle a resolve conflict event. Will be received in the case * that more then one match was found for a specified user name. * Add the users to the awareness list anyway. */ public void resolveConflict(ResolveEvent event) { STUser[] users = (STUser[]) event.getResolvedList(); m_awarenessList.addUsers(users); } /** * Resolve failed. No users are available to add to the list. */ public void resolveFailed(ResolveEvent event) { } /** * Logged out event. Print logged out msg to console. Leave default * behavior which will display a dialog box. */ public void loggedOut(LoginEvent event) { System.out.println("Logged Out"); } /** * Applet destroyed. Logout, stop and unload the session. */ public void destroy() { m_comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 15 Chapter 2. Sametime-Enabled AWT Components Directory Panel Overview The Directory Panel is an embeddable Sametime-enabled AWT component that allows you to display the list of available directories in the Sametime community and the directory contents. This panel enables basic directory browse and search capabilities for each of the available directories. An applet or application that needs to integrate directory access capabilities can quickly embed this panel and receive notifications on selections of users and groups within the directory. Information obtained from the directory can be used to interact with other users within the community. The Directory browsing service provides a list of all available directories and allows you to query for chunks of entries in each directory. Depending on your Sametime server configuration, directory browsing might not be available. See the Directory Service section in this manual for instructions on how to determine whether directory browsing is available on your Sametime server. A simple Directory dialog containing the Directory Panel is also provided in the toolkit. See the Sametime Java Toolkit Reference for more information on this dialog. Description The Directory Panel extends java.awt.Panel and can therefore be embedded inside any Java AWT Container. While the user is logged on to the system, the panel will display the available directories and enable the user to browse and search within each directory. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 16 Chapter 2. Sametime-Enabled AWT Components Follow these steps to use the Directory Panel: 1. Create the Directory Panel: DirectoryPanel dirPanel = new DirectoryPanel(m_session); 2. Add the panel to any AWT Container: add(dirPanel, BorderLayout.CENTER); 3. Listen to Directory Panel events by calling the addDirectoryListViewListener() method and passing a class that implements the DirectoryListViewListener or extends DirectoryListViewAdapter. 4. After the listener is registered, you can receive the following event notifications: • NodeDoubleClicked() – Indicates that the user double-clicked a node in the list. A node is either a user or group in the Directory list. • SelectionChanged() – Indicates that the user modified his selection in the list. You can use the Directory Panel method getSelectedEntries() to get a list of the currently selected entries at any time. Package com.lotus.sametime.directoryui See Also com.lotus.sametime.directoryui.DirectoryDialog of the Sametime Java Toolkit Reference The Directory Service section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 17 Chapter 2. Sametime-Enabled AWT Components Example The following example contains an applet that logs on to the Sametime community and displays the Directory Panel within the applet’s area. Any change in selection or a double click is recorded in the text area displayed below the panel. You can run the Directory Panel sample from the Java Toolkit Samples page. import import import import java.applet.*; java.awt.*; java.awt.event.*; java.util.*; import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.directoryui.*; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 18 Chapter 2. Sametime-Enabled AWT Components /** * Directory Sample using the directory panel. */ public class Directory extends Applet implements LoginListener, DirectoryListViewListener { /** * Our session. */ private STSession m_session; /** * Text area for displaying messages. */ private TextArea m_textArea; /** * The entry point for the applet. */ public void init() { try { // generate a new session with a unique name m_session = new STSession("Directory Applet " + this); // Call the session to load all available components m_session.loadAllComponents(); m_session.start(); setLayout(new BorderLayout()); DirectoryPanel dirPanel = new DirectoryPanel(m_session); add(dirPanel, BorderLayout.CENTER); //register a listener to receive selection change and //double click events. dirPanel.addDirectoryListViewListener(this); m_textArea = new TextArea(); add(m_textArea, BorderLayout.SOUTH); // login to the community login(); } catch(DuplicateObjectException e) { // This exception is thrown if an STSession with the same // name has already been created. e.printStackTrace(); } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { // get a reference to the community service. We use the session // object which contains a reference to all the components that Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 19 Chapter 2. Sametime-Enabled AWT Components // were loaded to get a reference to the community service. CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); // register a listener to the login/logout events. comm.addLoginListener(this); // login to the community comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), getParameter("password")); // Wait for the loggedin() event to enter the place } /** * Login event. */ public void loggedIn(LoginEvent event) { String msg = "Logged In"; m_textArea.setText(msg); } /** * Logout event */ public void loggedOut(LoginEvent event) { String msg = "Logged Out"; m_textArea.setText(msg); } /** * Returns the applet's insets. Creates 5 pixel margin around * the applet. */ public Insets getInsets() { return new Insets(5, 5, 5, 5); } /** * Selection changed in the directory list. */ public void selectionChanged(DirectoryListViewEvent event) { String msg = "**** Selection Changed ****\n"; Vector v = event.getSelectedNodes(); Enumeration e = v.elements(); while(e.hasMoreElements()) { msg += ((STObject) e.nextElement()).getName() + "\n"; } m_textArea.setText(msg); } /** Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 20 Chapter 2. Sametime-Enabled AWT Components * User or Group double clicked in the directory's list. */ public void nodeDoubleClicked(DirectoryListViewEvent event) { String msg = "**** Node Double Clicked ****\n"; msg += event.getDoubleClickedNode().getName(); m_textArea.setText(msg); } /** * Applet destroyed. Logout of Sametime. */ public void destroy() { CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 21 Chapter 2. Sametime-Enabled AWT Components Place Awareness List Overview The Place Awareness List is an embeddable Sametime-enabled AWT component that displays the list of users in a specific place. The users are shown with their online status and place attributes. This list is updated whenever a change in a user’s status or attribute occurs. The Place Awareness List and the Awareness List provide similar functionality. The major difference between them is the source of the list of names. Description This screen capture of the Place Awareness List shows two users in a place: The Place Awareness List extends java.awt.Panel and can therefore be embedded inside any Java AWT Container. Follow these steps to use the Place Awareness List: 1. Create the Place Awareness List: m_placeAwarenessList = new PlaceAwarenessList(m_session,true); 2. Add the list to any AWT Container: add(m_placeAwarenessList, BorderLayout.CENTER); 3. Bind the list to a specific place. The following example code creates a place object and then binds the Place Awareness List to it: m_place = placesService.createPlace("Tom's Place", "My Place", "", EncLevel.ENC_LEVEL_RC2_40, 0); m_placeAwarenessList.bindPlace(m_place); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 22 Chapter 2. Sametime-Enabled AWT Components 4. Listen to events that occur in the list by calling the addAwarenessViewListener() method and passing a class that implements AwarenessViewListener or extends AwarenessViewAdapter. After the listener is registered, you can receive the following event notifications. • StatusChanged() – Indicates a change in a user’s status • SelectionChanged() – Indicates that the user modified his selection in the list (mainly used for enabling/disabling menu items) • UsersAdded() – Indicates that users were added to the list • UsersRemoved() – Indicates that users were removed from the list • AddUserFailed() – Indicates that a user failed to be added to the list • ServiceUnavailable() – Indicates that the Awareness Service is currently unavailable (all users appear offline) • ServiceAvailable() – Indicates that the Awareness Service is currently available 5. (Optional) Set right-click behavior of the list. By default, the list’s right-click menu allows you to initiate only one type of meeting (Chat) with one or more online users. You can modify this behavior to initiate any kind of Sametime meeting by replacing the list’s controller and implementing some listeners of the Chat UI component. See the Chat UI section in Chapter 3 for more details. To change the lists’ controller: AVController avController = new AVController(m_placeAwarenessList.getModel()); m_placeAwarenessList.setController(avController); Package com.lotus.sametime.awarenessui.placelist See Also The Awareness List section in this guide Example The following example contains an applet that embeds a Place Awareness List. Click the "Press to Enter Place" button to enter the place. Select online users and right-click to start a meeting or see available meeting tools. You can run the Place Awareness List sample from the Java Toolkit Samples page. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 23 Chapter 2. Sametime-Enabled AWT Components import java.applet.*; import java.awt.*; import java.awt.event.*; import import import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.awarenessui.placelist.PlaceAwarenessList; com.lotus.sametime.awarenessui.av.AVController; com.lotus.sametime.community.*; com.lotus.sametime.places.*; com.lotus.sametime.core.constants.EncLevel; /** * Place Awareness Sample using the Place Awareness List. */ public class PlaceAwareness extends Applet implements LoginListener, ActionListener { /** * Our session. */ private STSession m_session; /** * The place awareness list. */ private PlaceAwarenessList m_placeAwarenessList; /** * Enter/leave place button */ private Button m_button; /** * The place being watched. */ private Place m_place; /** * The entry point for the applet. */ public void init() Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 24 Chapter 2. Sametime-Enabled AWT Components { try { // generate a new session with a unique name m_session = new STSession("Place Awareness List " + this); // Call the session to load all available components m_session.loadAllComponents(); m_session.start(); setLayout(new BorderLayout()); //add a label with the user name at top of the list Label label = new Label("User: " + getParameter("loginName")); label.setAlignment(Label.CENTER); add(label, BorderLayout.NORTH); // create the new list view m_placeAwarenessList = new PlaceAwarenessList(m_session, true); add(m_placeAwarenessList, BorderLayout.CENTER); //add the enter/leave button at the bottom m_button = new Button("Press To Enter Place"); add(m_button, BorderLayout.SOUTH); m_button.setEnabled(false); m_button.addActionListener(this); // The default right-click menu for the awareness list does not // give audio & video as options. We can change that by // changing the controller to a different one. AVController avController = new AVController(m_placeAwarenessList.getModel()); m_placeAwarenessList.setController(avController); // login to the community login(); } catch(DuplicateObjectException e) { // This exception is thrown if an STSession with the same // name has already been created. e.printStackTrace(); } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { // get a reference to the community service. We use the session // object which contains a reference to all the components that // were loaded to get a reference to the community service. CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 25 Chapter 2. Sametime-Enabled AWT Components // register a listener to the login/logout events. comm.addLoginListener(this); // login to the community comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), getParameter("password")); // Wait for the loggedin() event to enter the place } /** * Login event. */ public void loggedIn(LoginEvent event) { //Get refernce to the place service PlacesService placesService = (PlacesService) m_session.getCompApi(PlacesService.COMP_NAME); //Create a new place object m_place = placesService.createPlace("Tom's Place", "My Place", EncLevel.ENC_LEVEL_RC2_40, 0); //bind the list to the specified place. m_placeAwarenessList.bindPlace(m_place); //enable enter/leave button m_button.setEnabled(true); } /** * Logout event */ public void loggedOut(LoginEvent event) { //disable enter/leave button m_button.setEnabled(false); } /** * Action event. Leave/Enter button clicked enter or leave * place accordingly. */ public void actionPerformed(ActionEvent evt) { if(evt.getActionCommand().equals("Leave")) { //enter the place m_place.leave(0); m_button.setActionCommand("Enter"); m_button.setLabel("Press To Enter Place"); } else { //enter the place m_place.enter(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 26 Chapter 2. Sametime-Enabled AWT Components m_button.setActionCommand("Leave"); m_button.setLabel("Press To Leave Place"); } } /** * Applet destroyed. Logout of Sametime. */ public void destroy() { CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 27 Chapter 2. Sametime-Enabled AWT Components Privacy Panel Overview The Privacy Panel list is an embeddable Sametime-enabled AWT component that allows a user to view and modify his privacy settings. Privacy settings determine a user’s online status visibility within the Sametime community. The user can select one of three options: • Everybody can see me – The user is visible to all users in the community. • Only list below – Only the specified users in the list will receive online notifications about the user. • Everybody except list below – The user is visible to all users except for the users specified in the list. Remember that Sametime privacy is symmetric; you cannot see other users if you choose not to let them see you. A simple Privacy dialog containing the Privacy Panel is also provided in the toolkit. See the Sametime Java Toolkit Reference for more information on this dialog. Description In the screen capture of the Privacy Panel shown below, only one person will be able to see when the user is online: Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 28 Chapter 2. Sametime-Enabled AWT Components The Privacy Panel extends java.awt.Panel and can therefore be embedded inside any Java AWT Container. Follow these steps to use the Privacy Panel: 1. Create the Privacy Panel: PrivacyPane1 privacyPanel = new PrivacyPanel(m_session) 2. Add the panel to any AWT Container: add(privacyPanel, BorderLayout.CENTER); 3. The Privacy Panel has no event listeners to listen to. 4. The panel allows modifications of the user privacy settings. Call the submit() method of the panel to submit the end user’s changes. Package com.lotus.sametime.commui See Also com.lotus.sametime.commui.PrivacyDialog of the Sametime Java Toolkit Reference Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 29 Chapter 2. Sametime-Enabled AWT Components Example This example code contains an applet that logs on to the Sametime community and displays the Privacy Panel within the applet’s area. Any change in the privacy settings is recorded in the text area displayed below the panel. You can run the Privacy Panel sample from the Java Toolkit Samples page. import import import import java.applet.*; java.awt.*; java.awt.event.*; java.util.*; import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.commui.*; /** * Privacy Sample using the privacy panel. */ public class PrivacyApplet extends Applet implements LoginListener, ActionListener, MyPrivacyListener { /** * Our session. */ private STSession m_session; /** * Text area for displaying messages. */ private TextArea m_textArea; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 30 Chapter 2. Sametime-Enabled AWT Components /** * The Privacy Panel. */ private PrivacyPanel m_privacyPanel; /** * The entry point for the applet. */ public void init() { try { // generate a new session with a unique name m_session = new STSession("Privacy Applet " + this); // Call the session to load all available components m_session.loadAllComponents(); m_session.start(); //Create the UI components which include the privacy panel, //submit button and the text area for displaying privacy //information. setLayout(new BorderLayout(0, 10)); Panel upperPanel = new Panel(new BorderLayout()); m_privacyPanel = new PrivacyPanel(m_session); upperPanel.add(m_privacyPanel, BorderLayout.CENTER); Panel btnsPanel = new Panel(new BorderLayout(0, 10)); Button submitList = new Button("SubmitList"); submitList.addActionListener(this); btnsPanel.add(submitList, BorderLayout.CENTER); upperPanel.add(btnsPanel, BorderLayout.SOUTH); add(upperPanel, BorderLayout.CENTER); m_textArea = new TextArea(); add(m_textArea, BorderLayout.SOUTH); // login to the community login(); } catch(DuplicateObjectException e) { // This exception is thrown if an STSession with the same // name has already been created. e.printStackTrace(); } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { // get a reference to the community service. We use the session // object which contains a reference to all the components that // were loaded to get a reference to the community service. CommunityService comm = (CommunityService) Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 31 Chapter 2. Sametime-Enabled AWT Components m_session.getCompApi(CommunityService.COMP_NAME); // register a listener to the login/logout events. comm.addLoginListener(this); // login to the community comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), getParameter("password")); } /** * Login event. */ public void loggedIn(LoginEvent event) { // register a listener to privacy change evnets. event.getLogin().addMyPrivacyListener(this); String msg = "Logged In"; m_textArea.setText(msg); } /** * Logout event */ public void loggedOut(LoginEvent event) { String msg = "Logged Out"; m_textArea.setText(msg); } /** * Action Performed. The button was clicked open the dialog. */ public void actionPerformed(ActionEvent p1) { m_privacyPanel.submit(); } /** * Returns the applet's insets. Creates 5 pixel margin around * the applet. */ public Insets getInsets() { return new Insets(5, 5, 5, 5); } /** * My privacy settings changed. */ public void myPrivacyChanged(MyPrivacyEvent event) { String msg = "**** Users in my Privacy List ****\n"; Enumeration e = event.getPrivacyList().elements(); while(e.hasMoreElements()) { msg += ((STUser) e.nextElement()).getName() + "\n"; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 32 Chapter 2. Sametime-Enabled AWT Components } msg += "**** End of List ****\n"; m_textArea.setText(msg); } /** * Change to my privacy settings were denied. */ public void changeMyPrivacyDenied(MyPrivacyEvent event) { String msg = "**** Privacy Settings Denied ****\n"; m_textArea.setText(msg); } /** * Applet destroyed. Logout of Sametime. */ public void destroy() { CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 33 Chapter 2. Sametime-Enabled AWT Components Resolve Panel Overview The Resolve Panel is an embeddable Sametime-enabled AWT component that provides a text field for a user to enter a name to resolve and performs the resolve operation. The result is returned by a listener to the embedding application. If more than one match is found, a list is displayed from which the user can select the appropriate name. If no matches are found, an error message is displayed. Description Following is a screen capture of the Resolve Panel: The top part of the panel contains the text field for the user name to be searched and the “Search” button. The lower part contains an Awareness List that is populated with matching user names when more than a single match is found for the searched name. The Resolve Panel extends java.awt.Panel and can therefore be embedded inside any Java AWT Container. Follow these steps to use the Resolve Panel: 1. Create the Resolve Panel: ResolvePanel resolvePanel = new ResolvePanel(m_session); 2. Add the panel to any AWT Container: add(resolvePanel, BorderLayout.CENTER); 3. Listen to events that occur in the panel by calling the addResolveViewListener() method and passing a call that implements ResolveViewListener or extends ResolveViewAdapter. 4. After the listener is registered, you can receive the following event notifications: • Resolved() – Notification of a successful resolve operation. • ResolveFailed() – Notification of a failed resolve operation. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 34 Chapter 2. Sametime-Enabled AWT Components Package com.lotus.sametime.commui See Also com.lotus.sametime.commui .CommUI of the Sametime Java Toolkit Reference The Add Dialog section in this guide Example This example contains an applet that logs on to the Sametime community and displays the Resolve Panel within the applet’s area. Event notifications concerning the success and failure of the resolve operation are recorded in the text area displayed below the panel. You can run the Resolve Panel sample from the Java Toolkit Samples page. import import import import java.applet.*; java.awt.*; java.awt.event.*; java.util.*; import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.commui.*; /** Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 35 Chapter 2. Sametime-Enabled AWT Components * Resolve Sample using the resolve panel. */ public class ResolveApplet extends Applet implements LoginListener, ResolveViewListener { /** * Our session. */ private STSession m_session; /** * Text area for displaying messages. */ private TextArea m_textArea; /** * The entry point for the applet. */ public void init() { try { // generate a new session with a unique name m_session = new STSession("Resolve Applet " + this); // Call the session to load all available components m_session.loadAllComponents(); m_session.start(); setLayout(new BorderLayout()); ResolvePanel resolvePanel = new ResolvePanel(m_session); add(resolvePanel, BorderLayout.CENTER); //register a listener to receive notifications about user //resolved events. resolvePanel.addResolveViewListener(this); m_textArea = new TextArea(); add(m_textArea, BorderLayout.SOUTH); // login to the community login(); } catch(DuplicateObjectException e) { // This exception is thrown if an STSession with the same // name has already been created. e.printStackTrace(); } } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { // get a reference to the community service. We use the session // object which contains a reference to all the components that // were loaded to get a reference to the community service. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 36 Chapter 2. Sametime-Enabled AWT Components CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); // register a listener to the login/logout events. comm.addLoginListener(this); // login to the community comm.loginByPassword(getCodeBase().getHost(), getParameter("loginName"), getParameter("password")); } /** * Login event. */ public void loggedIn(LoginEvent event) { String msg = "Logged In"; m_textArea.setText(msg); } /** * Logout event */ public void loggedOut(LoginEvent event) { String msg = "Logged Out"; m_textArea.setText(msg); } /** * Returns the applet's insets. Creates 5 pixel margin around * the applet. */ public Insets getInsets() { return new Insets(5, 5, 5, 5); } /** * Notification of a successful resolve operation. */ public void resolved(ResolveViewEvent event) { String msg = "**** Resolved ****\n"; msg += event.getResolvedName() + " : " + event.getUser().getName(); m_textArea.setText(msg); } /** * Notification of a failed resolve operation. */ public void resolveFailed(ResolveViewEvent event) { String msg = "**** Resolved Failed****\n"; msg += event.getResolvedName() + ", Reason:" + Integer.toHexString(event.getReason()); m_textArea.setText(msg); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 37 Chapter 2. Sametime-Enabled AWT Components /** * Applet destroyed. Logout of Sametime. */ public void destroy() { CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 38 Chapter 3. Community UI Components Introduction Like all toolkit components, you must load the Community UI components into a Sametime session object for the components to be functional. These components are responsible for listening to Sametime events and displaying the appropriate UI. The available Community UI Components are: • Announcement UI Component • Chat UI Component • Community UI Component • FileTransfer UI Component Note The Java Toolkit supports keystroke access to Community UI components. For details, see the “Mnemonics” section of the properties file for each component (for example, chatui.properties in CommRes.jar or CommRes.cab). Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 39 Chapter 3. Community UI Components Announcement UI Component Overview The Announcement UI component provides the ability to send and receive announcements without having to deal with the low-level protocols involved. The component includes the SendAnnouncement dialog used for writing and sending an announcement, and the ReceiveAnnouncement dialog for receiving an announcement. Description You must load the Announcement UI component into the Sametime session object, like any other toolkit component. The Announcement UI component listens to events from the Announcement Service and notifies the user of incoming announcements. It can also be used to easily send announcements. Sending Announcements To send an announcement, call the sendAnnouncement() method of the Announcement Service. This method takes a list of STObject objects as a parameter. Each object in the list can be an STUser or an STGroup (a public group). The announcement will be sent to all users and public groups in the list. A SendAnnouncement dialog opens, letting the user write his announcement. The user can decide whether to let the recipients respond to the announcement by using the “Allow people to respond to me” checkbox. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 40 Chapter 3. Community UI Components The user clicks Send to send the announcement. Receiving Announcements To receive announcements, load the Announcement UI component into the Sametime session object. The Announcement UI component listens to events from the Announcement Service, and opens a ReceiveAnnouncement dialog as soon as an announcement is received. If the sender allowed responses, a Respond button appears. This button, when clicked, initiates an IM message to the sender. Package com.lotus.sametime.announcementui See Also The Announcement Service section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 41 Chapter 3. Community UI Components Chat UI Component Overview The Chat UI component provides the ability to create Sametime meetings and participate in them without having to deal with the low-level protocols that are involved. It includes the Invite dialog used for inviting users to meetings, the Join dialog for incoming invitations, and the chat windows. The Chat UI component can also launch the Meeting Room Client for complex Sametime meetings. Description You must load the Chat UI component into the Sametime session object, like any other toolkit component. The Chat UI component listens to events from the Instant Messaging and Post Services, and notifies the user of incoming instant messages (IMs) and meeting invitations. It can also be used to easily initiate IMs and meetings. Since the Chat UI component is not a Sametime-enabled AWT component, it cannot be embedded, and it displays more than one kind of UI dialog. Initiating Instant Messages (IMs) You can create an IM with another user in one of two ways. The table below identifies the two methods. If you have…. The user name only You will use… The create1On1Chat(String username) method. Chat UI tries to resolve the given string and start an IM session with the user. If the user cannot be resolved, an appropriate message will appear. If there is more than one registered user that matches the given name, a Resolve dialog will display the different matches from which the end user can select. An STUser object The create1On1ChatById(STUser user) method. Chat UI attempts to open an IM session with the user and displays a message if unsuccessful. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 42 Chapter 3. Community UI Components Initiating Meetings There is only one method for creating a new Sametime meeting. When called, the Chat UI component will create the meeting, invite the requested users, and launch the appropriate window for the meeting: createMeeting(MeetingTypes meetingType, String meetingName, String inviteText, boolean showInviteDlg, STUser[] users) The various meeting types are defined in the MeetingTypes class. The table below lists and describes the meeting types. Meeting Type Used For MeetingTypes.ST_CHAT_MEETING A chat meeting MeetingTypes.ST_AUDIO_MEETING An audio meeting MeetingTypes.ST_VIDEO_MEETING A video meeting MeetingTypes.ST_SHARE_MEETING An application-sharing meeting MeetingTypes.ST_COLLABORATION_MEETING A collaboration meeting Setting the showInviteDlg flag to true will launch an optional invitation dialog before the meeting invitations are sent. This dialog enables the end user to select the participants of the meeting using the dialog UI. Inviting to an existing meeting A user usually invites another user to an existing meeting using the meeting UI. At any time a meeting participant can select “Invite others” from a menu to open the Invitation dialog to invite other users to the meeting. The application itself can also invite users using the following method: inviteToMeeting(MeetingInfo info, Place place, String inviteText, STUser[] invitees, boolean showInviteDlg, boolean autoJoin); The meeting is described by a MeetingInfo object (described below). Also, the place object in which the meeting is held is required. Receiving Invitations to Meetings The Chat UI component enables you to receive instant messages (IMs) and invitations to meetings from other users in the community. When a user initiates an IM with you, a message window will pop up automatically. For meetings, a Join dialog will pop up with the meeting description, which allows you to decide if you want to join the meeting. By default, Chat UI only accepts invitations to chat meetings. Meetings that include IP Audio, IP Video, or Application Sharing capabilities are launched in a separate browser window using the Meeting Room Client (MRC). Launching a browser is dependent on the toolkit’s environment and therefore the toolkit does not include code to do so. Therefore, in order for an application to be able to participate in such meetings it should register itself as a MeetingListener by calling addMeetingListener(). Whenever Chat UI wants to launch Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 43 Chapter 3. Community UI Components the MRC, the launchMeeting() event will be generated with a MeetingInfo object describing the meeting and a URL object with the URL that the browser needs to be pointed to. A typical implementation of this event handler for an applet is: Public void launchMeeting(MeetingInfo info, URL url) { applet.getAppletContext().showDocument(URL); } Handling the UrlClicked() Event By default, text in a URL format will be shown underlined inside a chat transcript window of an IM or chat meeting. When a user clicks on the URL, an event is fired. An application should register as a UrlClickListener by calling the addUrlClickListener() method to handle this case. A typical implementation of this event handler is: public void urlClicked(UrlClickEvent event) { String urlString = event.getURL(); URL url; try { url = new URL(urlString); } catch (MalformedURLException e) { return; } applet.getAppletContext().showDocument(url); } Customizing Chat UI behavior You can alert users when a new one-on-one chat message arrives. The following table lists the types of alerts and how to set them. Type of Alert How to Set Audible beep setBeepOnMessage(Boolean beep); Blink on the frame title set/getBlinkOnMessage(Boolean blink); Message pops up on top of other windows set/getToFrontOnMessage(Boolean toFront); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 44 Chapter 3. Community UI Components If more than one IM window is opened, the windows will be cascaded. The application can set the cascading direction. The windows can either open from the top right corner and cascade to the left, or open from the top left corner and cascade to the right. Use: SetCascadingDirection(in direction); where the possible directions are ChatUI.CASCADE_LEFT and ChatUI.CASCADE_RIGHT. Package com.lotus.sametime.chatui See Also The Instant Messaging Service section of this guide The Places Service section of this guide Example The following example contains an applet that logs on to the Sametime community and allows you to initiate (and receive) instant messages and all the possible types of Sametime meetings. Enter the user names, select the meeting type, select whether you want to display the Invite dialog before you send the invitation, and click the “Send” button. You can run this Chat UI Component sample from the Java Toolkit Samples page. import import import import import import java.applet.Applet; java.awt.*; java.awt.event.*; java.net.*; java.util.Vector; java.util.StringTokenizer; import com.lotus.sametime.chatui.*; import com.lotus.sametime.core.comparch.*; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 45 Chapter 3. Community UI Components import import import import com.lotus.sametime.core.types.STUser; com.lotus.sametime.community.*; com.lotus.sametime.commui.*; com.lotus.sametime.core.constants.MeetingTypes; /** * A sample of the chat ui component. */ public class ChatUIApplet extends Applet implements LoginListener, MeetingListener, UrlClickListener, ActionListener, CommUIListener { /** * The session. */ private STSession m_session; /** * The chat ui component. */ private ChatUI m_chatUI; /** * The community ui component. */ private CommUI m_commUI; /** * The number of names that are waiting to be resolved. */ private int m_namesToResolve; /** * The list of resolved meeting users. */ private Vector m_meetingUsers = new Vector(); /** * The 'meeting type' choice. */ private Choice m_chType; /** * The user names text field. */ private TextField m_tfInvitees; /** * The 'send' button. */ private Button m_btnSend; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 46 Chapter 3. Community UI Components /** * The 'Show invite dialog' check box. */ private Checkbox m_cbInviteDlg; /** * Applet life cycle */ public void init() { // Create a session of components. try { m_session = new STSession("ChatUIApplet"); m_session.loadAllComponents(); m_session.start(); } catch(DuplicateObjectException e) { e.printStackTrace(); } initializeLayout(); // Login to the community. String serverName = getCodeBase().getHost().toString(); String loginName = getParameter("loginName"); String password = getParameter("password"); CommunityService comm = (CommunityService)m_session.getCompApi (CommunityService.COMP_NAME); comm.addLoginListener(this); comm.loginByPassword(serverName, loginName, password); m_chatUI = (ChatUI)m_session.getCompApi(ChatUI.COMP_NAME); m_chatUI.addUrlClickListener(this); m_chatUI.addMeetingListener(this); m_commUI = (CommUI)m_session.getCompApi(CommUI.COMP_NAME); m_commUI.addCommUIListener(this); } /** * Applet destroyed. Stop and unload the session. */ public void destroy() { CommunityService comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); comm.logout(); m_session.stop(); m_session.unloadSession(); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 47 Chapter 3. Community UI Components // // Login Listener. // /** * Logged in to the community. */ public void loggedIn(LoginEvent event) { System.out.println("Applet: LOGGED IN"); m_btnSend.setEnabled(true); } /** * Logged out of the community. */ public void loggedOut(LoginEvent event) { System.out.println("SAMPLE: LOGGED OUT. REASON=" + event.getReason()); m_btnSend.setEnabled(false); } // // Action Listener. // /** * Send button was clicked. */ public void actionPerformed(ActionEvent p1) { String[] userNames = breakString(m_tfInvitees.getText(), ","); if (userNames == null || userNames.length == 0) { return; } // Disable the send button until wer'e finished. m_btnSend.setEnabled(false); // Try to resolve the names. m_namesToResolve = userNames.length; for (int i=0; i < m_namesToResolve; i++) { m_commUI.resolve(userNames[i]); } } // // CommuiListener. // /** * Resolve request succeded. */ public void resolved(CommUIEvent event) { STUser resolved = event.getUser(); m_meetingUsers.addElement(resolved); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 48 Chapter 3. Community UI Components if (--m_namesToResolve == 0) { createMeeting(); } } /** * Resolve request failed. */ public void resolveFailed(CommUIEvent event) { if (--m_namesToResolve == 0) { createMeeting(); } } /** * All names resolved. Create the meeting. */ private void createMeeting() { m_btnSend.setEnabled(true); String meetingType = m_chType.getSelectedItem(); // Check if it is an 1on1 instant message. if ((meetingType == "Chat") && m_meetingUsers.size() == 1) { STUser imPartner = (STUser)m_meetingUsers.firstElement(); m_chatUI.create1On1ChatById(imPartner); m_meetingUsers.removeAllElements(); return; } // Create the meeting type accoding to the selected string. MeetingTypes type = null; if (meetingType == "Chat") { type = MeetingTypes.ST_AUDIO_MEETING; } else if (meetingType == "Audio") { type = MeetingTypes.ST_AUDIO_MEETING; } else if (meetingType == "Video") { type = MeetingTypes.ST_VIDEO_MEETING; } else if (meetingType == "Share") { type = MeetingTypes.ST_SHARE_MEETING; } else if (meetingType == "Collaboration") { type = MeetingTypes.ST_COLLABORATION_MEETING; } STUser[] invitees = new STUser[m_meetingUsers.size()]; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 49 Chapter 3. Community UI Components m_meetingUsers.copyInto(invitees); boolean showInviteDlg = m_cbInviteDlg.getState(); m_chatUI.createMeeting(type, "", "", showInviteDlg, invitees); m_meetingUsers.removeAllElements(); } // // Meeting Listener. // /** * Open the meeting room client to participate in a meeting. * This event is received as a result of this user initiating * a meeting or being invited to join a meeting by a different * user. */ public void launchMeeting(MeetingInfo meetingInfo, URL url) { getAppletContext().showDocument(url, meetingInfo.getDisplayName()); } /** * An error has occurred during a meeting creation. */ public void meetingCreationFailed(MeetingInfo meetingInfo, int reason) { System.err.println("Failed to create the meeting: " + reason); } // // Url Click Listener. // /** * Url was clicked. Open it. */ public void urlClicked(UrlClickEvent event) { URL url; String urlString = event.getURL(); try { url = new URL(urlString); } catch(MalformedURLException e) { System.err.println("URL Clicked: MALFORMED URL"); return; } getAppletContext().showDocument(url); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 50 Chapter 3. Community UI Components // // Helpers. // /** * Set up the ui components. */ void initializeLayout() { m_chType = new Choice(); m_chType.add("Chat"); m_chType.add("Audio"); m_chType.add("Video"); m_chType.add("Share"); m_chType.add("Collaboration"); Panel p = new Panel(new GridLayout(3,1)); Panel p1 = new Panel(); p1.add(m_btnSend = new Button("Send")); p1.add(m_cbInviteDlg = new Checkbox("Show Invite Dialog", true)); Panel p2 = new Panel(new GridLayout(3,1)); p2.add(new Label("Meeting type:")); p2.add(m_chType); p2.add(p1); Panel p3 = new Panel (new BorderLayout()); p3.add(new Label("Invitees names (divided by ,):"), BorderLayout.CENTER); p3.add(m_tfInvitees = new TextField(),BorderLayout.SOUTH ); p.add(p3); p.add(p2); p.add(p1); add(p); m_btnSend.addActionListener(this); // Enable sending only when we are logged in. m_btnSend.setEnabled(false); } /** * Break a string into an array of smaller strings, based on a given * separator char. */ protected String[] breakString(String toBreak, String separator) { String[] result = null; if (toBreak != null && !toBreak.equalsIgnoreCase("")) { if (separator == null || separator.equalsIgnoreCase("")) { result = new String[1]; result[0] = toBreak; } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 51 Chapter 3. Community UI Components else { StringTokenizer stk = new StringTokenizer(toBreak, separator); result = new String[stk.countTokens()]; for (int i = 0; i < result.length && stk.hasMoreTokens(); i++) result[i] = stk.nextToken(); } return result; } } Customizing the Chat UI Component Overview Customizing the Chat UI component provides the ability to customize the chat window without having to design a new window. You can customize the chat window by: • Adding user panels to three fixed positions • Adding menus and menu items to the window menu bar • Customizing the text before it is sent to the chat session Customizing the Chat UI component allows the addition of more features to the chat window to suit the user’s specific needs. Note These changes appear in both the IM and conference windows. Description To customize the Chat UI, you will need to create a new class that extends the DefaultChatFactroy and overrides it with the needed functions. The DefaultChatFactroy, which implements the ChatFactory interface, responds to calls from the ChatUI components by generating the appropriate UI component for the request. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 52 Chapter 3. Community UI Components Below are examples of the regular and customized chat windows: Adding user panels This section describes: • Adding a Logo Panel • Adding Buttons Panel You can add up to three panels by overriding this method: public Panel getCustomizedPanels(int panelPosition, ChatFrame frame) The first parameter is panelPosition. The table below identifies the position of the constants on the panel: Constants Position DefaultChatFactory. TOP_PANEL On top on the user panel under the menu. DefaultChatFactory. CENTER_PANEL In the center on the user panel above of the buttons. DefaultChatFactory. BOTTOM_PANEL At the bottom on the user panel above the status bar. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 53 Chapter 3. Community UI Components Below is an example of the possible positions: The second parameter is ChatFrame, the container for the customized panels. The method getCustomizedPanels returns the panel associated with the requested position. A typical implementation of this method is: public Panel getCustomizedPanels(int panelPosition, ChatFrame frame) { … if (panelPosition == TOP_PANEL) return createLogoPanel("logo.gif"); if (panelPosition == CENTER_PANEL) return ShortcutButtons(frame); if (panelPosition == BOTTOM_PANEL) return createLogoPanel("logo.gif"); return null; } The panel can contain image buttons, banners, links, and more. The ChatFrame will insert the user panel into the specified position. Adding a Logo Panel In the given sample, the top and bottom panels each contain a logo. The logo panels are created by the following method: private Panel CreateLogoPanel(String logo) { Panel p = new ImagePanel(getLogoURL(logo)); p.setBackground(new Color(0xFFcc00)); return p; } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 54 Chapter 3. Community UI Components The getLogoURL(logo) returns the URL of the image (where the samples are). The ImagePanel creates a panel with the image that was given in the constructor. The complete code is available for download from the Java Toolkit section on the Sametime server. Adding Buttons Panel On the center panel there are two buttons that send pre-prepared messages and a check box to add a time stamp to the sent text. (See the Modify Written Text section of this chapter for more information.) The center panel is created by the following method: public Panel ShortcutButtons(ChatFrame frame) The complete code is available for download from the Java Toolkit section on the Sametime server. Adding a Menu and Menu Items Another way to customize the chat window is to add a menu to the menu bar by overriding the method: public void getCustomizedMenu(MenuBar mb) You now have access to the frames MenuBar and you are able to add menus and menu items. In the following sample code, a typical implementation of this method is used to add a help menu with an “About” menu item. public void getCustomizedMenu(MenuBar mb) { Menu helpMenu = new Menu("Help"); MenuItem about = new MenuItem("About"); about.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { try { m_applet.getAppletContext().showDocument(newURL("http://www.lotus.c om/home.nsf/welcome/sametime"),"target"); } catch (MalformedURLException e) { e.printStackTrace(); } } }); helpMenu.add(about); mb.add(helpMenu); } Note The existing menus (Meeting and Edit) cannot be modified. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 55 Chapter 3. Community UI Components Modify Written Text The ability to intercept text before it is sent enables you to modify the original text into a customized version. This ability is useful, to add a check spelling service to the chat for example; or as in our sample, to add a time stamp to the written text. In order to intercept text messages, a developer needs to perform the following steps. A TextModifier listener has to be attached to the ChatFrame. This is done by implementing the TextModifier interface that includes only the method shown below: public String TextSubmitted(String text) This function is called every time the text is submitted. Prior to being sent, the method gets the typed text, modifies it, and returns the modified text to be sent. To return the object that implements the TextModifier interface, you must override the method. Overriding the DefaultChatFactory’s method: public TextModifier getTextModifier(ChatFrame frame) This method is called by each ChatFrame, upon its initialization, to get the appropriate TextModifier that will be associated with this frame. If it is not implemented, this method will return the default TextModifier that is set to null. In our sample, the newChatFactory implements the TextModifier interface. In the center panel is a check box that adds the time to the chat message that was written. Changing the status of the check box enables/disables adding the time stamp. Note The following is the implementation of this method: Enable/disable the time stamp public String TextSubmitted(String text) { if(m_addTime.getState()) { text =getTimeStamp ()+text; } return text; } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 56 Chapter 3. Community UI Components In the sample, the current time is taken from the system and attached to the beginning of the sent message. Example The sample shown on the server (and shown in the above screen shot) opens a customized chat window that contains two logo panels, one at the top and one at the bottom. The sample also contains a center panel that contains buttons that send pre-prepared messages, and a check box that adds a time stamp to the written text. A help menu was added to the modified chat window. Note To view the complete code, you need to download the sample from the server. The sample contains three classes: • CustomizeChatUI – Extends an Applet and sets the NewChatFactory as the ChatFactory for the ChatUI component • CustomizeChatFactory – Extends the DefaultChatFactory and provides customized UI • ImagePanel – Creates a panel with an image Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 57 Chapter 3. Community UI Components Community UI Component Overview The Community UI component provides the following capabilities: • Display of messages when the user is disconnected from the community. The message includes a short text description of the specific reason. • Display of administrator messages that are sent to the entire community. • Resolving user names in the community. When more than one user match is found, a dialog allowing the end user to select the appropriate match is displayed. Description The following is a dialog of an administrator message: When you resolve user names and more than one match is found, the following dialog is displayed: Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 58 Chapter 3. Community UI Components To resolve a user name using the Community UI: 1. Get a reference to the Community UI component: CommUI commUI = (CommUI) m_session.getCompApi(CommUI.COMP_NAME); 2. Listen to community UI events by calling the addCommUIListener() method and passing a class that implements CommUIListener or extends CommUIAdapter. 3. Call the resolve method with the required user name: commUI.resolve("admin"); 4. You can receive the following event notifications as a response to the resolve request: • resolved() – the user name was resolved successfully • resolveFailed() – the user name was not resolved 5. If the more then one match is found for the user name, a dialog will be launched (see above) and the end user can then make a selection. After the users makes a selection, a resolved() event will be fired with the selected user details. Package com.lotus.sametime.commui See Also The Community Services section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 59 Chapter 3. Community UI Components FileTransfer UI Component Overview The FileTransfer UI component provides the ability to send and receive files without having to deal with the low-level protocols that are involved. It includes the SendFile dialog, used for choosing the file to send and initiating the file transfer; the ReceiveFile dialog for accepting or declining the file transfer; and the FileTransferStatus dialog that indicates the progress of the transfer on both sides. Note that if you are creating an applet that supports file transfer, you must sign the applet, to allow local file access. Description You must load the FileTransfer UI component into the Sametime session object, like any other toolkit component. The FileTransfer UI component listens to events from the FileTransfer Service and notifies the user of incoming file transfers. It can also be used to easily initiate file transfers. Sending Files To send a file, call the sendFile() method of the FileTransferUI Service. This method takes the remote user’s STUser object as a parameter. A SendFile dialog opens, letting the user choose a file to send and add a description. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 60 Chapter 3. Community UI Components When the user clicks Send, a FileTransfer object is created. The transfer starts as soon as the other side accepts it. Then the FileTransferStatus dialog opens, indicating the progress of the transfer. If you want to get notifications when the file transfer is completed or stopped, implement the FileTransferUIListener interface and use the addFileTransferUIListener() method of the FileTransfer Service to register the listener object, before you call the sendFile() method. Receiving Files To receive file transfers, you need only load the FileTransfer UI component into the Sametime session object. The FileTransfer UI component listens to events from the FileTransfer Service, and opens a ReceiveFile dialog as soon as a file transfer request is received. The user can either accept or decline the transfer. If the user accepts, a FileTransferStatus dialog opens, indicating the progress of the transfer. After successful completion, the user can open the file directly from the FileTransferStatus dialog. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 61 Chapter 3. Community UI Components If you want to get notifications when the file transfer is completed or stopped, implement the FileTransferUIListener interface and use the addFileTransferUIListener() method of the FileTransferUI Service to register the listener object, before you call the accept() method. Package com.lotus.sametime.filetransferui See Also The FileTransfer Service section of this guide Example This example consists of two classes: UIFileSenderSample and UIFileReceiverSample. UIFileSenderSample displays a ‘Send a File’ button. After clicking this button, the user sees the SendFile dialog of the toolkit, and can select the file to send. The transfer starts when the user clicks Send. When the transfer is completed, the user can send another file by clicking ‘Send a File’ again. The receiver logs in and then waits for a file transfer. Upon receiving a file transfer, the toolkit creates a ReceiveFile dialog and the user can accept the transfer or decline it. After the transfer is completed, the receiver waits for another transfer. To run this example, simply copy the code and change the constants defined at the beginning of each class to real values from your community. Be sure to run the receiver before you click the Send button, because the receiver must be already logged in when the sender tries to send the file. import java.util.Date; import java.awt.*; import java.awt.event.*; import import import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.types.*; com.lotus.sametime.core.util.Debug; com.lotus.sametime.community.*; com.lotus.sametime.lookup.*; com.lotus.sametime.filetransferui.*; public class UIFileSenderSample extends Frame implements LoginListener, FileTransferUIListener, ResolveListener, ActionListener { // replace all these constants with real values from your // community private final static String SERVER_NAME = "server_name"; private final static String SENDER_NAME = "sender_user_name"; private final static String PASSWORD = "sender_password"; private final static String RECEIVER_NAME = "receiver_user_name"; private STSession m_session; private CommunityService m_comm; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 62 Chapter 3. Community UI Components private private private private String m_remoteUserName; FileTransferUI m_fileTransferUI; Button m_sendBtn; STUser m_receiver; public UIFileSenderSample(String host, String userName, String password, String remoteUserName) { try { m_session = new STSession("UIFileSenderSample " + this); m_session.loadAllComponents(); m_session.start(); Frame frame = findParentFrame(); System.err.println("Mainframe = " + frame); m_session.setSessionProperty("mainFrame", frame); m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); m_remoteUserName = remoteUserName; m_sendBtn = new Button("Send A File"); m_sendBtn.setEnabled(false); m_sendBtn.addActionListener(this); add(m_sendBtn,BorderLayout.CENTER); pack(); setVisible(true); FileTransferUI fileTransferUISvc = (FileTransferUI) m_session.getCompApi(FileTransferUI.COMP_NAME); fileTransferUISvc.addFileTransferUIListener(this); m_comm.loginByPassword(host, userName, password); } } catch(DuplicateObjectException e) { e.printStackTrace(); } /** * Main */ public static void main(String[] args) { UIFileSenderSample uIFileSenderSample1 = new UIFileSenderSample(SERVER_NAME ,SENDER_NAME, PASSWORD, RECEIVER_NAME); } // // LoginListener // Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 63 Chapter 3. Community UI Components /** * Logged in event. */ public void loggedIn(LoginEvent event) { System.out.println("Logged In"); m_fileTransferUI = (FileTransferUI) m_session.getCompApi(FileTransferUI.COMP_NAME); LookupService lookupSvc = (LookupService) m_session.getCompApi(LookupService.COMP_NAME); } Resolver resolver = lookupSvc.createResolver(true, true, true, false); resolver.addResolveListener(this); resolver.resolve(m_remoteUserName); /** * Logged out event. */ public void loggedOut(LoginEvent event) { System.out.println("Logged Out"); m_session.stop(); } // // ResolveListener // /** * A resolve request has been performed, and a match was found. * * @param event The event object. * @see ResolveEvent#getName * @see ResolveEvent#getResolved */ public void resolved(ResolveEvent event) { m_receiver = (STUser)event.getResolved(); } Frame frame = new Frame("the frame"); m_sendBtn.setEnabled(true); /** * A resolve request has been performed, and multiple matches have * been found. * * @param event The event object. * @see ResolveEvent#getName * @see ResolveEvent#getResolvedList */ public void resolveConflict(ResolveEvent event) { System.out.println("FileSender Resolve conflict"); m_comm.logout(); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 64 Chapter 3. Community UI Components /** * A resolve request failed. * * @param event The event object. * @see ResolveEvent#getReason * @see ResolveEvent#getFailedNames */ public void resolveFailed(ResolveEvent event) { System.out.println("FileSender Resolve Failed"); m_comm.logout(); } // // ActionListener // public void actionPerformed(ActionEvent event) { //send the file m_fileTransferUI.sendFile(m_receiver); } // // FileTransferUIListener // /** * Notification sent when a file transfer session has been completed * successfully. */ public void fileTransferCompleted(FileTransferUIEvent event) { Date date = new Date(); System.out.println("File Transfer Completed: " + event.getFileName() + " Time: " + date.toString()); } /** * Notification sent when a session has been stopped/terminated. */ public void fileTransferFailed(FileTransferUIEvent event) { System.out.println("File Transfer Failed reason: " + event.getReason() + "File: " + event.getFileName()); } // // Helpers // /** * Find the parent frame of this applet. */ public Frame findParentFrame() { Frame frame = null; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 65 Chapter 3. Community UI Components Container c = this.getParent(); while(c != null) { if(c instanceof Frame) { frame = (Frame)c; break; } } } c = c.getParent(); } return frame; import java.util.Date; import java.awt.*; import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.community.*; com.lotus.sametime.core.util.Debug; com.lotus.sametime.filetransferui.*; public class UIFileReceiverSample extends Frame implements LoginListener, FileTransferUIListener { // replace all these // community private final static private final static private final static constants with real values from your String SERVER_NAME = "server_name"; String RECEIVER_NAME = "receiver_user_name"; String PASSWORD="receiver_password"; private STSession m_session; private CommunityService m_comm; public UIFileReceiverSample(String host, String userName, String password) { try { m_session = new STSession("UIFileReceiverSample " + this); m_session.loadAllComponents(); m_session.start(); Frame frame = findParentFrame(); System.err.println("Mainframe = " + frame); m_session.setSessionProperty("mainFrame", frame); m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); FileTransferUI fileTransferUISvc = (FileTransferUI) m_session.getCompApi(FileTransferUI.COMP_NAME); fileTransferUISvc.addFileTransferUIListener(this); m_comm.loginByPassword(host, userName, password); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 66 Chapter 3. Community UI Components } } catch(DuplicateObjectException e) { e.printStackTrace(); } /** * Main. */ public static void main(String[] args) { UIFileReceiverSample uiFileReceiverSample1 = new UIFileReceiverSample(SERVER_NAME ,RECEIVER_NAME, PASSWORD); } // // LoginListener // /** * Logged in event. */ public void loggedIn(LoginEvent event) { System.out.println("Logged In"); } /** * Logged out event. */ public void loggedOut(LoginEvent event) { System.out.println("Logged Out"); m_session.stop(); } // // FileTransferUIListener // /** * Notification sent when a file transfer session has been completed * successfully. */ public void fileTransferCompleted(FileTransferUIEvent event) { Date date = new Date(); System.out.println("File Transfer Completed: " + event.getFileName() + " Time: " + date.toString()); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 67 Chapter 3. Community UI Components /** * Notification sent when a session has been stopped/terminated. */ public void fileTransferFailed(FileTransferUIEvent event) { System.out.println("File Transfer Failed reason: " + event.getReason() + "File: " + event.getFileName()); } // // Helpers // /** * Find the parent frame of this applet. */ public Frame findParentFrame() { Frame frame = null; Container c = this.getParent(); while(c != null) { if(c instanceof Frame) { frame = (Frame)c; break; } c = c.getParent(); } return frame; } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 68 Chapter 4. Community Services Introduction The following Sametime Community Services are provided by the toolkit: • Announcement Service • Buddy List Service • Community Service • Directory Service • FileTransfer Service • Instant Messaging Service • Lookup Service • Names Service • Places Service • Post Service • Storage Service • Token Service Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 69 Chapter 4. Community Services Announcement Service Overview An announcement is a one-way message that can be sent to one or more people. The Announcement Service provides the ability to send and receive announcements between Sametime users. Description Every Sametime user can send announcement messages to other users in the community. You can send an announcement to a list of STUser and STGroup (public group) instances. The message will be sent only to users who are online. To use the Announcement Service, you must load the BLService component into the Sametime session object, like any other toolkit component. To send an announcement, use the sendAnnouncement() method. To receive announcements, you must implement the AnnouncementListener interface, which contains the single method announcementReceived(). Use the addAnnouncementListener() method to add the listener to the list of listeners for your Announcement Service instance. Package com.lotus.sametime.announcement See Also The Announcement UI section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 70 Chapter 4. Community Services Awareness Service Overview The Awareness Service provides the ability to know the online status of different kinds of Sametime objects such as users, groups, and servers. Using this service, you can register to receive notifications of changes in the online status of users and the online attributes of users and Sametime servers. This service is sometimes referred to as “People Awareness.” Description The Awareness Service provides the ability to receive notifications on changes in the status of Sametime objects. The table below summarizes the supported objects, all derived from STObject, and the type of notifications you can receive on each object. Object Name Status Notification Attribute Notification STUser 9 9 STGroup 9 9 STServer 9 Notifications for STGroup objects are not actually about the group. They are about the online users in the group, as defined by the administrator in the directory. You will not receive any notifications for users in the group who are offline, except to notify you that an online user is now offline. Sametime server attributes are used to broadcast different capabilities of a Sametime server to all clients connected to that server. For example, a server attribute is used to notify clients whether directory browsing is available on this server. User Status Status events are generated whenever a Sametime user changes his online status and are returned as STWatchedUser objects derived from STUser. A status event could be a change from offline to online, from online to offline, or a status change while being online. An online user in Sametime has four standard statuses: Active, Away, Automatic Away, and Do Not Disturb. The Automatic Away is displayed in the UI with the same icon as Away, but indicates that the application assumes that you are not available. For example, Sametime Connect changes your status to Automatic Away when you have not touched your mouse or keyboard for a predetermined amount of time. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 71 Chapter 4. Community Services Sametime Attributes Attribute events are generated whenever a Sametime user or server changes or removes one of its online attributes. A Sametime attribute (STAttribute) has a key and a value, where the value can be a Boolean, integer, long, string, or byte array. The last login to change the attribute value overrides any previous value of the attribute. When an attribute event is generated, the attribute is returned as an STExtendedAttribute object. STExtendedAttribute is derived from STAttribute and includes additional information on the attribute. The two special types of Sametime attributes are Existential Attributes and Heavy Attributes. Existential Attributes An existential attribute is an attribute that has no value. Its existence or non-existence is by itself an indication of some state. For example, Sametime uses an existential attribute to indicate whether or not a user has a video camera installed. An existential attribute stays set until the last login that set it logs out. For example, if a user Joe sets an extended attribute, anyone watching Joe will receive an attributeChanged() event. Then a second login of Joe sets the same existential attribute. No one will receive any event because this attribute was set by the first login. Now the first login of Joe logs out. (He closes the client.) Again, no one will receive any attributeChanged() event because the second login is still “holding” this attribute. Only when the second login removes the attribute or logs out will all the other users of the community receive the attrRemoved() event. Existential attributes are used to publish properties shared by all logins of a given user. Use the isExistential() method of STExtendedAttribute to find out whether or not an attribute is existential. Heavy Attributes Heavy attributes are attributes that have a “heavy” value. The Awareness Service defines some byte limit over which a value is considered heavy. All users who are aware of a specific user receive notifications on his attributes changes. If this attribute is large, the notification will create a lot of network traffic and load the Sametime server. Instead, if the attribute is considered heavy, the Awareness Service notifies all the interested users that a specific user has changed his attribute, but it does not provide the value part of the attribute. Use the getActualSize() method of STExtendedAttribute to determine if a returned attribute is heavy. The attribute is heavy if it is not existential and the returned actual size is 0. To retrieve the value of a heavy attribute, call the queryAttrContent() method of the WatchList object that contains the watched Sametime object. If you want to know the expected size of the heavy attribute before querying for it, use the getSize() method of STExtendedAttribute. Attribute Filter Most applications are only interested in a subset of the possible attributes. The Awareness Service requires that you define a list of attribute keys about which you want to receive notifications. This list is a single global list for all watch lists. It is called the attribute filter. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 72 Chapter 4. Community Services Using the Awareness Service The Awareness Service provides several functions: • Tracking the availability of the Awareness Service • Creating WatchList objects • Finding a specific user’s status • Setting the attribute filter • Changing your own online attributes Tracking the Availability of the Awareness Service Tracking Awareness Service availability is important so that you know when you are receiving awareness updates in real-time and when you are not receiving any notifications due to a network or server problem. At any point in time, you can call the isServiceAvailable() method of the Awareness Service to find out current service availability. A better way to track the service is to use the AwarenessServiceListener, which provides two events: serviceAvailable() and serviceUnavailable(). By registering to this listener you will receive events whenever the service availability changes. If for any reason the service becomes unavailable, the Awareness Service component will immediately attempt to restore connection to the service and will notify you when the connection has been restored. Creating WatchList Objects Awareness of users and other Sametime objects is achieved using a WatchList object. You create a new WatchList by calling the Awareness Service method createWatchList(). See the Using Watch Lists section below for information on how to use WatchList objects. Finding a Specific User’s Status If you want to determine the status of a specific user and you know he is already in one of your WatchList objects, you can call the Awareness Service method findUserStatus(). This method returns the status of the user if found after searching all the WatchList objects. Setting the Attribute Filter Use the setAttrFilter(), addToAttrFilter(), and removeFromAttrFilter() methods of the Awareness Service to modify the global attribute filter. Modify the attribute filter before adding any items to your watch lists; by default, the filter is empty and no attribute notifications are received. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 73 Chapter 4. Community Services Changing Your Own Online Attributes You can change your own login attributes by using the changeMyAttr() and removeMyAttr() methods of the Awareness Service. Use a MyAttributeListener object to receive events on whether these attribute changes and removals were successful. Using Watch Lists As previously mentioned, awareness on Sametime objects is achieved with the WatchList class. A WatchList is a list of watched Sametime objects. Once you have created a WatchList object by using the createWatchList() method of the Awareness Service you can: • Add Listeners to receive status and attribute change events. • Add/Remove Sametime objects to/from the WatchList. • Query for the content of heavy attributes. You can add three types of Sametime objects to your watch lists: STUser, STGroup, and STServer objects. The table below describes the methods related to these watch list objects. Method Description addItem() Adds a single object to a watch list. addItems() Adds multiple objects to a watch list. removeItem() Removes a single object from the watch list and stops receiving events about the object. removeItems() Removes multiple objects from the watch list and stops receiving events about the objects. reset() Removes all current Sametime objects from the watch list. close() Allows the Awareness Service to “clean up” after the object is removed. The object cannot be used after a call to this method is made. Receiving Events From a WatchList The two types of events that can be received on Sametime objects in a WatchList are status events and attribute events. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 74 Chapter 4. Community Services Receiving Status Events To receive status events, implement the StatusListener interface and add it to the WatchList with the addStatusListener() method. StatusListener has two event handlers: • userStatusChanged() – This event handler is called when one or more users have changed their online status. Use the getWatchedUsers() method of the event object to retrieve the array of STWatchedUser objects whose status has changed. • groupCleared() – This event handler is called when the Awareness Service requests to clear the list of users in a Sametime group. Use the getGroup() method of the event object to retrieve the STGroup object whose users should be cleared. Any UI displaying the online users of a Sametime group should remove these users accordingly. Immediately after this event, the Awareness Service will resend a userStatusChanged() event for each of the online users of the group. This event is relatively rare; but it can happen if, for example, an administrator changes the contents of a Sametime group in the directory. Receiving Attribute Events To receive attribute events, implement the AttributeListener interface and add it to the WatchList with the addAttributeListener() method. AttributeListener has four event handlers. Use the getWatchedObject() method of the event object to find out which item in the list each event refers to for all four event handlers. The event handlers are: • attrChanged() – Called when the attributes of an item in the WatchList have changed. Use the getAttributeList() method of the event object to retrieve the array of changed attributes. • attrRemoved() – Called when an attribute of a Sametime object in the WatchList has been removed by its owner. For example, if a user we are currently watching has first set some attribute concerning himself and then decided to remove this attribute, you will first receive the attrChanged() event and then the attrRemoved() event concerning this user. • attrContentQueried() – Called if the content of a heavy attribute has been successfully retrieved. To retrieve the contents of a heavy attribute you must call the queryAttrContent() method of the WatchList. Use the getAttribute() method of the event object to retrieve the returned heavy attribute. • queryAttrContentFailed() – Called if the queryAttrContent() request has failed for any reason. Use the getAttributeKey() method to find out the attribute key this failed event refers to and use the getReason() method to retrieve the reason code for the failure. Package com.lotus.sametime.awareness Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 75 Chapter 4. Community Services See Also The Awareness List section of this guide Example This example demonstrates use of the Awareness Service by showing how you can add users to a list of "watched" users. Whenever the online status of a user in the list changes, the change is displayed by the example applet. import import import import import import import import import import import import java.awt.*; java.applet.*; java.awt.event.*; java.util.*; com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.constants.*; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.awareness.*; com.lotus.sametime.commui.*; com.lotus.sametime.guiutils.chat.ChatArea; public class AwarenessApplet extends Applet implements LoginListener,CommUIListener, AwarenessServiceListener, StatusListener, ActionListener { private STSession m_session; private CommunityService m_comm; private CommUI m_commUiService; private AwarenessService m_awareness; private WatchList m_watchList; private private private private private String m_myName =""; TextField m_watchName = new TextField(); Button m_addBtn = new Button("Add"); Font m_font = new Font("Dialog",12,Font.PLAIN); ChatArea m_transcript = new ChatArea(150,m_font,50); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 76 Chapter 4. Community Services public void init() { try { m_session = new STSession("ImApplet" + this); m_session.loadAllComponents(); } catch(DuplicateObjectException e) { e.printStackTrace(); } m_session.start(); initLayout(); login(); } /** * set the applet layout */ private void initLayout() { setLayout(new BorderLayout(0,0)); Font labelFont = new Font("Dialog",14,Font.PLAIN); Panel pnl = new Panel(new BorderLayout(0,0)); pnl.add(new Label("Watch user name:"),BorderLayout.NORTH); pnl.add(m_watchName,BorderLayout.CENTER); pnl.add(m_addBtn,BorderLayout.EAST); m_addBtn.addActionListener(this); add(pnl,BorderLayout.NORTH ); add(m_transcript,BorderLayout.CENTER); validate(); } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); m_comm.loginByPassword(getCodeBase().getHost().toString(), getParameter("loginName"), getParameter("password")); } /** * Loggedin event receive only if loggedin successfully */ public void loggedIn(LoginEvent event) { m_myName = m_comm.getLogin().getMyUserInstance().getDisplayName(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 77 Chapter 4. Community Services m_transcript.writeSeparator("Loggedin :"+m_myName, Color.green); m_awareness = (AwarenessService) m_session.getCompApi(AwarenessService.COMP_NAME); m_awareness.addAwarenessServiceListener(this); m_commUiService = (CommUI ) m_session.getCompApi(CommUI.COMP_NAME); m_commUiService.addCommUIListener(this); } /** * Loggedin event receive only if loggedout */ public void loggedOut(LoginEvent event) { m_transcript.writeSeparator("Loggedout :"+m_myName, Color.green); } /** * if the send button was pressed take the name form the textField * and resolve for appropriate user */ public void actionPerformed(ActionEvent event) { m_commUiService.resolve(m_watchName.getText()); } /** * resolved event receive aftere you send request to resolve a name */ public void resolved(CommUIEvent event) { m_watchList.addItem(event.getUser()); } /** * resolveFailed event receive aftere you send request to resolve * a name but no approrriate user was found. */ public void resolveFailed(CommUIEvent event) { m_transcript.writeSeparator("resolve failed type another name" , Color.red); } /** * Indicates that the awareness service is currently available. */ public void serviceAvailable(AwarenessServiceEvent event) { m_watchList = m_awareness.createWatchList(); m_watchList.addStatusListener(this); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 78 Chapter 4. Community Services /** * Indicates that the awareness service is currently unavailable. */ public void serviceUnavailable(AwarenessServiceEvent event) { m_transcript.writeSeparator("Awareness service unavailable" , Color.red); } /** * Indicates one or more users status' have changed. */ public void userStatusChanged(StatusEvent event) { STWatchedUser[] users =(STWatchedUser[])event.getWatchedUsers(); for(int i=0; i<users.length; i++) { STUserStatus userStatus = users[i].getStatus(); String statusDescription = users[i].getStatus().getStatusDescription(); if (users[i].getStatus().getStatusType()== 0) { statusDescription= "user is offline"; } String message = users[i].getDisplayName()+" : " + statusDescription; m_transcript.writeSeparator(message , Color.black); } } /** * Indicates the awareness service has cleared the list of users * in a Sametime group. Any UI displaying the online users of a * Sametime group should remove these users accordingly. */ public void groupCleared(StatusEvent event) { m_transcript.writeSeparator("group cleared" , Color.red); } public void destroy() { m_comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 79 Chapter 4. Community Services Buddy List Service Overview The Buddy List Service provides the ability to get a user’s contact list from the user storage on the Sametime server, or to store it there. It also provides conversion methods between String and BL objects. These capabilities enable the developer to avoid dealing with the low-level protocols defined by the Storage Service. Description Before beginning to use the Buddy List Service, you must: • Load the BLService component into the Sametime session object, like any other toolkit component. • Implement BLServiceListener, and add it to your Buddy List Service instance by calling the method: addBLServiceListener(); BLServiceListener provides two events to let you know if the BLService is currently available: • void serviceAvailable(BLEvent evt); This indicates that the Buddy List Service is currently available. • void serviceUnavailable(BLEvent evt); If the service has failed, you receive the serviceUnavailable() event. The service component automatically reconnects to the service when it is available again. You will then receive the serviceAvailable() event. The BL Object The BL object contains groups that are encapsulated by the PrivateGroup and PublicGroup classes implementing the BLGroup interface. To add, remove, and retrieve groups and users, see the Sametime Java Toolkit Reference. Get the Contact List from the User Storage The developer can get a contact list using this method, which is defined in the BLServiceListener: void getBuddyList(); Note that this method does not return any value. The asynchronized result is retrieved by the event handler. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 80 Chapter 4. Community Services void blRetrieveSucceeded(BLEvent evt); The BL object can be extracted from the BLEvent: BL m_buddyList = evt.getBL(); In case of failure, the user gets the BLEvent through the event handler: void blRetrieveFailed(BLEvent evt); Set the Contact List to the User Storage The following method (defined in the BLServiceListener) is used to write a new Contact list to user storage: void setBuddyList(BL newBuddyList) If the set action succeeds, the user should get the BLEvent through the event handler, which is defined in the BLServiceListener: void blSetSucceeded(BLEvent evt); In case of failure, the user gets the BLEvent through the event handler: void blSetFailed(BLEvent evt); BuddyList Updated The user should get the BLEvent through the following method when the contact list has been updated by some other login. This method is defined in the BLServiceListener: void blUpdated(BLEvent evt); Converting between String and BL Objects The Buddy List Service provides parsing methods that convert String to BL object and vice versa. These methods are used, for example, when reading the BL object from a text file or writing it to a text file: BL stringToBuddyList(buddyListString) String buddyListToString(BL buddyList) Package com.lotus.sametime.buddylist Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 81 Chapter 4. Community Services See Also The Storage Service section of this chapter Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 82 Chapter 4. Community Services Community Service Overview The Community Service is the core service you must use in order to log in and log out from the Sametime server. In addition to login services, the Community Service provides the ability to receive administrator messages, to change your status and privacy in the community, and to request to change your user name if you logged on anonymously. Description The Community Service provides three methods to log in to the community: • loginByPassword() – Enables login using a login name and password. • loginByToken() – Enables login using a login name and a temporary login token generated by the Token Service or by some other means. See the Token Service section in this chapter for more information on how to create a temporary login token. • loginAsAnon() – Enables login as an anonymous user to the community. Anonymous login to a Sametime Community should be enabled by the administrator for this type of login to succeed. Once logged in, you can log out at any time by calling the logout() method. By default, the toolkit first attempts to log in through a plain socket connection via port 1533. If this attempt fails, the toolkit attempts to connect via an HTTP tunneling connection on port 8082. This default behavior can be changed by calling the setConnectivity() method with an array of connections to try before calling one of the login methods. The toolkit provides Connection classes for direct connection, HTTP, socks4, socks5, and HTTPS. Receiving Login Events To receive login or logout events, you must add a LoginListener object to the Community Service. The loggedIn() event is called when the user has logged in to the community by password or token. The loggedOut() event is called if a login request failed or if the user was disconnected from the Sametime server. Use the getReason() method on the event object to retrieve the precise reason for the logout. Receiving Admin Messages The Sametime administrator can send administration messages to all the users in the community. To receive such messages, add an AdminMsgListener to the Community Service. When the administrator sends a message, the adminMsgReceived() event is called with the message text in the event object. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 83 Chapter 4. Community Services Sensing Availability of Services The Community Service can be used to determine the status of a Sametime server-side service. If a server-side component fails, you can be notified when it becomes available again. Add a ServiceListener object, and then call the senseService() method with the service type for which you want to determine the status. When a service of the requested type is available again, you will receive the serviceAvailable() event of the listener. The Login Object Once logged in, you can use the getLogin() method to get a Login object. Using this object, you can query and modify your current status and privacy settings. You can also use this object to change your user name if you logged in anonymously. The Login object is valid only as long as you are logged in and is not be stored for later reference. Querying and Changing Your Online Status Use the getMyStatus() method of the Login object to retrieve your current online status. To change the status, call the changeMyStatus() method. To track changes in your online status, add a MyStatusListener object to the Login object. You will receive the myStatusChanged() event for each change in the user status. If you are logged in more than once, you will receive events on status changes made by your other logins. Note You can also change the default status that will be used on subsequent logins. For example, you may want to specify a default status of “Mobile Active” for mobile users when they log in. To specify the default status, call the setLoginStatus() method of the CommunityService object. Querying and Changing Your Privacy Use the getMyPrivacy() method of the Login object to retrieve your current privacy settings. To change your privacy settings, call the changeMyPrivacy() method. To track changes in your privacy settings, add a MyPrivacyListener object to the Login object. You will receive the myPrivacyChanged() event for each change in the user privacy settings. If you are logged in more than once, you will receive events on privacy changes made by your other logins. If you try to change your privacy settings and the request cannot be performed by the Sametime server, you will receive the changeMyPrivacyDenied() event. Changing an Anonymous Login User Name Use the changeMyUserName() method of the Login object to request to change your anonymous login user name. Add a MyNameListener object to track the request results. If the request is approved, you will receive a myUserNameChanged() event. If the request is denied, you will receive the changeMyUserNameDenied() event. Note that changing your user name (the name other users see), is only possible if you logged in anonymously. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 84 Chapter 4. Community Services Other Login Object Information The Login object contains useful information about the current login. Use the getServer() method to retrieve the Sametime server you are logged in to. To retrieve your user name, user ID, or login ID, use the getMyUserInstance() method. Use the getServerVersion() method to obtain the version of the server you are currently logged in to. Package com.lotus.sametime.community See Also The Community UI section of this guide Example See the Live Names sample in the Awareness List section in Chapter 2 for code that shows how to change your online status. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 85 Chapter 4. Community Services Directory Service Overview The Directory Service enables you to browse the Sametime community directories. It provides a list of all available directories and allows you to query for chunks of entries in each directory. Depending on the directory configuration, directory browsing might not be available on your Sametime server. For example, if your Sametime server is configured to use an LDAP directory, directory browsing is not available. See the Checking for Directory Browsing Support section below for more information. When directory browsing is not available, the developer should limit the application to the use of the Lookup Service which provides basic resolve capabilities. Description Before using the Directory Service you must: 1. Implement DirectoryServiceListener and add it to the service by calling the addDirectoryServiceListener() method. 2. Call the queryAllDirectories() method of Directory Service to retrieve the list of all available directories on the Sametime server you are logged in to. DirectoryServiceListener provides two types of events. The events serviceAvailable() and serviceUnavailable() let you know if the Directory Service is currently available on the Sametime server. If you perform an operation on the Directory Service and the Directory Service is unavailable, the serviceUnavailable() event is generated. The Directory Service component automatically attempts to restore a connection to the Directory Service on the server and notifies you with the serviceAvailable() event when successful. The other events you can receive from the DirectoryServiceListener are responses to the queryAllDirectories() method. If the query fails, you receive the allDirectoriesQueryFailed() event. Use the getReason() method of the event object to get the reason code for the failure. If the query is successful, you receive the allDirectoriesQueried() event. Use the getDirectories() method of the Event object to get an array of Directory objects representing all the directories on the Sametime server you are logged in to. Using Directory Objects Once you have an array of Directory objects representing the directories on the Sametime server, you can use the getTitle() method of Directory to display a list of the directories. You can browse one directory or several directories at once if needed. To start browsing the directories: 1. Implement DirectoryListener and add it to your Directory object by calling the addDirectoryListener() method. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 86 Chapter 4. Community Services 2. Change the default chunk size of the directory if needed by calling the getMaxEntries() and setMaxEntries() methods. 3. Open the directory for browsing by calling the open() method. 4. Once you call the open() method, you receive one of two DirectoryListener events: • directoryOpened() – The directory has been opened successfully. Use the getDirectory() method of the event object to find out to which directory this event refers. Use the getDirectorySize() method of the event object to find the total number of entries in the directory. • directoryOpenFailed() – The directory could not be opened for browsing. Use the getDirectory() method of the event object to find out to which directory this event refers. Use the getReason() method of the Event object to find the reason for the failure. 5. After you receive the directoryOpened() event, query the directory for chunks of users by calling one of the queryEntries() methods. See the “Querying the Directory” that follows for more details. 6. Close the directory when finished browsing by calling the close() method. Querying the Directory Once you have opened the directory, you can query for chunks of entries by moving backward or forward in the chunks or by searching for a chunk starting with a certain string prefix. There are two queryEntries() methods for each of these possibilities, and each returns a request ID you should store to compare with the query response events. For each query you receive one of two events in your DirectoryListener: • entriesQueried() – Entries from the directory have been queried successfully. Use the getRequestId() method of the event object to match the event with the appropriate request. Use the getEntries() method of the event object to get an array of STObjects. Each STObject could be a STUser or STGroup object. Use the isAtStart() and isAtEnd() methods of the event object to find out if the directory is at its first or last chunk. • entriesQueryFailed() – A query entries request has failed. Use the getRequestId() method of the event object to match the event with the appropriate request. Use the getReason() method of the event object to find the failure code. Checking for Directory Browsing Support As mentioned previously, not every Sametime server supports directory browsing. Follow these steps to find out if your directory supports directory browsing: 1. Add the following attribute key to your Awareness Service attribute filter: com.lotus.sametime.awareness.AwarenessConstants.BROWSE_ENABLED 2. Create a Watch List on your Awareness Service and add an AttributeListener to it. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 87 Chapter 4. Community Services 3. Use the Community Service to find your own server’s STServer object by calling getLogin().getServer(). 4. Add the returned STServer object to your WatchList object. 5. If you receive an attrChanged() event for the server object with the above attribute key, then you know that the Sametime server supports directory browsing. If you do not receive this attribute from the server, then the server does not support directory browsing. Package com.lotus.sametime.directory See Also The Directory Panel section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 88 Chapter 4. Community Services FileTransfer Service Overview The FileTransfer Service provides the ability to send and receive files between Sametime users. The initiator creates a FileTransfer object and starts the transfer. The other side can accept or decline the transfer. After the file transfer starts, both sides receive progress notifications, and can stop the transfer before it completes successfully. Note that if you are creating an applet that supports file transfer, you must sign the applet, to allow local file access. Description The FileTransfer class represents a file transfer session between two clients. It is used for both sending and receiving files. A FileTransfer object can be created in either of two ways: • Explicitly by the sender – The sender uses the createFileTransfer() method of the FileTransfer Service. • Implicitly on the receiver’s side – When someone initiates a file tranfer to you, the toolkit creates a FileTransfer object. This FileTransfer object is passed to the FileTransferInitiated() event handler in the event object. In order to receive this event, the receiver must implement the FileTransferServiceListener and add it to the FileTransferService instance using the addFileTransferServiceListener() method. Checking and Setting Attributes In order to send files, your application must connect to a Sametime server that supports file transfer. After the connection is established, and before any file transfer is attempted, your application should check that existential server attribute 9009, AwarenessConstants.FILE_TRANSFER_MAX_FILE_SIZE, is set. For information about checking server attributes, please refer to "Awareness Service" in Chapter 4. To receive files, your application must set existential user attribute 6, AwarenessConstants.FILE_TRANSFER_SUPPORTED. This attribute is set automatically (provided the server attribute is set) if you use the FileTransferUI component, but must be set manually otherwise. To do so, call AwarenessService.changeMyAttr(). Sending Files To send a file, you first create a FileTransfer object, using the createFileTransfer() method of the FileTransfer Service. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 89 Chapter 4. Community Services This method returns a FileTransfer object. To use this method, you must provide the following parameters: • • • • remoteUser – The STUser object of the user you are sending the file to. fileIn – The FileInputStream that you want to send. fileName – A string with the full pathname of the file. fileDesc – A string with the description of the file. The receiver will get the name and the description in the FileTransfer object. To use the FileTransfer object, you must first call the addFileTransferListener() method to register the FileTransfer listener object. Then you can call the start() method to start the transfer. To cancel a transfer, call FileTransfer.stop(). The results of the file transfer operation are returned to the object implementing the FileTransferListener interface. The possible events are: • fileTransferStarted() – The transfer has started. This notification is received after the other side accepts the file transfer. • bytesTransferredUpdate() – This notification is received several times during the transfer to indicate progress. You can get the exact number of bytes sent from the FileTransferEvent object. By default, you will get this notification every time an additional 5% of the data is sent. You can change this 5% value by calling the setUpdateInterval() method of the FileTransfer object before starting the transfer. • fileTransferCompleted() – The transfer has completed successfully. • fileTransferDeclined() – The other side has declined the file transfer. • fileTransferStopped() – The other side has stopped the file transfer (after it was started). Receiving Files To receive a file transfer, you need to implement FileTransferServiceListener and add it to your FileTransferService instance using the addFileTransferServiceListener() method of the FileTransfer Service. When someone initiates a file transfer to you, the toolkit creates a FileTransfer object. This FileTransfer is passed to the FileTransferInitiated() method. From the FileTransfer object, you can get the file transfer details, such as the sending remote user, the file name and description, and the file size. If you want to decline the transfer, use the decline() method of the FileTransfer object. If you want to accept the transfer, call the addFileTRansferListener()method to register the FileTransferListener object. Then you can call the accept() method to start the file transfer. The results of the file transfer operation are returned to the object that implemented the FileTransferListener interface. The possible events are: • bytesTransferredUpdate() – This notification is received several times during the transfer to indicate progress. You can get the exact number of bytes received from the Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 90 Chapter 4. Community Services • • FileTransferEvent object. By default, you will get this notification every time another 5% of the data is received. You can change this 5% value by calling the method setUpdateInterval() of the FileTransfer object before calling the accept() method. fileTransferCompleted() – The transfer has completed successfully. fileTransferStopped() – The other side has stopped the file transfer after it was started. If the sender cancels a file transfer, any partially received file is automatically deleted by the FileTransfer object. Note that you cannot reuse the FileTransfer object to receive the same or another file. Instead, create a new object. Package com.lotus.sametime.filetransfer See Also The FileTransfer UI section of this guide Example The following example consists of two classes: FileSenderSample and FileReceiverSample. The sender sends a file to the receiver right after logging in. After the transfer is completed, the sender logs out. The receiver logs in and then waits for a file transfer. Upon receiving a file transferr, the receiver accepts it. After it is completed, the receiver waits for another transfer. To run this example, simply copy the code and change the constants defined at the beginning of each class to real values from your community. Be sure to run the receiver before you run the sender; the receiver must be already logged in when the sender tries to send the file. import java.io.*; import java.util.Date; import import import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.util.Debug; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.lookup.*; com.lotus.sametime.filetransfer.*; public class FileSenderSample implements LoginListener, FileTransferListener, ResolveListener { // replace all these constants with real values from your //community private final static String SERVER_NAME = "server_name"; private final static String SENDER_NAME = "sender_user_name"; private final static String PASSWORD = "sender_password"; private final static String RECEIVER_NAME = "receiver_user_name"; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 91 Chapter 4. Community Services private final static String FILE_NAME= "c:\\source_dir\\filename"; private private private private private private STSession m_session; CommunityService m_comm; FileTransferService m_fileTransSvc; FileTransfer m_fileTransferSession; String m_remoteUserName; String m_fileName; /** * Constructs a new file sender client. */ public FileSenderSample(String host, String userName, String password, String remoteUserName, String fileName) { m_remoteUserName = remoteUserName; m_fileName = fileName; try { // start the session m_session = new STSession("FileSenderSample " + this); m_session.loadSemanticComponents(); m_session.start(); m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); m_comm.enableAutomaticReconnect(5, 10000); m_fileTransSvc = (FileTransferService) m_session.getCompApi(FileTransferService.COMP_NAME); m_fileTransSvc.addFileTransferServiceListener(this); } catch(DuplicateObjectException e) { e.printStackTrace(); } // login to the community m_comm.loginByPassword(host, userName, password); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 92 Chapter 4. Community Services /** * Main */ public static void main(String[] args) { FileSenderSample fileSenderSample1 = new FileSenderSample(SERVER_NAME, SENDER_NAME, PASSWORD, RECEIVER_NAME, FILE_NAME); } // // LoginListener // /** * Logged in event. */ public void loggedIn(LoginEvent event) { System.out.println("Logged In"); LookupService lookupSvc = (LookupService) m_session.getCompApi(LookupService.COMP_NAME); Resolver resolver = lookupSvc.createResolver(true, true, true, false); resolver.addResolveListener(this); resolver.resolve(m_remoteUserName); } /** * Logged out event. */ public void loggedOut(LoginEvent event) { System.out.println("Logged Out"); if(!event.isReconnecting()) { m_session.stop(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 93 Chapter 4. Community Services // // ResolveListener // /** * A resolve request has been performed, and a match was found. * * @param event The event object. * @see ResolveEvent#getName * @see ResolveEvent#getResolved */ public void resolved(ResolveEvent event) { try { //Separate the file name from the full path name. int index = Math.max(m_fileName.lastIndexOf("\\"), m_fileName.lastIndexOf("/")); String fileName = m_fileName.substring(++index, m_fileName.length()); m_fileTransferSession = m_fileTransSvc.createFileTransfer( (STUser) event.getResolved(), new FileInputStream(m_fileName), fileName, "This is the description..."); m_fileTransferSession.addFileTransferListener(this); m_fileTransferSession.start(); } catch(IOException e) { m_fileTransferSession.stop(); e.printStackTrace(); } } /** * A resolve request has been performed, and multiple matches have * been found. * * @param event The event object. * @see ResolveEvent#getName * @see ResolveEvent#getResolvedList */ public void resolveConflict(ResolveEvent event) { Debug.println("FileSender Resolve conflict"); m_comm.logout(); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 94 Chapter 4. Community Services /** * A resolve request failed. * * @param event The event object. * @see ResolveEvent#getReason * @see ResolveEvent#getFailedNames */ public void resolveFailed(ResolveEvent event) { System.out.println("FileSender Resolve Failed"); m_comm.logout(); } // // FileTransferListener // /** * Notification sent when a file transfer session has been started. */ public void fileTransferStarted(FileTransferEvent event) { Date date = new Date(); System.out.println("File Transfer Started: " + event.getFileTransfer().toString() + " Time: " + date.toString()); } /** * Notification sent when a file transfer session has been completed * successfully. */ public void fileTransferCompleted(FileTransferEvent event) { Date date = new Date(); System.out.println("File Transfer Completed: " + event.getFileTransfer().toString() + " Time: " + date.toString()); m_comm.logout(); } /** * Notification when an attempt to send a file to remote client has * been declined by the remote client. */ public void fileTransferDeclined(FileTransferEvent event) { System.out.println("File Transfer Declined: " + event.getFileTransfer().toString() + " Reason: " + Integer.toHexString(event.getReason())); m_comm.logout(); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 95 Chapter 4. Community Services /** * Notification sent when a session has been stopped/terminated. */ public void fileTransferStopped(FileTransferEvent event) { System.out.println("File Transfer Stopped reason: " + Integer.toHexString(event.getReason()) + "Session: " + event.getFileTransfer().toString()); m_comm.logout(); } /** * Notification send periodicly according indicating the nubmer of * bytes of transferred up till now. */ public void bytesTransferredUpdate(FileTransferEvent event) { System.out.println("Bytes transferred: " + event.getFileTransfer().getNumOfByteTransferred()); } } import import import import import import import java.io.*; java.util.Date; com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.community.*; com.lotus.sametime.core.util.Debug; com.lotus.sametime.filetransfer.*; public class FileReceiverSample implements LoginListener, FileTransferListener, FileTransferServiceListener { // replace all these constants with real values from your // community private final static String SERVER_NAME = "server_name"; private final static String RECEIVER_NAME = "receiver_user_name"; private final static String PASSWORD = "receiver_password"; private final static String DIR_NAME = "c:\\target_dir\\"; private private private private STSession m_session; CommunityService m_comm; FileTransferService m_fileTransSvc; FileTransfer m_fileTransferSession; public FileReceiverSample(String host, String userName, String password) { try { // create the session m_session = new STSession("BaseClient " + this); m_session. loadSemanticComponents (); m_session.start(); m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 96 Chapter 4. Community Services m_comm.enableAutomaticReconnect(5, 10000); m_fileTransSvc = (FileTransferService) m_session.getCompApi(FileTransferService.COMP_NAME); } catch(DuplicateObjectException e) { e.printStackTrace(); } // login to the community m_fileTransSvc.addFileTransferServiceListener(this); m_comm.loginByPassword(host, userName, password); } /** * Main. */ public static void main(String[] args) { FileReceiverSample fileReceiverSample1 = new FileReceiverSample( SERVER_NAME,RECEIVER_NAME, PASSWORD); } // // LoginListener // /** * Logged in event. */ public void loggedIn(LoginEvent event) { System.out.println("Logged In"); } /** * Logged out event. */ public void loggedOut(LoginEvent event) { System.out.println("Logged Out"); if(!event.isReconnecting()) { m_session.stop(); } } // // FileTransferListener // /** * Notification sent when a file transfer session has been started. */ public void fileTransferStarted(FileTransferEvent event) { Date date = new Date(); System.out.println("File Transfer Started: " + Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 97 Chapter 4. Community Services event.getFileTransfer().toString() + " Time: " + date.toString()); } /** * Notification sent when a file transfer session has been completed * successfully. */ public void fileTransferCompleted(FileTransferEvent event) { Date date = new Date(); System.out.println("File Transfer Completed: " + event.getFileTransfer().toString() + " Time: " + date.toString()); } /** * Notification when an attempt to send a file to remote client has * been declined by the remote client. */ public void fileTransferDeclined(FileTransferEvent event) { System.out.println("File Transfer Declined: " + event.getFileTransfer().toString() + " Reason: " + Integer.toHexString(event.getReason())); } /** * Notification sent when a session has been stopped/terminated. */ public void fileTransferStopped(FileTransferEvent event) { System.out.println("File Transfer Stopped reason: " + Integer.toHexString(event.getReason()) + "Session: " + event.getFileTransfer().toString()); } /** * Notification send periodicly according indicating the nubmer of * bytes of transferred up till now. */ public void bytesTransferredUpdate(FileTransferEvent event) { System.out.println("Bytes transferred: " + event.getFileTransfer().getNumOfByteTransferred()); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 98 Chapter 4. Community Services // // FileTransferServiceListener // /** * A file trnasfer session has been intiated by a remote client. * @param The File transfer session. */ public void FileTransferInitiated(FileTransferEvent event) { System.out.println("File Transfer session Initated"); m_fileTransferSession = event.getFileTransfer(); m_fileTransferSession.addFileTransferListener(this); Date date = new Date(); System.out.println("File transfer initated, File: " + m_fileTransferSession.getFileName() + " File Desc: " + m_fileTransferSession.getFileDesc() + " File Size: " + m_fileTransferSession.getFileSize() + " Time: " + date.toString()); try { FileOutputStream fileOut = new FileOutputStream( DIR_NAME + m_fileTransferSession.getFileName()); m_fileTransferSession.setUpdateInterval(10); m_fileTransferSession.accept(fileOut); } catch(IOException e) { e.printStackTrace(); m_fileTransferSession.stop(); } } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 99 Chapter 4. Community Services Instant Messaging Service Overview The Instant Messaging Service allows the sending of text and/or binary messages between clients. It is used for standard Instant Messages (IM), but it can also be used for passing any other messages, such as game moves and translated messages. This service uses an IM type parameter to classify message sessions of different types. To allow clients from different vendors to interoperate, reserved message types should not be used for third-party purposes. The IM types 0 – 10000 are reserved for Lotus internal use. If you need to reserve IM types for your own commercial applications, please follow the registration instructions at http://www.lotus.com/sametimedevelopers. Description The IM class, representing an Instant Message (IM) session between two clients, is used for both sending and receiving instant messages. IM objects can be created in one of two ways: • Using the createIm() method of the Instant Messaging Service. • When someone initiates an instant message to you, the Sametime Toolkit creates an IM object. This IM is passed to the imReceived() event handler in the event object. In order to receive this event, you must: 1. Implement ImServiceListener and add it to the InstantMessagingService using the addImServiceListener() method. 2. Use the registerImType() method of InstantMessagingService to register the IM types your application recognizes and is willing to accept. This step is very important. Without it, no IMs will be received, because the Instant Messaging Service will automatically reject any incoming IMs that do not have a registered IM type. The initiating user will receive an openImFailed() event with the appropriate error code. Opening IM Objects IM objects must be opened in order to be able to use them for the actual passing of information. IMs created using the createIm() method are closed by default. Incoming IM objects created by the imReceived() event are open by default. You can use the isOpen() method at any time to find out whether an IM object is currently open or closed. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 100 Chapter 4. Community Services Add an IMListener object to your IM object and then call the open() method to open a closed IM. You will receive one of two events from the ImListener: • imOpened() – The IM object has been opened successfully. Use the getIm() method of the event object to find the IM object this event refers to. • openImFailed() – The IM object could not be opened for some reason. Use the getIm() method of the event object to find the IM this event refers to. Use the getReason() method of the event object to get the reason code for the failure. Sending and Receiving Text or Data with IM Objects Once you have created an open IM in one of the two ways described above, the same operations can be performed on the IM. Any side can send text or data to the other party at any time as long as the IM session is open. Use the sendText() method to send text to the other party that will receive a textReceived() event . Use the sendData() method to send binary data to the other party that will receive a dataReceived() event. Closing IM Objects Any party of the IM session can close the session at any time by calling the close() method of the IM object. The other side will receive an imClosed() event. Once an IM is closed by any party, the IM object needs to be reopened before it can be used again. Note, that an IM object is created with a specific target user in mind. The IM object can be used only for IM sessions with that user during the lifetime of the object. Package com.lotus.sametime.im See Also The Chat UI section of this guide The Post Service section in this chapter of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 101 Chapter 4. Community Services Example This example demonstrates how the Instant Messaging Service is used to send and receive IMs from users. The sample logs you into the Sametime community and allows you to send an IM to any user by typing his name and the message. This example will also display any incoming IM messages sent to you. import import import import java.awt.*; java.applet.*; java.awt.event.*; java.util.*; import import import import import import import import import import com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.constants.*; com.lotus.sametime.core.types.*; com.lotus.sametime.community.*; com.lotus.sametime.im.*; com.lotus.sametime.commui.*; com.lotus.sametime.guiutils.chat.ChatArea; com.lotus.sametime.guiutils.misc.*; com.lotus.sametime.resourceloader.*; public class ImApplet extends Applet implements LoginListener, ImServiceListener, ImListener, CommUIListener, ActionListener { private private private private private STSession m_session; CommunityService m_comm; InstantMessagingService m_imService; CommUI m_commUiService; Vector m_ImOpened = new Vector(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 102 Chapter 4. Community Services private private private private private private String m_myName =""; TextField m_imDestination =new TextField(); TextField m_imText= new TextField(); Button m_sendBtn = new Button("Send"); Font m_font = new Font("Dialog",12,Font.PLAIN); ChatArea m_transcript = new ChatArea(150,m_font,50); public void init() { try { m_session = new STSession("ImApplet" + this); //we are not to loading the chatUi comp //because we are going to handle the events //in different way m_session.loadSemanticComponents(); new CommUIComp(m_session); new ResourceLoaderComp(m_session); } catch(DuplicateObjectException e) { e.printStackTrace(); } m_session.start(); initLayout(); login(); } /** * set the applet layout */ private void initLayout() { setLayout(new BorderLayout(0,0)); Font labelFont = new Font("Dialog",14,Font.PLAIN); Panel northPnl = new Panel(new BorderLayout(10,0)); Panel details = new Panel(new BorderLayout(0,0)); details.add(new Label("Type your partner name here:"), BorderLayout.NORTH); details.add(m_imDestination,BorderLayout.SOUTH); Panel messagePnl = new Panel(new BorderLayout(0,0)); messagePnl.add(new Label("Type your message here:"), BorderLayout.NORTH); messagePnl.add(m_imText,BorderLayout.CENTER); messagePnl.add(m_sendBtn,BorderLayout.EAST); m_sendBtn.addActionListener(this); northPnl.add(details,BorderLayout.NORTH); northPnl.add(messagePnl,BorderLayout.SOUTH); add(northPnl,BorderLayout.NORTH ); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 103 Chapter 4. Community Services add(m_transcript,BorderLayout.CENTER); validate(); } /** * Login to the community using the user name and password * parameters from the html. */ private void login() { m_comm = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_comm.addLoginListener(this); m_comm.loginByPassword(getCodeBase().getHost().toString(), getParameter("loginName"), getParameter("password")); } /** * get an im object and send the text */ public void sendText(Im im) { im.sendText(false,m_imText.getText()); m_transcript.writeSeparator(m_myName + ": " + m_imText.getText(), Color.black); m_imText.setText(""); } /** * Loggedin event receive only if loggedin successfully */ public void loggedIn(LoginEvent event) { m_myName = m_comm.getLogin().getMyUserInstance(). getDisplayName(); m_transcript.writeSeparator("Loggedin :" + m_myName, Color.green); m_imService = (InstantMessagingService) m_session.getCompApi(InstantMessagingService.COMP_NAME); m_imService.registerImType(ImTypes.IM_TYPE_CHAT); m_imService.addImServiceListener(this); m_commUiService = (CommUI ) m_session.getCompApi(CommUI.COMP_NAME); m_commUiService.addCommUIListener(this); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 104 Chapter 4. Community Services /** * Loggedin event receive only if loggedout */ public void loggedOut(LoginEvent event) { m_transcript.writeSeparator("Loggedout :" + m_myName, Color.green); } /** * imReceived event received if someone try to open im to you, * check if you have already im with this person, if not add * Im listener */ public void imReceived(ImEvent event) { Im im = event.getIm(); boolean imExsit = false; Im currentIm = null; for(int i = 0; i < m_ImOpened.size(); i++) { currentIm = (Im)m_ImOpened.elementAt(i); if(currentIm.equals(im)) { imExsit = true; im = currentIm; break; } } if(!imExsit) { m_ImOpened.addElement(im); im.addImListener(this); } } /** * if the send button was pressed take the name from the * textField and resolve for appropriate user */ public void actionPerformed(ActionEvent event) { m_commUiService.resolve(m_imDestination.getText()); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 105 Chapter 4. Community Services /** * resolved event receive after you send request to resolve * a name * check if you already have im with this person, * if you have sent the text else open new im. */ public void resolved(CommUIEvent event) { STUser partner = event.getUser(); Im im = m_imService.createIm(partner, EncLevel.ENC_LEVEL_NONE, ImTypes.IM_TYPE_CHAT); Im currentIm = null; boolean imExsit = false; for(int i = 0; i < m_ImOpened.size(); i++) { currentIm = (Im)m_ImOpened.elementAt(i); if(currentIm.getPartner().equals(partner)) { imExsit = true; im = currentIm; sendText(im); break; } } if(!imExsit) { m_ImOpened.addElement(im); im.addImListener(this); im.open(); } } /** * resolveFailed event receive aftere you send request to resolve a * name but no approrriate user was found. */ public void resolveFailed(CommUIEvent event) { m_transcript.writeSeparator("resolve failed type another name", Color.red); m_imDestination.setText(""); } /** * if the user start the im (by im.open()) imOpened event will * be receved if the im open successfully */ public void imOpened(ImEvent event) { event.getIm().sendText(false,m_imText.getText()); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 106 Chapter 4. Community Services m_transcript.writeSeparator(m_myName + ": " + m_imText.getText(), Color.black); m_imText.setText(""); } /** * if the user start the im (by im.open()) imOpened event will * be receved openImFailed if the user you try to open im to * is offline or DND etc. */ public void openImFailed(ImEvent evt) { System.out.println("openImFailed reason :"+evt.getReason()); m_transcript.writeSeparator ("Failed to open im ,type another user name", Color.red); } /** * if, from any reason the im was closed. * you will need to remove the im from the open im list */ public void imClosed(ImEvent event) { Im im = event.getIm(); boolean imExsit = false; Im currentIm = null; for(int i = 0; i < m_ImOpened.size(); i++) { currentIm = (Im)m_ImOpened.elementAt(i); if(currentIm.equals(im)) { imExsit = true; m_ImOpened.removeElement(im); im.close(0); im.removeImListener(this); break; } } } /** * textReceived print it to the screen */ public void textReceived(ImEvent event) { String partnerName = event.getIm().getPartner().getDisplayName(); m_transcript.writeSeparator(partnerName + ": " + event.getText(), Color.blue); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 107 Chapter 4. Community Services /** * DataReceived print a message to the screen */ public void dataReceived(ImEvent evt) { System.out.println("Data Received data type = " + evt.getDataType()); } public void destroy() { m_comm.logout(); m_session.stop(); m_session.unloadSession(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 108 Chapter 4. Community Services Lookup Service Overview The Lookup Service provides the ability to resolve user and group names and query group content. Most Sametime operations that deal with users or groups require STUser or STGroup objects as parameters. The resolve operation matches a name to provide either an STUser or an STGroup object. To query group content, you must provide an STGroup object. The service attempts to return the full list of STUser objects in the group as registered in the directory of the Sametime server. For example, this service can be used to display a complete list of all the users in a group to the end user. Description Resolving Names To resolve names, first call the CreateResolver() method of LookupService. This method returns a resolver object. To use this method, you must provide the following parameters: • OnlyUnique – Determines whether the created resolver object should return only unique matches • ExhaustiveLookup – Determines whether the created resolver object should perform an exhaustive lookup through all directories or stop in the first directory where a match is found • ResolveUsers – Determines whether the created resolver should search the directory for users matching the provided name • ResolveGroups – Determines whether the created resolver should search the directory for groups matching the provided name To use the resolver object, you must first call the addResolveListener() method to register the resolve listener object. Then you can call one of the two resolve() methods (one for a single name and one for multiple names). You can call the resolve() method as many times as necessary on the same resolver object. The results of a resolve operation are returned to the object implementing the resolveListener interface as one of three possible events: • resolved() – The request has been resolved successfully, and a unique match has been found. Use the event object’s getResolved() method to get the result. • ResolveConflict() – The resolve request has been resolved successfully and multiple matches were found. Use the event object’s getResolvedList() method to get the list of Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 109 Chapter 4. Community Services found matches. It is up to the application to determine the correct behavior for such as response. • ResolveFailed() – The resolve request has failed. Use the event object’s getReason() method to determine the reason for failure. Querying Group Content To query a group’s content, first call the CreateGroupContentGetter() method of the LookupService. This method returns a GroupContentGetter object. To use the GroupContentGetter object, call the addGroupContentListener() method to register the listener object. Then call the queryGroupContent() method, passing the STGroup object. You can call the same groupContentGetter object’s queryGroupContent() method as many times as necessary. The results of a queryGroupContent operation are returned to the object implementing the GroupContentListener interface as one of two possible events: • groupContentQueried() – The group content has been successfully queried. Call the event object’s getGroupContent() method to get the actual group content. • queryGroupContentFailed() – The group content of the queried group could not be queried for some reason. Call the event object’s getReason() method to get the failure reason. Package com.lotus.sametime.lookup See Also The Resolve Panel section of this guide The Community UI section of this guide Example See the Live Names Sample in the Awareness List section of Chapter 2 of this guide for sample code that shows how to resolve user names using the Lookup Service. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 110 Chapter 4. Community Services Names Service Overview The Names Service helps manage user nicknames and name delimiters across the entire application. This service is a local service and has no equivalent server-side component. Sametime Connect is an example of a Sametime-enabled application that uses nicknames. A user can define the nickname “Joe” for a user in his contact list, and that user will appear as “Joe” anywhere he is shown. Another option in Sametime Connect is to have “Automatic Nicknames” for users. This is a way to quickly shorten all the names of the users in the contact list by having the name cut at some predefined delimiter such as “/” so “Joe Smith/Org” will be shown as “Joe Smith.” Description The Names Service provides two different name management services: • Synchronizing user name and nickname changes • Synchronizing name delimiter changes Synchronizing User Names The Names Service allows you to store references to STUser objects that include a user’s name, nickname, and name delimiter and to be aware of changes to any of these users names. Store an STUser object reference by calling the setUserName() method. Retrieve an STUser object reference by calling the getUser() method. You can retrieve the most updated nickname for a specific user by calling the getNickname() method. Application components that want to be aware of user name and nickname changes can register as a NameServiceListener on the service and receive the nameChanged() event each time a new user name or nickname has been set for a specific user. Synchronizing User Names Delimiter The Names Service allows you to set a global names delimiter string using the setNameDelimiter() method of the Names Service and to retrieve its value using the getNameDelimiter()method. Application components that want to be aware of name delimiter changes can register as a NameServiceListener on the Names Service and receive the nameDelimiterChanged() event each time a new delimiter string has been set. Package com.lotus.sametime.names Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 111 Chapter 4. Community Services Places Service Overview The Places architecture defines a virtual place where users can meet and collaborate. The Places Service exposes the Places architecture and allows you to create virtual places. The flexibility of the Places architecture allows you to develop varied applications that take advantage of placebased awareness. The Sametime Places architecture unifies the Meeting and Community Services in Sametime. It binds the activities provided by the Meeting Services (such as audio, video, application sharing, and the whiteboard) with a place provided by the Community Services. This architecture is a natural evolution of the Who Is Here Service provided in Sametime 1.5. For example, an event-hosting application such as an auditorium could separate the audience from the presenters by putting them into different sections. The presenters could add activities such as whiteboard, audio, and video to broadcast the event to the audience. Attributes could be used to manipulate different features or permissions in the event. Description The Places Service exposes the Places architecture and allows you to create places and add meeting activities to them. The Places architecture defines the concept of a virtual place where users can meet and collaborate. A place consists of sections, activities, and attributes. Refer to Chapter 8 of the Sametime Java Toolkit Tutorial for a detailed description of the Places architecture. Places Service The Places Service provides two basic functions: • Tracks availability of the Places Service Tracking the availability of the Places Service is achieved by calling the isServiceAvailable() method of PlacesService and by implementing the PlacesServiceListener and adding it to the Places Service. The listener provides the events serviceAvailable() and serviceUnavailable() according to the state of the Places Service on the server. If the service is unavailable, the Places Service Component automatically attempts to reconnect to the service and will notify you with the serviceAvailable() event when it has successfully connected to the service. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 112 Chapter 4. Community Services • Creates new Place objects You create new Place objects by calling the createPlace() method of the Places Service. Provide the following parameters to the createPlace() method: placeName – The first of two parameter uniquely identifying a place (see placeType at the end of this list) displayName – The suggested display name for the place. The display name of a place is determined by its creator. encLevel – The encryption level of messages in the place. placeType – The second of two parameters uniquely identifying a place. Place Object The createPlace() method returns a Place object. Note that a virtual place on the Places Service of the Sametime server has not yet been created. The virtual place is created on the Sametime server only when you request to enter the place. Entering a Place To actually create the virtual place on the Sametime server you need to enter the place by calling one of the two enter() methods. When you enter a place you can specify whether you want to create a new place, join an existing place, or enter the place without caring whether you are creating a new one or joining an existing one. You can also specify whether to be put on the stage or in one of the other sections once you have entered the place. You can also specify the password if required for the place. To know if you successfully entered the place, you must first implement a PlaceListener object and add it to the Place object. You will receive one of the following two events: • entered() – The place was entered successfully. Use the getPlace() method of the event object to find the Place object this event references. • enterFailed() – The request to enter the place has failed. Use the getPlace() method of the event object to find the place object this event references. Use the getReason() method of the event object to get the reason code for the failure. Operations on a Place Once you have entered a place you can do the following: • Use the addAllowedUsers() method to limit access to the place to a specified list of users. If you do not call this method, any user can enter the place as long as he has the place name, type and password (if applicable). If the Places Service does not accept this request, you will receive an addAllowedUsersFailed() event on the PlaceListener object. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 113 Chapter 4. Community Services • Add an activity to the place by calling the addActivity() method. You receive either an activityAdded() event if successful or an addActivityFailed() event if unsuccessful. See the following Activity Objects section for more information on activities. • Get information about the place. Use the following methods: getActivitiesNum() – Returns the total number of activities currently in the place. This method is useful if you want to know how many activityAdded() events to expect when you enter the place. getMembers() – Returns an enumeration you can use to go over all the members of the place: users, sections, activities, etc. Note: Users in sections that you are not listening to, will not be returned. getMySection() – Returns the section object of the section you are currently in. getServer() – Returns the server object on which the place has actually been created. In some cases this server might not be the same server as the one you are currently logged in to. getMyselfInPlace() – Gets the MyselfInPlace object that represents the current user (myself) in the place. • Invite Sametime 1.5 clients to the place. For backward compatibility reasons, an invite15User() method has been added. It allows Sametime 1.5 clients (Sametime Connect or toolkit clients) to be invited to place meetings without their being aware that they are actually in a place. From their point of view, they are in an old-style version 1.5 conference. Receiving Section and Activity Events You receive section and activity events by implementing the PlaceListener and adding it to the place using the addPlaceListener() method. When you enter a place, you receive sectionAdded() and activityAdded() events for each section and activity that was already exists in the place. Once in the place you will receive updates on sections and activities being added and removed with the sectionAdded(), sectionRemoved(), activityAdded(), and activityRemoved() events. Leaving a Place When you want to leave a place, call the leave() method of the Place object. You will receive a left() event from the PlaceListener. You can enter and leave a place multiple times. When you have no more use for the Place object, call the close() method. After calling the close() method, the Place object should no longer be used. PlaceMember Interface Many different kinds of objects are in a place (Place, Section, Activity, UserInPlace, and MyselfInPlace). These objects are all place members and therefore, they all implement the PlaceMember interface. This interface allows you to communicate with each member of a place Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 114 Chapter 4. Community Services by sending text and data messages to the member, and that you can change or remove the attributes of each member. Note that place member attributes are limited to the scope of a specific place, and their lifetime is limited to the duration of the place. Place member attributes have nothing to do with online attributes used by the Awareness Service (whose scope is the entire community) and with Storage Service attributes that are stored persistently on the Sametime server. Sending Text and Data to a Place Member Use the sendText() and sendData() methods of the PlaceMember interface to send text and data to specific place members. Using these methods, you can send a message to a specific user, to all users in a section, or to all users in a place by calling it on different place member objects. You can also use these methods to send messages to activities in the place since they are place members themselves. If the message could not be sent, you receive a sendFailed() event in the appropriate listener. Manipulating Attributes of Place Members You can manipulate the attributes of a place member by calling the changeAttribute() or removeAttribute() methods. If you want to retrieve the value of a known or heavy attribute you can use the queryAttrContent() method. The PlaceMemberListener provides an attributeChanged() event when an attribute has changed or if an attribute was queried on a place member. An attributeRemoved() event will be generated if an attribute was removed from a place member. All of the above operations on place members might not be authorized, and can therefore fail. Trying to perform an unauthorized operation yields a XXXFailed() event with a reason code of ST_ERROR_PLC_NOT_AUTHORIZED. For example, trying to send a message to the place with the sendText() method while not being in a stage section creates the sendFailed() event. Section Object The Section object represents a section in the place and implements the PlaceMember interface. When you enter the place and have added a PlaceListener, you receive a snapshot of all the sections of that place. You also receive continuous updates on sections being added or removed from the place (see the Receiving Section and Activity Events section above). In Sametime every place has three sections and users cannot add or remove sections in a place. To determine if a section is a stage section, use the isStage() method. Restricting the Section to Allowed Users Use the Section object to restrict the section to a specified list of allowed users by calling the addAllowedUsers() method. You receive the addAllowedUsersFailed() event of the SectionListener if the allowed users could not be set for any reason. You can determine the total number of possible users in the section by calling the getCapacity() method. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 115 Chapter 4. Community Services Receiving Notifications on Users Entering and Leaving Sections Using a SectionListener you can receive notifications on users entering and leaving the section. You receive a usersEntered() event each time users enter the section. The first time you add a SectionListener to a section you will receive a usersEntered() event with all the users who are in that section. You will receive a userLeft() event for each user who leaves the section. Activity Object The Activity object represents an activity in a place and implements the PlaceMember interface. Activities are added to the place using the addActivity()method of the Place object. Notification about activities being added and removed are received in the PlaceListener by the activityAdded() and activityRemoved() events. Use the Activity object to retrieve information on the activity (such as its type or data), and whether you or another user added the activity. UserInPlace Object This object represents a user in the place and implements the PlaceMember interface. UserInPlace also extends STUserInstance (which extends STUser) and can therefore be used easily with other toolkit services that expect a STUser object. MyselfInPlace Object Because MyselfInPlace extends the UserInPlace class, it is a place member itself. You can use the MyselfInPlace object that is returned by the Place method getMyselfInPlace() to change your section in the place and to receive message events sent to you. Changing Your Section To change your section: 1. Implement MySectionListener and add it to the MyselfInPlace object with the addMySectionListener() method. 2. Call the changeSection() method providing the Section object representing the section you want to change to. 3. You will receive the sectionChanged() event if you had changed sections successfully. You will receive the changeSectionFailed() event if you have failed to change sections. Use the getReason() method of the event object to get the reason code for the failure. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 116 Chapter 4. Community Services Receiving Place Text and Data Messages To receive messages sent to you by other members of the place, you should: 1. Implement MyMsgListener and add it to the MyselfInPlace object with the addMyMsgListener() method. 2. You will receive a textReceived() event when any member of the place sends you a text message. You will receive a dataReceived() event when a member of the place sends you a binary message. Package com.lotus.sametime.places See Also The Place Awareness List section of this guide Example This example demonstrates the concept of sections and scope in a place using the Places Service. This example logs you into the Sametime community and enters you into a predefined place. It allows you to navigate among sections in the place and to send messages to different scopes (user, section, and place). import java.applet.*; import java.awt.*; import java.awt.event.*; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 117 Chapter 4. Community Services import import import import import import java.util.Hashtable; com.lotus.sametime.places.*; com.lotus.sametime.community.*; com.lotus.sametime.core.comparch.STSession; com.lotus.sametime.core.comparch.DuplicateObjectException; com.lotus.sametime.core.constants.EncLevel; /** * This applet allows chat over different sections of a place. It accepts 3 * parameters from the HTML file: SERVER_NAME, LOGIN_NAME and password which it * then uses to login. */ public class PlacesApplet extends Applet implements LoginListener, ActionListener, ItemListener, SectionListener, MyMsgListener, MySectionListener { /** * The place name. */ private static final String PLACE_NAME = "SamplePlace"; /** * The session object. */ private STSession m_session; /** * The community service. (For login). */ private CommunityService m_commService; /** * The places service. */ private PlacesService m_placesService; /** * The place were going to deal with. */ private Place m_place; /** * The current section wer'e in. */ private Section m_mySection; /** * The list of sections in the place. */ private Hashtable m_sections = new Hashtable(); /** * The list of users in the current section we're in. */ private Hashtable m_users = new Hashtable(); // UI components. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 118 Chapter 4. Community Services private private private private private private Button TextField TextArea Choice Choice List m_btnSend; m_tfSend; m_taTranscript; m_chSections; m_chScope; m_peopleList; // // Applet life cycle. // /** * Initialize the sametime components. */ public void init() { try { m_session = new STSession("Places Session" + this); m_session.loadSemanticComponents(); m_session.start(); } catch(DuplicateObjectException e) { e.printStackTrace(); } // Get a reference to the components we are interested in. m_commService = (CommunityService) m_session.getCompApi(CommunityService.COMP_NAME); m_commService.addLoginListener(this); m_placesService = (PlacesService) m_session.getCompApi(PlacesService.COMP_NAME); initUI(); } /** * Login to the community server. */ public void start() { String serverName = getCodeBase().getHost().toString(); String loginName = getParameter("loginName"); String password = getParameter("password"); m_commService.loginByPassword(serverName, loginName, password); } /** * Logout. */ Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 119 Chapter 4. Community Services public void destroy() { m_commService.logout(); m_session.stop(); m_session.unloadSession(); } /** * A notification that wer'e logged in. */ public void loggedIn(LoginEvent event) { System.out.println("Sample: Logged in"); // Create the place wer'e going to work with, and enter. m_place = m_placesService.createPlace(PLACE_NAME, PLACE_NAME, EncLevel.ENC_LEVEL_DONT_CARE, 0); // Add an adapter to be the listener to this place. addPlaceListener(); m_place.enter(); } /** * Logged out of the server. */ public void loggedOut(LoginEvent event) { System.out.println("Sample: Logged out"); } /** * Add a PlaceAdapter to listen to the events we care about. */ private void addPlaceListener() { m_place.addPlaceListener(new PlaceAdapter() { public void entered(PlaceEvent event) { PlacesApplet.this.entered(event); } public void enterFailed(PlaceEvent event) { PlacesApplet.this.enterFailed(event); } public void left(PlaceEvent event) { PlacesApplet.this.left(event); } public void sectionAdded(PlaceEvent event) { PlacesApplet.this.sectionAdded(event); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 120 Chapter 4. Community Services public void sendFailed(PlaceMemberEvent event) { PlacesApplet.this.sendFailed(event); } }); } // // Place listener interface. // /** * Entered the place. */ private void entered(PlaceEvent event) { // Listen to my section in order to get notification on its users. m_mySection = m_place.getMySection(); m_mySection.addSectionListener(this); MyselfInPlace myself = m_place.getMyselfInPlace(); // Listen for incoming messages. myself.addMyMsgListener(this); // Listen for section changes. myself.addMySectionListener(this); enableGuiItems(true); } /** * Failed to enter the place. Better luck next time. */ private void enterFailed(PlaceEvent event) { System.out.println("Sample: Failed to enter to the place. Reason: " + event.getReason()); } /** * Left the place for some reason. */ private void left(PlaceEvent event) { System.out.println("Sample: Left the place. Reason: " + event.getReason()); enableGuiItems(false); } /** * New section in the place. */ public void sectionAdded(PlaceEvent event) { Section newSection = event.getSection(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 121 Chapter 4. Community Services Integer sectionId = newSection.getMemberId(); String sectionKey = "Section" + sectionId.toString(); m_sections.put(sectionKey, newSection); m_chSections.add(sectionKey); } // // Section listener. // /** * New users have entered the section. */ public void usersEntered(SectionEvent event) { String userName; UserInPlace[] newUsers = event.getUsers(); for (int i = 0; i < newUsers.length; i++) { userName = newUsers[i].getDisplayName(); m_users.put(userName, newUsers[i]); m_peopleList.add(userName); } } /** * A user has left the section. */ public void userLeft(SectionEvent event) { String userName = event.getUser().getDisplayName(); m_users.remove(userName); m_peopleList.remove(userName); } /** * A attempt to send a message was failed. */ public void sendFailed(PlaceMemberEvent event) { m_taTranscript.append("\n ************Failed to send the message. Reason: " + Integer.toHexString(event.getReason()) + "h ************ \n\n"); } /** * AWT events. */ public void actionPerformed(ActionEvent event) { if (event.getSource() == m_btnSend) { PlaceMember receiver; String text = m_tfSend.getText(); String scope = m_chScope.getSelectedItem(); // Get the receiver place member according to the selected scope. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 122 Chapter 4. Community Services if (scope.equals("Scope: PLACE")) { receiver = m_place; } else if (scope.equals("Scope: SECTION")) { receiver = m_mySection; } else { String selectedUser = m_peopleList.getSelectedItem(); receiver = (UserInPlace)m_users.get(selectedUser); } receiver.sendText(text); m_tfSend.setText(""); } } /** * */ public void itemStateChanged(ItemEvent event) { if (event.getSource() == m_chSections) { String sectionKey = (String)event.getItem(); Section newSection = (Section)m_sections.get(sectionKey); MyselfInPlace myself = m_place.getMyselfInPlace(); // Move to the selected section. See sectionChanged() below. myself.changeSection(newSection); } } // // My section listener. // /** * Navigated to a new section. */ public void sectionChanged(MyselfEvent event) { System.out.println("Sample: Section changed"); m_users.clear(); m_peopleList.removeAll(); m_mySection.removeSectionListener(this); m_mySection = event.getSection(); m_mySection.addSectionListener(this); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 123 Chapter 4. Community Services /** * Unable to switch sections. */ public void changeSectionFailed(MyselfEvent event) { System.out.println("Sample: Failed to change a section. Reason: " + event.getReason()); } // // My Msg Listener. // /** * A text message was received. */ public void textReceived(MyselfEvent event) { PlaceMember sender = event.getSender(); if (sender instanceof UserInPlace) { String senderName = ((UserInPlace)sender).getDisplayName(); String scope; if (event.getScope() == PlacesConstants.SCOPE_PLACE) { scope = "Place "; } else if (event.getScope() == PlacesConstants.SCOPE_SECTION) { scope = "Section "; } else { scope = "User "; } m_taTranscript.append(scope + senderName + " "); m_taTranscript.append(event.getText() + "\n"); m_tfSend.requestFocus(); } } public void dataReceived(MyselfEvent event) {} // // Helpers. // /** * Set up the ui components. */ private void initUI() { setLayout(new BorderLayout()); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 124 Chapter 4. Community Services Panel sendPanel = new Panel(new BorderLayout()); sendPanel.add("East", m_btnSend = new Button("Send")); sendPanel.add("Center", m_tfSend = new TextField()); sendPanel.add("West", m_chScope = new Choice()); m_chScope.add("Scope: PLACE"); m_chScope.add("Scope: SECTION"); m_chScope.add("Scope: USER"); Panel chatPanel = new Panel(new BorderLayout()); chatPanel.add("South", sendPanel); chatPanel.add("Center", m_taTranscript = new TextArea()); m_taTranscript.setFont(new Font("Courier New", Font.PLAIN, 12)); m_taTranscript.setForeground(Color.blue); m_taTranscript.setEnabled(false); Label header = new Label(); header.setFont(new Font("Dialog", Font.BOLD, 12)); header.setText("SCOPE SENDER TEXT"); chatPanel.add("North", header); Panel listPanel = new Panel(new BorderLayout()); listPanel.add("North", m_chSections = new Choice()); listPanel.add("Center", m_peopleList = new List()); m_peopleList.setForeground(Color.magenta); m_btnSend.addActionListener(this); m_chSections.addItemListener(this); // Enable the gui items only after we enter to the place. enableGuiItems(false); add("East", listPanel); add("Center", chatPanel); } private void enableGuiItems(boolean enable) { m_btnSend.setEnabled(enable); m_tfSend.setEnabled(enable); m_peopleList.setEnabled(enable); m_chScope.setEnabled(enable); m_chSections.setEnabled(enable); m_tfSend.requestFocus(); } public void addAllowedUsersFailed(SectionEvent event) {} public void removeAllowedUsersFailed(SectionEvent event) {} public void removeAttributeFailed(PlaceMemberEvent event) {} public void attributeChanged(PlaceMemberEvent event) {} Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 125 Chapter 4. Community Services public void attributeRemoved(PlaceMemberEvent event) {} public void queryAttrContentFailed(PlaceMemberEvent event) {} public void changeAttributeFailed(PlaceMemberEvent event) {} } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 126 Chapter 4. Community Services Post Service Overview The Post Service allows the sending of one-time messages to many users at once, and allows these users to respond to the message they received. An example of a use for this service is a company secretary sending a meeting reminder to all the meeting participants. Another use is to send invitations to a new meeting type. Description Sending a Post Message Most of the functionality of the Post Service is implemented in the Post object. You create a post object by calling one of the two createPost() methods of the PostService. Once you have the Post object, you can set its title, message, and details; and you can add users to the list of users to whom the post message should be sent. Before sending the post message you should add a PostListener object. Call the send() method to send the prepared post message to all users. For each user that the post message could not be sent to, you receive the PostListener event sendToUserFailed(). For each user that responds to the post message, you receive the PostListener event userResponded(). You can use the same Post object to send more than one post message. Receiving and Responding to a Post Message To receive Post messages, you must perform two preparation steps: 1. Register the post types you are willing to receive by calling the registerPostType() method of PostService. 2. Add a PostServiceListener object by calling the addPostServiceListener() method of PostService. You will now receive messages posted to you by the posted() event of the PostServiceListener. By using the getPost() method of the event object, you can retrieve the Post object to learn more about who posted you. You can respond to the postee by calling the respond() method of the Post object. Note that only post messages having a type that you have registered will be received and the posted() event generated. The Post Service will automatically reject post messages of other types. Package com.lotus.sametime.post Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 127 Chapter 4. Community Services See Also The Instant Messaging Service section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 128 Chapter 4. Community Services Storage Service Overview The Storage Service stores user-related information as attributes directly on the Sametime server. The Storage Service allows you to access these attributes from wherever you log in to your Sametime server. For example, in Sametime your Sametime Connect contact list is stored on the Sametime server. You can log in using Sametime Connect from any machine and always get your latest contact list. Your Sametime applications can use this service to access standard Sametime attributes, such as contact list and Sametime Connect preferences, or add their own applicationspecific attributes. Do not confuse the attributes used in this service with the online attributes of the Awareness or Places Services. The Storage Service persistently stores user-related attributes for a specific user, and only that user can retrieve the attribute values. The Awareness Service allows a user to set non-persistent online attributes that can be listened to by other users in the community. The Places Service has similar attributes, but they exist in the context of a place. Description Before beginning to use the Storage Service, you must: 1. Implement StorageServiceListener and add it to the Storage Service by calling the addStorageServiceListener() method. 2. Decide whether you want to enable request buffering. When buffering is enabled, the storage requests will be buffered until the Storage Service on the Sametime server is available. Use the enableBufferring() method of the Storage Service to set this option. By default, request buffering is disabled. StorageServiceListener provides two events to let you know if the Storage Service is currently available or not: serviceAvailable() and serviceUnavailable(). If the service is unavailable for some reason, you will receive the serviceUnavailable() event, and the service component will automatically reconnect to the service when it is available. Once the service is available again, you will receive the serviceAvailable() event. The Storage Service provides the basic store and query operations. Storing Attributes To store an attribute you must create or have an STAttribute object. Call either the storeAttr() or storeAttrList() method and record the returned request ID. If you use the storeAttr() method, you receive an attrStored() event. Use the getRequestId() method of the event object to compare the event request ID with the request ID you recorded previously. Use the getRequestResult() method of the event object to find out if the store request was successful. The possible values are: Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 129 Chapter 4. Community Services • ST_OK – All the attributes were stored successfully. Use the getAttrList() method of the event object to get the list of attributes that were stored successfully. • ST_FAIL – None of the attributes was stored successfully. Use the getAttrList() method of the event object to get the list of attributes that failed to be stored. Querying Stored Attributes To query an attribute, you must know the attribute key or keys; and then call the queryAttr() or queryAttrList() method and record the returned request ID. As a response to a query request, you will receive an attrQueried() event. Use the getRequestId() method of the event object to compare the event request ID with the request ID you recorded previously. Use the getRequestResult() method of the event object to find out if the query request was successful or not. The possible values are: • ST_OK – All the requested attributes were retrieved successfully. Use the getAttrList() method of the event object to get the list of successfully retrieved attributes. • ST_ATTRS_NOT_EXIST – Some of the requested attributes were not retrieved because they had not been stored on the Sametime server. Use the getAttrList() method of the event object to get the list of successfully retrieved attributes. Use the getFailedAttrKeys() method of the event object to get the list of attribute keys that were not retrieved. • ST_FAIL – None of the attributes were retrieved. Use the getFailedAttrKeys() method of the event object to get the list of attribute keys that were not retrieved. Receiving Attribute Updates StorageServiceListener also has the attrUpdated() event. This event is fired if an attribute was changed by a different login of the same user. In other words, the user is running more than one client, and one of the clients stored some attribute using the Storage Service. Use the getUpdatedKeys() method of the event object to get the array of attribute keys that have changed. Note that these are only the attribute keys and not the actual values of the changed attributes. Use the queryAttr() method to retrieve the actual changed attribute values if needed. Attributes are shared by all logins of the same user. The Storage Service stores only a single copy of each attribute on the Sametime server for each user. Package com.lotus.sametime.storage Example See the Live Names Sample in the Awareness List section of Chapter 2 of this guide for code that shows how to use the Storage Service to store and retrieve attributes. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 130 Chapter 4. Community Services Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 131 Chapter 4. Community Services Token Service Overview The Token Service provides the ability to generate a token that can be used by a logged-in user to log in to the Sametime server without being challenged to authenticate again. For example, a Sametime application could generate a token and pass it as a parameter to a second application. The launched application would then use this token to log in to the community. A token has a time limit, depending on adminstrator configuration. Description The Token Service returns a Token object. Use this object’s getLoginName() and getTokenString() methods to get the login name and token string to pass to the Community Service method loginByToken(). To get a login token using the TokenService: 1. Add a TokenServiceListener object by calling the addTokenServiceListener() method of Token Service. 2. Call the generateToken() method of Token Service. 3. Receive the token in the tokenGenerated() event of the TokenServiceListener object. Package com.lotus.sametime.token See Also The Community Service section of this guide Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 132 Chapter 5. Meeting Services Introduction The Meeting Services Java API allows client Java applets and applications to create and join multi-participant meetings. The APIs are used to share and annotate documents, share and control applications, and communicate using live audio and video between meeting participants. The developer can choose the tools to use in each meeting and control the visual layout and containment of various UI components. The Meeting Services include Application Sharing, Shared Whiteboard, and Interactive Audio and Video and provides a highly scalable and lightweight Broadcast Receiver. The Broadcast Receiver receives and interprets low bandwidth audio, video, and data streams generated by the different Meeting Services, and displays these without actively participating in the meeting. The following topics are covered in this chapter: • Meeting Factory Services • Application Sharing Service • Whiteboard Service • Streamed Media Service • Meeting Moderation and Permissions • Sizeable Interface Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 133 Chapter 5. Meeting Services Meeting Factory Services Overview The Meeting Factory Services handle the authenticated connection to the Sametime server used by the various meeting components. Objects can register themselves as a MeetingFactoryListener and receive events about the connection and meeting join process. Creating a MeetingFactoryComp is required before any of the interactive meeting components (application sharing, whiteboard, audio/video) can be created and used. The individual meeting services (AppshareService, WhiteboardService, and StreamedMediaService) create the activity components for a given place. The MeetingComp and MeetingCompListener interfaces allow interested parties to be notified about the connection progress and status of a specific component. Note Use of the Streamed Media Broadcast Service does not require the Meeting Factory Services. A MeetingFactoryComp object is not needed. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 134 Chapter 5. Meeting Services interface MeetingFactoryService COMP_NAME addMeetingFactoryListener removeMeetingFactoryListener EventListener STComp interface MeetingFactoryComp ...event.MeetingFactoryListener MeetingFactoryComp connectionStarted stop addMeetingFactoryListener removeMeetingFactoryListener connected disconnected connectionFailed meetingJoinStarted meetingJoined meetingJoinFailed STComp MeetingComponentService MeetingComponentService stop getComponentForPlace EventListener interface MeetingComp isStarted isConnected addMeetingCompListener removeMeetingCompListener Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide interface ...event.MeetingCompListener componentStarted componentConnected componentConnectionFailed 135 Chapter 5. Meeting Services Description A MeetingFactoryComp must be created before any meeting component services are created and used. MeetingFactoryComp has two primary responsibilites: • Creating and maintaining a single shared connection to the Sametime server (used by individual Meeting components) • Establishing the location for system resources (property and image files) The Sametime server distinguishes between Community Services and Meeting Services. The actual connection to the Meeting server is made only when a meeting activity is added to a particular place. When connecting to the Sametime server, the toolkit makes use of any proxy information available and will use an HTTP tunneling mode if a direct connection to the server cannot be established.Furthermore, support for Mozilla’s Proxy Auto Configuration (PAC) files is included, but it requires the containing Applet to either extend STApplet or provide a reference to an object that has implemented the PACService interface. See Appendix D for more information. Objects can register as a MeetingFactoryListener and receive events detailing the connection and meeting join process. Follow these steps to use the Meeting Factory Services: 1. Create an STSession object. 2. Create a MeetingFactoryComp object and pass it the appropriate STSession and as a reference to an STApplet or other PACService object (only needed for applications expecting to gain use of PAC file support). 3. Create any meeting component services that are required for the desired set of meeting activities (AppshareComp, WhiteboardComp and StreamedMediaComp). 4. Log in to the desired community using the CommunityService. 5. Create the appropriate Place object using the PlacesService. 6. Enter the place and add a PlaceListener. 7. Add all of the desired meeting activities to the place. 8. Once events are received from the place for each of the activities, the developer can get the activity components from their respective services. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 136 Chapter 5. Meeting Services Package com.lotus.sametime.conference com.lotus.sametime.conference.event See Also • The Places Service section in this guide • The Whiteboard Service, Application Sharing Service, and Streamed Media Service sections in this chapter • The “Meeting Room” sample in the Toolkit Samples page • Appendix C in this guide Example The following example explains how to construct a MeetingFactoryComp and then create and add a WhiteboardComp, an AppshareComp, and a StreamedMediaComp. An inner handler class is used to add a MeetingFactoryListener to the MeetingFactoryComp. Upon receiving MeetingFactoryEvents, the example uses console prints to track progress. Similarly, an inner class is used to add MeetingCompListeners to the various Meeting Component Services. MeetingCompEvents trigger console prints to the Java console that include the service name. protected void createMeetingServices( STSession session, String resource_path, String resource_namespace, PACServivce pac_support_object) { // Have the STSession object load all components (developers // can choose to selective load only those components their // code requires, for more information on this see STSession). session.loadAllComponents(); // Create the MeetingFactoryService. MeetingFactoryService meeting_factory = new MeetingFactoryComp(session, resource_path, resource_namespace, pac_support_object); // Add a listener to the factory so we can handle connection // and meeting join events. meeting_factory.addMeetingFactoryListener( new MeetingFactoryHandler()); // Create the WhiteboardComp and add a MeetingCompHandler // as a listener. WhiteboardComp whiteboard_comp = new WhiteboardComp (session); whiteboard_comp.addMeetingCompListener( Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 137 Chapter 5. Meeting Services new MeetingCompHandler("WhiteboardComp")); // Create the AppShareComp and add a MeetingCompHandler // as a listener. AppShareComp appshare_comp = new AppShareComp(session); appshare_comp.addMeetingCompListener( new MeetingCompHandler("AppShareComp")); // Create the StreamedMediaService and add a MeetingCompHandler // as a listener. StreamedMediaComp appshare_comp = new StreamedMediaComp(session); appshare_comp.addMeetingCompListener( new MeetingCompHandler("StreamedMediaComp")); } class MeetingCompHandler extends MeetingCompAdapter { private String Component_Name = null; public MeetingCompHandler(String component_name) { Component_Name = component_name; } public void componentStarted(MeetingCompEvent event) { System.out.println("MeetingCompHandler " + "COMPONENT STARTED: " + Component_Name); } public void componentConnected(MeetingCompEvent event) { System.out.println("MeetingCompHandler " + "COMPONENT CONNECTED: " + Component_Name); } public void componentConnectionFailed(MeetingCompEvent event) { System.out.println("MeetingCompHandler " + "COMPONENT CONNECTION FAILED: " + Component_Name); } } class MeetingFactoryHandler extends MeetingFactoryAdapter { public void connectionStarted(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "CONNECTION STARTED."); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 138 Chapter 5. Meeting Services public void connected(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "CONNECTED."); } public void disconnected(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "DISCONNECTED."); } public void connectionFailed(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "CONNECTION FAILED."); } public void meetingJoinStarted(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "MEETING JOIN STARTED."); } public void meetingJoined(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "MEETING JOINED."); } public void meetingJoinFailed(MeetingFactoryEvent event) { System.out.println("MeetingFactoryHandler: " + "MEETING JOIN FAILED."); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 139 Chapter 5. Meeting Services Application Sharing Service Overview The Application Sharing Service (AppShare) allows applications to be shared within the context of a place. Also, clients within a place are able to view and/or control the shared application. Common uses include on-line editing, remote control, software demonstrations, and presentations. MeetingComponentComp AppShareComp AppShareComp MeetingComponentServi interface AppShareService getAppShareForPlace getAppShareForPlace interface MeetingComponent interface AppShare ...event.AppShareListener appshareAvailable addAppShareListener hostLocaleChanged removeAppShareListener currentHostChanged isViewerAvailable controlPermissionChanged isSharingAvailable isRemoteControlAvailable getViewableComponent controlRemoteApp createDesktopWindow createSharedFrame createWindowArray AppShareIMEAction AppShareIMEAction getName getActionTitle performAction createWindowFromHandle interface ShareWindow interface ...event.ShareWindowListener addShareWindowListener windowClosed removeShareWindowListener invalidVideoMode share controlPermissionChanged unShare allowRemoteControl getName getType getHandle Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 140 Chapter 5. Meeting Services Description To use the Application Sharing Services, the developer must first create an instance of an AppShareComp object in the context of an STSession object. All other objects in the Application Sharing Service are exposed as a set of Java interfaces. Once the AppShareComp object is created, its AppShareService interface is used to create an AppShare object within the context of a specific Place object. The AppShare object is then used to create ShareWindow objects and create an AWT Component that renders the shared window. Only one AppShare object can be created per place. The getViewableComponent() method is used to get a viewable AWT Component. This method allows the developer to specify whether the Component object will automatically handle scrolling. If the use_internal_scroll parameter is set to true, scrollbars appear and disappear as needed. In this mode, all content is viewable regardless of the viewer’s contained size. The AWT Component object returned by this method also implements the Sizeable interface and can be cast as such. The Sizeable interface allows control over how the data is displayed. Adding a SizeableListener allows the developer to receive events when the preferred size of the Sizeable object has changed. See the Sizeable section later on in this chapter for more details. Application Sharing features are divided into three categories: • Sharing a local application • Viewing a remote application • Controlling a remote application Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 141 Chapter 5. Meeting Services The system administrator, the meeting moderator and/or the currently hosting user can control each user’s feature set. The following table explains how each feature is controlled: Administrator’s Control Moderator’s Control Current Host’s Control Sharing a local application The administrator can make this feature unavailable on a specific server. If available, the moderator can prevent individuals from using this feature. If available and if allowed by the moderator, an application can be shared if nobody else is sharing. Viewing a remote application The administrator can make this feature unavailable on a specific server. The moderator cannot control the use of this feature. The moderator cannot control the use of this feature. Controlling a remote application The administrator can make this feature unavailable on a specific server. If available, the moderator can prevent individuals from using this feature. If available and if allowed by the moderator, an application can be controlled if the host allows control. Feature The ShareWindow objects are used to select and share applications. Both the AppShare and ShareWindow objects use listener interfaces to deliver events. To use the Application Sharing Service: 1. Create an STSession object. 2. Create a MeetingFactoryComp object for this STSession. 3. Create the AppShareComp object for this STSession. 4. Log in to the desired Community using the CommunityService. 5. Create the appropriate Place object using the PlacesService. 6. Add a PlaceListener and enter the place. 7. Add the AppShare activity to the place. 8. When the AppShare activity has been added to a place, the Places Service will send an activityAdded() event. Use the getAppShareForPlace() method of the AppShareService to obtain an instance of an AppShare object within the context of the specific place. 9. Add a listener to the AppShare object and wait until the appshareAvailable() method is called. AppShare’s behavior is undefined until this event occurs. This event specifies which Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 142 Chapter 5. Meeting Services features of the Application Sharing Service are available to the current user based on settings made by the server’s administrator. 10. Use the createSharedFrame(), createDesktopWindow(), and createWindowArray() methods of the AppShare object to create ShareWindow objects that can be selected and shared. 11. When sharing an application, use the allowRemoteControl() method of the ShareWindow object to allow remote users to control the local application. 12. Use the getViewableComponent() method of the AppShare object to get an AWT Component that can be added to an AWT Container. 13. This Component object is used for viewing the shared application. This Component also handles all local user input when controlling the shared application. 14. When locally viewing a remote application, use the controlRemoteApp() method of the AppShare object to control the shared application. A user will receive a controlPermissionChanged() event when the host of the remote application has allowed users to control the shared application. Activity IDs and Attribute Usage The AppShare activity ID is defined in the AppShare interface as follows: public static final int APPSHARE_ACTIVITY_TYPE = 0x9102; AppShare uses three user place attributes to communicate information about the current share session. The table below lists and describes these attributes. Description Attribute Name Attribute ID Type Possible Values Currently Hosting 4 Boolean true or false Determines whether this user is currently hosting a shared application (true) or not hosting (false) Current Speed Grouping 5 Integer 0,1, or 2 Designates the current speed group this user belongs to: 0: Not in any bandwidth group 1: In the “fast” group 2: In the “slow” group Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 143 Chapter 5. Meeting Services Attribute Name Attribute ID Type Possible Values Control Indicator 15 String “0:,1initial,2initial Description Detects remote state changes of a user who is sharing an application, where stateNumber is: "0" - Viewer Not Controlling Shared App "1" - Viewer Controlling Shared App "2" - Host Not Controlling Shared App "3" - Host Controlling Shared App "4" - Control Indicator Idle The user initials are set per user, based on the display name used in the session. Appending the user initials to the state string is just an optimized way to get a user's state and initials in one element. Platform Requirements Hosting a shared application is only supported on Win32 systems. Therefore, the AppShare native library must be installed. When used in an applet, the code must be signed and used with the provided JNI loader plug-in and/or ActiveX control. See Appendix C for more information. Packages com.lotus.sametime.appshare com.lotus.sametime.appshare.event See Also • The Meeting Factory Services section in this chapter • The Meeting Moderation and Permissions section in this chapter Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 144 Chapter 5. Meeting Services • The Sizeable section in this chapter • The Places Service section in this guide • Appendix C in this guide • The “Meeting Room” and “Application Sharing” samples in the Toolkit Samples page Example This section includes two examples. The first example demonstrates how to share the local desktop. The second example demonstrates how to view and control the shared desktop. Both examples assume that the user is logged in and has entered a place; and that the Application Sharing activity has been added to the place and is ready to provide service. Example 1 – Sharing the Desktop Window protected void appShareReady(AppShare app_share) { if(app_share.isSharingAvailable() == true) { ShareWindow window = app_share.createDesktopWindow(); if(window != null) { window.addShareWindowListener(this); window.share(ShareWindow.HIGH_PRIORITY, ShareWindow.EMBEDDED_CONTROL_BUTTONS, "Sharing Desktop","Stop Sharing", "Allow Control"); window.allowRemoteControl(true); } } } Example 2 – Viewing and Controlling the Shared Desktop Window protected void appShareReady(AppShare app_share) { if(app_share.isViewerAvailable() == true) { Component viewer = app_share.getViewableComponent(true); app_share.controlRemoteApp(true); Toolkit toolkit = Toolkit.getDefaultToolkit(); Dimension dimension = toolkit.getScreenSize(); Viewer_Frame = new Frame(); Viewer_Frame.add(viewer); Viewer_Frame.setSize(dimension); Viewer_Frame.show(); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 145 Chapter 5. Meeting Services Whiteboard Service Overview The Whiteboard Service allows users within a place to simultaneously view and annotate attached content and to create whiteboard content by using a basic set of tools for drawing lines, boxes, circles, and text. Whiteboard content, such as a Power Point presentation, can be attached to a meeting created in the Sametime Meeting Center. Whiteboard content is organized within documents, each of which can contain multiple pages. For each attached item, a whiteboard document with the necessary number of pages is created and added. A default document with a single blank page is automatically added to every whiteboard session. The Whiteboard API allows developers to either programmatically control the various whiteboard elements (such as switching between documents and pages, and selecting drawing tools/colors/stroke widths) or to use a default set of AWT components that encompass complete whiteboard functionality. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 146 Chapter 5. Meeting Services MeetingComponentServic MeetingComponentComp interface WhiteboardComp WhiteboardService WhiteboardComp getWhiteboardForPlace getWhiteboardForPlace interface WhiteboardControls MeetingComponent setTool interface getTool Whiteboard setStrokeColor getViewableComponent getStrokeColor getDefaultToolbar setFillColor getDefaultControlPanel getFillColor getDocuments setStrokeWidth getDocumentCount getStrokeWidth getActiveDocument setTextFont getActivePage getTextFont addDocumentManagerListener removeDocumentManagerListener EventListen interface ...event.WhiteboardDocumentManagerListener whiteboardPageAdded whiteboardPageActivated whiteboardPageActivateRequested whiteboardDocumentAdded interface interface WhiteboardDocument getName getId activateRequest activateRequest isActive getActivePage getFirstPage getLastPage getPages getPageCount Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide WhiteboardPage getName getId activateRequest activateRequest isActive isFirstPage isLastPage getPreviousPage getNextPage getDocument 147 Chapter 5. Meeting Services Description To use Whiteboard Services, the developer must first create an instance of a WhiteboardComp object in the context of an STSession object. All other objects in the Whiteboard Service are exposed as a set of Java interfaces. Once the WhiteboardComp object is created, its WhiteboardService interface is used to create a Whiteboard object within the context of a specific Place object. The Whiteboard object contains the following functionality: • Manages all whiteboard content, including synchronization of the currently active document and page • Provides an AWT component that displays the current page and manages scrolling (if desired) • Provides a default AWT component with Graphical User Interface (GUI) controls for selecting the current whiteboard tool, setting the stroke width, and setting the stroke and fill colors • Provides a listener interface to notify interested parties when whiteboard pages or documents have been added or activated To make a whiteboard component fully functional, the developer can simply obtain the Whiteboard object from the Whiteboard Service and visually contain its viewer, control panel, and toolbar. This approach is the simplest. However, developers wanting more control over the level of functionality (such as limiting the drawing tools to a subset of all tools) or wanting to change the user interface can do so by accessing the different whiteboard interfaces directly. The WhiteboardControls interface (implemented by the Whiteboard object) provides a complete set of methods for setting and getting the current tool, stroke width, stroke color, fill color, and text font. The getViewableComponent() method of Whiteboard allows the developer to specify whether the viewer automatically handles scrolling. If the use_internal_scroll parameter to this method is true, scrollbars appear and disappear as needed to make sure all whiteboard content is viewable regardless of the viewer’s contained size. The AWT Component returned by this method also implements the Sizeable interface and can be cast as such. The Sizeable interface allows control over how the whiteboard data is rendered (scaling, image quality) and how events are received when the preferred size of the Sizeable object has changed (by adding a SizeableListener). See the Sizeable section later in this chapter for more information. The WhiteboardDocument objects within the whiteboard can be retrieved via the getDocuments() method. The WhiteboardDocument interface allows developers to request a document to become the active document as well as to retrieve the individual whiteboard pages. Similarly, the WhiteboardPage interface has methods which request that a page become the active page within a document. To use the Whiteboard Service: Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 148 Chapter 5. Meeting Services 1. Create an STSession object. 2. Create a MeetingFactoryComp object for this STsizeable Session. 3. Create the WhiteboardComp object for this STSession. 4. Log in to the desired Community using the CommunityService. 5. Create the appropriate Place object using the PlacesService. 6. Add a PlaceListener and enter the place. 7. Add the whiteboard activity to the place. 8. Once the whiteboard activity has been successfully added, the Places Service sends an event. At this point, you can obtain a valid whiteboard object by calling the WhiteboardService.getWhiteboardForPlace() method. 9. The developer can now obtain a viewable component, toolbar, and control panel using the Whiteboard object’s getViewableComponent(), getDefaultToolbar(), and getDefaultControlPanel() methods. Each of these methods simply returns a Java AWT component that can be visually contained. Package Activity IDs and Attribute Usage The Whiteboard activity ID is defined in the Whiteboard interface as follows: public static final int WHITEBOARD_ACTIVITY_TYPE = 0x9101; Platform Requirements Because the Whiteboard Service components are pure Java, they run on all platforms. Packages com.lotus.sametime.whiteboard com.lotus.sametime.whiteboard.event Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 149 Chapter 5. Meeting Services See Also • The Meeting Factory Services section in this chapter • The Meeting Moderation and Permissions section in this chapter • The Sizeable section in this chapter • The Places Service section in this guide • Appendix C in this guide • The “Meeting Room” sample in the Toolkit Samples page Example The following example shows how to retrieve a Whiteboard object from the Whiteboard Service and place the toolbar, control panel, and viewer in a Java Panel. // // This example method would be called after receiving // notification that the Whiteboard activity has been added // to the Place. // protected void addWhiteboard() { // Get the WhiteboardService from the session. WhiteboardService whiteboard_service = (WhiteboardService) Session.getCompApi(WhiteboardService.COMP_NAME); // Get the Whiteboard object from the service for // the current Place. Whiteboard whiteboard = whiteboard_service.getWhiteboardForPlace(Whiteboard_Place); // Create a viewer panel to contain the Whiteboard components. Panel whiteboard_panel = new Panel(); whiteboard_panel.setLayout(new BorderLayout()); // Add the Whiteboard GUI components to our panel. whiteboard_panel.add("North", whiteboard.getDefaultControlPanel()); whiteboard_panel.add("Center", whiteboard.getViewableComponent(true)); whiteboard_panel.add("South", whiteboard.getDefaultToolbar()); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 150 Chapter 5. Meeting Services Streamed Media Service Overview General Streamed Media Service The General Streamed Media Service allows clients to access audio, video, and/or data content in a meeting. This service handles all service-level aspects of controlling the content streams, including support for audio mute and pause/play of video. The specific implementation of the service determines which types of content are available and whether the content can be both transmitted and received or received only. Streamed Media Interactive Service The Streamed Media Interactive Service provides clients with two-way communication via audio and video within the context of a place. This service encompasses all the functionality needed to participate in a two-way or multiple-way IP audio/video call. The service handles all semanticlevel aspects of controlling the audio and video streams including support for audio mute, pause/play of video, displaying the video stream, and conducted or request mode audio calls. Streamed Media Broadcast Service The Streamed Media Broadcast Service allows clients to receive the audio, video, and data content being sourced by an interactive client meeting. Clients using this service are limited to only viewing the meeting and cannot interact. Unlike many services, the Broadcast Streamed Media Service does not require the use of places. This service also does not require use of the MeetingFactoryComp. Common uses of the Streamed Media Broadcast Service include remote viewing and large-scale software demonstrations and presentations. This service is more scalable than the interactive services since multicast is used whenever possible. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 151 Chapter 5. Meeting Services General Streamed Media Service AudioDeviceInfo setDeviceName getDeviceName setPreferredDevi isPreferredDevic setDeviceAvailab isDeviceAvailabl setDeviceID getDeviceID interface VideoDeviceInfo StreamedMedia setDeviceName getAudioRecorderDeviceI getDeviceName getAudioPlayerDeviceInf setPreferredDevi getVideoRecorderDeviceI isPreferredDevic getVideoPlayerDeviceInf setDeviceAvailab getAudioRecorder isDeviceAvailabl getAudioPlayer setDeviceID getVideoRecorder getDeviceID getVideoPlayer getDataRecorder getDataPlayer interface AudioController setGain interface interface DataController getViewableComponent getGain VideoController showConfigDialog getViewableComponent setNumberOfVULevels getNumberOfVULevels setVUUpdateRate interface getVUUpdateRate showConfigDialog MediaController setSilenceSuppressionSensi getState getSilenceSuppressionSensi pauseStream addAudioControllerListener resumeStream removeAudioControllerListen isStreamPaused pauseMonitor resumeMonitor isMonitorPaused addMediaControllerListene removeMediaControllerList interface ...event.AudioControllerList gainChanged interface vuChanged ...event.MediaControllerListener silenceDetected stateChanged voiceDetected streamPaused streamResumed monitorPaused monitorResumed monitorActivated monitorInactivated Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 152 Chapter 5. Meeting Services Description The Streamed Media Service is a generic set of interfaces currently implemented by two different types of technology, Interactive and Broadcast media. To use an implementation of the Streamed Media Service, the developer must obtain an instance of the object that implements the StreamedMedia interface. Regardless of which implementation is being used, the StreamedMedia interface is used to retrieve “controller” objects for the audio, video, and data streams. Each controller object is classified by its corresponding Player and Recorder devices. • Player device refers to a device used to locally display remote media. For instance, the “audio player device” refers to a local sound card that plays meeting audio into the local speakers. • Recorder device refers to the device used to capture the local media, which is transmitted from the local machine into the meeting. For instance, the “audio recorder device” refers to a local sound card from which local microphone input is collected. The StreamedMedia interface is used to obtain information about the various Player and Recorder devices that are available on the local machine. This information can be used to select the device to be used in the meeting. All aspects of the local Recorder and Player devices are controlled through three interfaces: • AudioController • VideoController • DataController These interfaces are accessed through the StreamMedia interface by calling one of the following methods: • GetAudioRecorder() • GetAudioPlayer() • GetVideoRecorder() • GetVideoPlayer() • GetDataRecorder() • GetDataPlayer() Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 153 Chapter 5. Meeting Services General Media Controller Framework As shown in the diagram, the AudioController, VideoController, and DataController interfaces derive from the MediaController interface, which contains the following functionality common to all controller types: • Pausing and resuming the associated stream, which stops the flow of data between the client and the server. (When resuming, a delay might occur before displaying resumes, because the stream between the client and server must be re-created.) pauseStream() resumeStream() streamPaused() streamResumed() • Pausing and resuming the monitor associated with the stream, which does not affect the flow of data between the client and the server. (When resuming, there is almost no delay, since the stream was not affected.) pauseMonitor() resumeMonitor() monitorPaused() monitorResumed() monitorActivated() monitorInactivated() • Monitoring state changes of the device being controlled: stateChanged() Typically, once a particular instance of a controller is obtained, the developer will want to add a listener to monitor state changes and other asynchronous controller activity. To add a listener, the developer should implement the MediaController interface and add this listener to the appropriate MediaController through a method call to addMediaControllerListener(). Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 154 Chapter 5. Meeting Services General AudioController The two types of AudioController objects are an audio player and an audio recorder. Both the audio player and recorder objects are controlled through the same AudioController interface. This interface gives developers the ability to control and monitor the following parameters: • • • • Changing the gain of the associated audio stream (volume control): getGain() setGain() gainChanged() Tracking VU (Volume Unit) changes in real time for metering: setNumberOfVULevels() getNumberOfVULevels() setVUUpdateRate() getVUUpateRate() vuChanged() Controlling Silence Suppression adjustments (audio recorder only): setSilenceSuppressionSensitivity() getSilenceSuppressionSensitivity() silenceDetected() voiceDetected() Displaying a device driver’s specific settings panel: showConfigDialog() Typically, once a particular instance of an AudioController is obtained, the developer will want to add a listener to the controller to monitor activities specific to the AudioController. To add a listener, the developer should implement the AudioListener interface and add the listener to the appropriate AudioController through a method call to addAudioListener(). To monitor activity that is common to all controllers, the developer should implement the MediaController interface and add this listener to the appropriate MediaController through a method call to addMediaControllerListener(). Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 155 Chapter 5. Meeting Services General VideoController The two types of VideoController objects are a video player and a video recorder. Both the video player and recorder objects are controlled through the same VideoController interface. This interface gives developers the ability to control and monitor the following: • The ability to view the video being received: • getViewableComponent() The ability to display the video device driver’s specific setup panel: showConfigDialog() Typically, once a particular instance of a VideoController is obtained, the developer will want to add a listener to monitor state changes and other asynchronous controller activity. To do this, the developer should implement the MediaController interface and add this listener to the appropriate VideoController through a method call to addMediaControllerListener(). Since there are no events specific only to a VideoController, there is no VideoListener interface. The AWT Component used for rendering either the local or remote video stream is accessed from the VideoController object through a method call to getViewableComponent(). Once the AWT Component is obtained, it can be cast to a Sizeable object, and a SizeableListener can be added. The Sizeable interface allows the container to control local displaying and to receive events about the Component’s preferred size when the video monitor’s size changes. For more information on the Sizeable interface, see the Sizeable section in this chapter. General DataController The two types of DataController objects are a data player and a data recorder. Both the data player and recorder objects are controlled through the same DataController interface. This interface provides developers with the ability to view the data being received through the getViewableComponent() method. Typically, once a particular instance of a DataController is obtained, the developer will want to add a listener to the controller to monitor state changes and other asynchronous controller activity. To add a listener, the developer should implement the MediaController interface and add this listener to the appropriate DataController through a method call to addMediaControllerListener(). Since there are no events specific only to a DataController, there is no DataListener interface. The AWT Component for monitoring the remote data stream is accessed from the DataController object through a method call to getViewableComponent(). Once the AWT Component is obtained, it can be cast to a Sizeable object and a SizeableListener can be added. The Sizeable interface allows the container to control local displaying and to receive events about the Component’s preferred size when the data monitor’s size changes. For more information on the Sizeable interface, see the Sizeable section in this chapter. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 156 Chapter 5. Meeting Services Streamed Media Interactive Service Note: The details of the general StreamedMedia framew have been left out of this diagram. See the general StreamedMedia framework diagram for those details. MeetingComponentComp MeetingComponentServic interface StreamedMediaComp StreamedMediaService StreamedMediaComp getStreamedMediaForPlace getStreamedMediaForPlace interface StreamedMedia MeetingComponent interface StreamedMediaInteractive ...event.StreamedMediaInteractiveListene micAcquired micRevokeEnabled initAudio micRevokeDisabled initVideo micRevoked setSpeakingMode micEnabled getSpeakingMode micDisabled grabMicRequest speakingModeChanged releaseMicRequest audioRecorderDeviceOpened revokeMicRequest audioPlayerDeviceOpened setAudioLoopback videoRecorderDeviceOpened addStreamedMediaInteractiveListener videoPlayerDeviceOpened removeStreamedMediaInteractiveListener networkConnectionFailed tunnelingActivated accessDenied Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 157 Chapter 5. Meeting Services Description To use the Streamed Media Interactive Service, the developer must create an instance of a StreamedMediaComp object in the context of an STSession. All other objects in this service’s framework are exposed as a set of Java interfaces. Once created, the StreamedMediaService is used to create a StreamedMediaInteractive object, which implements the StreamedMedia interface. StreamedMediaInteractive Object The StreamedMediaInteractive object determines the available audio and video Player and Recorder. The toolkit developer begins by accessing the complete list of audio and video record and playback devices available on the local machine through the various getDeviceInfo() methods. After choosing a device, the developer must then initialize audio, or audio and video, with the selected devices; or pass null into the initialization methods. All aspects of the audio/video recorders and players are controlled through either an AudioController or a VideoController object. These objects are accessed through the StreamedMedia object by calling one of the various accessor methods. Once the developer has obtained an instance of the StreamedMediaInteractive object, the developer sets up all associated UI components before audio and video are initialized. Note that the toolkit handles the explicit opening and closing of the audio and video device. The developer is only responsible for initializing the appropriate audio and/or video activity. The StreamedMediaInteractive object is used to switch between the two different “speaking modes” supported by the toolkit. These modes include: • Automatic Speaking Mode – This mode is a fully interactive type of meeting in which any person with a microphone who is participating in the meeting can speak at any time. • Request Microphone Speaking Mode – This mode is a conducted mode of operation where a meeting participant must request the microphone from the meeting before speaking. Only one person can speak at a time in this types of meeting. The StreamedMediaInteractive component provides the methods with the capability to do all of the following activities with respect to speaking mode: • Change the speaking mode (if you are the meeting moderator). • Request the microphone (when in the Request Microphone Mode). • Release the microphone (when in the Request Microphone Mode). • Revoke the microphone from the current user (if you are the meeting moderator). Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 158 Chapter 5. Meeting Services Streamed Media Broadcast Service StreamedMediaBroadcastFactory getStreamedMediaBroadcast The details of the general StreamedMedia framework have been left out of this diagram. StreamedMedia interface StreamedMediaBroadcast See the Gener StreamedMedia framework for those details. interface ...event.StreamedMediaBroadcastListener streamControlConnecting initVideo streamControlConnected initAudio streamControlFailed connect streamControlReleased disconnect streamControlLost setPassword streamControlPlay addStreamedMediaBroadcastListener streamControlPasswordRequired removeStreamedMediaBroadcastListener Description To use the Streamed Media Broadcast framework, the developer must obtain an instance of a StreamedMediaBroadcast object by calling the getStreamedMediaBroadcast() method in the StreamedMediaBroadcastFactory. All other objects in the Streamed Media Broadcast Service are exposed as a set of Java interfaces. StreamedMediaBroadcast Object The StreamedMediaBroadcast object is used to select the available audio, video, and data players and connect to the broadcast session. Currently, the toolkit developer is required to allow the toolkit to pick the most appropriate device by simply passing null into the initialization methods that require a device to be specified. StreamedMediaBroadcast is then used to establish a connection to the broadcast meeting on the server by calling the connect() method. Because the StreamedMediaBroadcast object does not provide a way to create a broadcast meeting, the meeting must be created by using the Sametime Meeting Center or by using the Places Service. If the Places Service is used to create a new meeting, an existential place attribute (atrribute #9013) can be created in the place prior to adding any activities to the place. If this attribute exists, the meeting is marked as a broadcast meeting. A broadcast receiver can only join meetings that have been marked as broadcast meetings. Also, at least one participant in the interactive meeting must be using the interactive services in order for content to be sourced from the broadcast gateway to the broadcast receivers. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 159 Chapter 5. Meeting Services After calling the connect() method of StreamedMediaBroadcast, a method of the StreamedMediaBroadcastListener interface will be called to indicate whether the meeting was successfully joined. The streamControlConnected() method indicates the meeting has been joined, and the streamControlFailed() method indicates failure. If a password is required to join the meeting, the streamControlPasswordRequired() event handler of the StreamedMediaBroadcastListener interface will be called. Use the setPassword() method of the StreamedMediaBroadcast interface to pass the password to the framework. When the client has successfully connected to the meeting, the StreamedMediaBroadcast object can be used to retrieve the AudioController, VideoController, and DataController objects corresponding to the audio, video, and data streams. Only the player versions of the controllers can be retrieved in a broadcast meeting. The VideoController and DataController objects each contain an AWT component that displays the contents of the specific stream. The AudioController displays its stream contents via the computer speakers. Each controller is also used to pause and resume the stream or the monitor. Pausing the stream stops the server’s transmission of data to the client. Pausing the monitor stops the client’s displaying of the data but does not stop the transmission of data from the server. When a stream is paused and then resumed, a delay will occur before the displaying of the data resumes on the client. Broadcast AudioController The audio player is the only type of AudioController object when using the Streamed Media Broadcast Service. The audio player only has content to play when a participant in the meeting uses an audio recorder with the Streamed Media Interactive Service. See the AudioController and MediaController descriptions in the Streamed Media Service section of this chapter for more information. Note An audio device setup panel is not supported in the Streamed Media Broadcast Service. Broadcast VideoController The video player is the only type of VideoController object when using the Streamed Media Broadcast Service. The video player only has content to display when a participant in the meeting uses a video recorder in the Streamed Media Interactive Service. See the VideoController and MediaController descriptions in the Streamed Media Service section of this guide for more information. Note A video device setup panel is not supported in the Streamed Media Broadcast Service. Broadcast DataController The data player is the only type of DataController object when using the Streamed Media Broadcast Service. The data player only has content to display when a participant in the meeting uses the Application Sharing or Whiteboard Interactive services. The broadcast client can view content from only one of these services at a time. When the interactive client wants the broadcast clients to switch between application sharing and whiteboard content, an attribute in the place must be set. See the DataController and MediaController descriptions in the Streamed Media Service section of this guide for more details. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 160 Chapter 5. Meeting Services Activity IDs and Attribute Usage The Audio activity ID and the Video activity ID are both defined in the Streamed Media interface as follows: public static final int AUDIO_ACTIVITY_TYPE = 0x9103; public static final int VIDEO_ACTIVITY_TYPE = 0x9104; Note There is no activity ID or attributes for the Streamed Media Broadcast Service, since the Streamed Media Broadcast framework does not rely on the Places Service. Place Attribute Usage Attribute Name ID # Type Possible Values Notes Currently Visible Activity 9007 Integer 1 – Whiteboard The broadcast gateway expects this place attribute to be set by the client application. This setting triggers the broadcast gateway to display either AppShare or Whiteboard content. 2 – Application Sharing Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 161 Chapter 5. Meeting Services User Attribute Usage Attribute Name ID # Type Possible Values Audio Recorder State 6 Integer 1 – Controller is active 2 – Controller is paused 3 – Controller is disabled Audio Player State 7 Integer 1 – Controller is active 2 – Controller is paused 3 – Controller is disabled Video Recorder State 8 Integer 1 – Controller is active 2 – Controller is paused 3 – Controller is disabled Video Player State 9 Integer 1 – Controller is active 2 – Controller is paused 3 – Controller is disabled Speaking User’s State 10 Integer 1 – Controller is active 2 – Controller is paused 3 – Controller is disabled Platform Dependencies The Streamed Media Interactive Service is currently limited to sourcing and playing back audio and video streams within the Windows® operating system. Also, the StreamedMediaInteractive component must run in a Virtual Machine (VM) that supports Java Native Interface (JNI). The Streamed Media Broadcast Service is currently limited to playing back audio, video, and data streams within the Windows operating system. Packages com.lotus.sametime.streamedmedia com.lotus.sametime.streamedmedia.event Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 162 Chapter 5. Meeting Services See Also • The Meeting Factory Services section in this chapter • The Meeting Moderation and Permissions section in this chapter • The Sizeable section in this chapter • The Places Service section in this guide • Appendix C in this guide • The “Meeting Room” and “Broadcast” samples in the Toolkit Samples page Examples Example 1 – Initiating the connection to the broadcast meeting on the server. public void init() { StreamedMediaBroadcast broadcast = StreamedMediaBroadcastFactory.getStreamedMediaBroadcast(); broadcast.addStreamedMediaBroadcastListener(this); broadcast.initAudio(null); broadcast.initVideo(null); try { broadcast.connect( null, // PAC file helper object “sametimeserver”, // direct connection server name 554, // direct connection port “sametimeserver”, // tunnel connection server name 554, // tunnel connection port “Sametime”, // mount point “mid=SAMA-4NAPHP”, // meeting id “Anonymous”, // user name “(550CB12AE301A64368FE4748D14F6BC7)”,// access token 1000, // buffer time 5000, // direct connection timeout 5000, // tunnel connection timeout 900000); // tunnel connection aux timeout } catch (StreamedMediaException exception) { System.out.println(exception.getMessage()); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 163 Chapter 5. Meeting Services Example 2 – Retrieving the viewers for the data and video streams after the connection to the server has been established and adding them to the UI public void streamControlConnected(StreamedMediaBroadcastEvent event) { StreamedMediaBroadcast broadcast = (StreamedMediaBroadcast)event.getSource(); DataController data_player = broadcast.getDataPlayer(); VideoController video_player = broadcast.getVideoPlayer(); setLayout(new BorderLayout()); add(data_player.getViewableComponent(), BorderLayout.CENTER); add(video_player. getViewableComponent (), BorderLayout.EAST); } Example 3 – Adding and initializing the interactive Video Component. // The VideoExample class shows how to add the video activity to // a Place, obtain the StreamedMediaInteractive component from the // StreamedMediaService, initialize the Video component and add // a listener to know when the component has actually been started. public class VideoExample { // Constructs a VideoExample for the given STSession and Place. public VideoExample(STSession session, Place meeting_place) { // Add the core video activity to the Place. meeting_place.addActivity ( StreamedMedia.VIDEO_ACTIVITY_TYPE, null); // Get the StreamedMediaService from the STSession by name. StreamedMediaService streamed_media_service = (StreamedMediaService) session.getCompApi(StreamedMediaService.COMP_NAME); // Get the StreamedMediaInteractive for the given Place // from the StreamedMediaService. StreamedMediaInteractive streamed_media_interactive = streamed_media_service.getStreamedMediaForPlace(meeting_place); try { // Initialize the Video activity. By specifying null // for both the recorder and player device parameters, // the StreamedMediaInteractive component will be // reponsible for choosing an appropriate device. streamed_media_interactive.initVideo(null, null); } catch (StreamedMediaException exception) { System.out.println("Unable to initialize Video."); } // Add a MeetingCompListener to the StreamedMediaInteractive. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 164 Chapter 5. Meeting Services // This will allow us to receive events as the component // becomes available. streamed_media_interactive.addMeetingCompListener( new MeetingCompHandler()); } // Inner class for handling MeetingCompEvents. class MeetingCompHandler extends MeetingCompAdapter { public void componentStarted(MeetingCompEvent event) { System.out.println("Video Component Started."); } } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 165 Chapter 5. Meeting Services Meeting Moderation and Permissions Overview The meeting moderator is a user who has a special role in a place. The moderator controls the level of participation of all other users by enabling and disabling a set of permissions. These permissions control: • The ability to share an application or drive a shared application • The ability to draw on the whiteboard or switch the current whiteboard page • The ability to source audio and video content (speak) The meeting moderator role can be transferred between users. Only the current meeting moderator can relinquish moderator status by selecting another user in the place to assume this role. Description By default, users have all permissions enabled when entering a place (both Permission to Edit/Share and Permission to Speak are set to true). When controlling the participation level of individual users is not a concern, the meeting moderator and user permissions can simply be ignored and all users will be able to participate. However, if it is important for a particular application to control the permissions of individual users, this control can be exercised by the meeting moderator and through user permissions. Any application that intends to interact with the Sametime Meeting Room Client (MRC) should be aware that the MRC makes use of the meeting moderator and user permissions. Initially, the creator of a meeting is the meeting moderator. See the section “Adding the Audio Activity” in Chapter 9 of the Sametime Java Toolkit Tutorial for information on how the meeting creator should set himself as the meeting moderator so that the Meeting Services will initialize correctly. Although there can only be one meeting moderator in a place at a given time, this role can be passed among users. If a user is granted the meeting moderator role and subsequently leaves the place, moderator status is returned to the initial meeting moderator. Only the current meeting moderator has the ability to grant another user the moderator role or change the user permissions of meeting participants. User Meeting Permissions The two types of permissions associated with a user in a meeting are: • Permission to Edit/Share (Data) – Both application sharing and the whiteboard are controlled by this permission. Users with Permission to Edit/Share can share applications, Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 166 Chapter 5. Meeting Services control shared applications, modify whiteboard content, and switch between whiteboard pages. With Permission to Edit/Share disabled, users will only be able to view the content of both application sharing and the whiteboard. • Permission to Speak (Audio/Video) – Users with Permission to Speak can source (i.e., transmit) both audio and video content. With Permission to Speak disabled users will only be able to view video and hear audio sourced by other meeting participants. The meeting moderator and user permissions values are stored as user attributes within a place. Users can add a UserInPlaceListener to their MyselfInPlace object to receive events as their moderator status and meeting permissions change. The user attributes should only be set or altered by the Sametime server. Users should not attempt to modify them using the standard methods to alter a user attribute. The table below lists and defines moderation-related user attributes: Attribute Name Attribute ID Type Possible Values Notes Permission to Edit/Share (Data) 1 Boolean true or false Determines whether this user can share an application or modify whiteboard content Permission to Speak (Audio/Video) 2 Boolean true or false Determines whether this user can send audio or video content Moderator 3 Boolean true or false Determines whether this user is currently the meeting moderator Modifying User Meeting Permissions The meeting moderator can modify these attributes by sending a request (data message) to the server via the sendData() method of the Activity object representing the Application Sharing, Whiteboard, Audio, or Video activity (you can use any of these activities). The following table lists and defines the data messages that the meeting moderator can send. Name of Data Message Type Value GRANT_AV_PERMISSION 1 String containing a list of user IDs separated by semicolons (;). REVOKE_AV_PERMISSION 2 String containing a list of user IDs separated by semicolons (;). GRANT_DATA_PERMISSION 3 String containing a list of user IDs separated by semicolons (;). Data Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 167 Chapter 5. Meeting Services REVOKE_DATA_PERMISSION 4 String containing a list of user IDs separated by semicolons (;). GRANT_AV_TO_ALL 5 N/A REVOKE_AV_FROM_ALL 6 N/A GRANT_DATA_TO_ALL 7 N/A REVOKE_DATA_FROM_ALL 8 N/A SWITCH_MODERATOR 9 The User ID of the user who is becoming the moderator A reference to the Meeting Activity object can be retrieved by calling getActivity() on any of the PlaceEvents received as the meeting activities are added to the Place. Platform Requirements Switching the Meeting Moderator and modifying user attributes is done completely in Java and therefore can run on any platform. See Also • The Whiteboard Service section of this guide • The Application Sharing Service section of this guide • The Streamed Media Service section of this guide Example The following example is a simple class that is passed as a reference to a Place object upon construction. The STSamplePermissionsManager class prints messages to the Java console as meeting user permissions change. It also provides two methods, setPermissions() and setModerator(), that attempt to alter user meeting permissions and switch the moderator to another user. public class STSamplePermissionsManager { // User Attributes. public static final int DATA_PERMISSION public static final int AV_PERMISSION public static final int MEETING_MODERATOR = 1; = 2; = 3; // Meeting Activity Permissions Data Messages. public static final int GRANT_AV_PERMISSION = 1; public static final int REVOKE_AV_PERMISSION = 2; Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 168 Chapter 5. Meeting Services public public public public public public public static static static static static static static final final final final final final final int int int int int int int GRANT_DATA_PERMISSION REVOKE_DATA_PERMISSION GRANT_AV_TO_ALL REVOKE_AV_FROM_ALL GRANT_DATA_TO_ALL REVOKE_DATA_FROM_ALL SWITCH_MODERATOR = = = = = = = 3; 4; 5; 6; 7; 8; 9; // The Meeting Activity used for sending Data Messages // to the server. private Activity Meeting_Activity = null; public STSamplePermissionsManager(Place place) { // Obtain our MyselfInPlace object from the Place // and add a UserHandler. MyselfInPlace myself_in_place = place.getMyselfInPlace(); myself_in_place.addUserInPlaceListener(new UserHandler()); // Add a PlaceHandler as a listener to the Place. place.addPlaceListener(new PlaceHandler()); } // The setModerator() method is called when this user // wants to change the Moderator to another user. This // can only succeed if this user is currently the Moderator. public void setModerator(STUser user) { if (Meeting_Activity != null) { // This sendData() call results in a message being sent // to the Sametime server requesting a change of // Moderator. Meeting_Activity.sendData (SWITCH_MODERATOR, user.getId().getId().getBytes()); } } // The setPermissions() method is called when this user // wants to change the permissions of a set of users. // This can only succeed is this user is currently the // Moderator. public void setPermissions(STUser[] users, int permission_type) { String users_string = new String(""); // Build a list of UserID's separated by the semi-colon // character (";"). for (int i = 0; i < users.length; i++) { users_string = users_string + users[i].getId().getId()+";"; } if (Meeting_Activity != null) { // This sendData() call results in a message being sent // to the Sametime server requesting a change of // permissions for the specified users. Meeting_Activity.sendData ( Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 169 Chapter 5. Meeting Services permission_type, users_string.getBytes()); } } class PlaceHandler extends PlaceAdapter { public void activityAdded(PlaceEvent event) { Activity activity = event.getActivity(); switch (activity.getActivityType()) { case Whiteboard.WHITEBOARD_ACTIVITY_TYPE: case AppShare.APPSHARE_ACTIVITY_TYPE: case StreamedMedia.AUDIO_ACTIVITY_TYPE: case StreamedMedia.VIDEO_ACTIVITY_TYPE: Meeting_Activity = activity; break; } } } class UserHandler extends UserInPlaceAdapter { public void attributeChanged(PlaceMemberEvent event) { // As the Meeting User Attributes change, // print a message to the Java console. switch (event.getAttributeKey()) { case DATA_PERMISSION: System.out.println( "Data Permissions Changed: " + event.getAttribute().getBoolean()); break; case AV_PERMISSION: System.out.println( "Audio/Video Permissions Changed: " + event.getAttribute().getBoolean()); break; case MEETING_MODERATOR: System.out.println( "Moderator Status Changed: " + event.getAttribute().getBoolean()); break; } } public void attributeRemoved(PlaceMemberEvent event) { // It is important to listen for the removal of // the Meeting Moderator attribute. If it is removed, // this User is not the Meeting Moderator. if (MEETING_MODERATOR == event.getAttributeKey()) { System.out.println("Moderator Status Changed: false"); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 170 Chapter 5. Meeting Services } } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 171 Chapter 5. Meeting Services Sizeable Interface Overview The Sizeable Interface is implemented by all Meeting Services AWT components. Its purpose is to allow developers to better contain these components and control how they are displayed. Developers can: • Be notified when the desired size of a Sizeable component has changed. • Switch between “draft quality” and “high quality” display modes. • Control whether the Sizeable component displays itself scaled to fit its current size. Diagram interface interface Sizeable FIT_TO_DATA FIT_TO_COMPONENT ...gdk.event.SizeableListen sizeChanged modeChanged DRAFT_QUALITY HIGH_QUALITY setRenderingMode getRenderingMode setRenderingHint getRenderingHint addSizeableListener removeSizeableListener Description Although all Meeting Services getViewableComponent() methods return a standard Java AWT Component, they all implement the Sizeable interface and can be cast as such. Not all Sizeable components implement all of the Sizeable functionality. For example, calling setRenderingHint() on the Application Sharing’s viewable component has no effect. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 172 Chapter 5. Meeting Services The three major functions enabled by the Sizeable interface are: • Size Change Notification – Containers can be notified of a Sizeable component’s change in size by registering as a SizeableListener by calling the addSizeableListener() method. This allows the parent container a chance to make any layout changes necessary to accommodate the new size of a Sizeable component. See Example 1 below. • Scaling Rendered Data – By calling setRenderingMode(), developers can control whether a Sizeable component scales its image data to fit its current contained size (FIT_TO_COMPONENT) or displays it at its preferred size (FIT_TO_DATA). See Example 2 below. • Controlling Rendering Quality – By calling setRenderingHint(), developers can control the quality of the Sizeable component’s displayed data. Platform Requirements The Sizeable interface is pure Java and therefore runs on all platforms. Package com.lotus.sametime.gdk com.lotus.sametime.gdk.event See Also The Whiteboard Service section of this guide The Application Sharing Service section of this guide The Streamed Media Service section of this guide Example Example 1 The following example shows how to cast a shared application’s viewable component to a Sizeable object, add a SizeableListener, and change the size of the containing frame as the size of the component changes. // This example class is a sample AppShare container. // It is constructed with a AppShare object and simply // contains the AppShare's viewer in a java Frame, which // is resized as the AppShare viewer's preferred size // changes. public class AppSharePanel extends Frame {// This example class is a sample AppShare container. // It is constructed with a AppShare object and simply Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 173 Chapter 5. Meeting Services // contains the AppShare's viewer in a java Frame, which // is resized as the AppShare viewer's preferred size // changes. public class AppSharePanel extends Frame { private Component AppShare_Viewer_Component = null; public AppSharePanel(AppShare appshare) { super("Application Sharing"); Component appshare_viewer = null; Sizeable appshare_sizeable_component = null; // Passing "false" when getting the viewable component // from the AppShare object disables the default scrolling. AppShare_Viewer_Component = appshare.getViewableComponent(false); // Cast the AppShare viewable Component to a Sizeable object. appshare_sizeable_component = (Sizeable) AppShare_Viewer_Component; // Add ourselves as a sizeable listener (see the "sizeChanged()" // and "modeChanged()" methods below). appshare_sizeable_component.addSizeableListener( new SizeableHandler()); // Set the layout and add the AppShare viewer. setLayout(new BorderLayout()); add("Center", AppShare_Viewer_Component); // Make this frame visible. setVisible(true); } class SizeableHandler extends SizeableAdapter { public void sizeChanged(SizeableEvent event) { Dimension appshare_preferred_size = null; Insets frame_insets = null; int frame_width = 0; int frame_height = 0; // Ask the AppShare component for its preferred size. appshare_preferred_size = AppShare_Viewer_Component.getPreferredSize(); // Get the insets of this frame (this accounts for the // size of the window frame and border and will be added // to the AppShare viewer's preferred size when //determining the new size of the Frame). frame_insets = getInsets(); // Set the Frame's new size. setSize( appshare_preferred_size.width + insets.left + Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 174 Chapter 5. Meeting Services insets.right, appshare_preferred_size.height + insets.top + insets.bottom); } } } Example 2 The following example shows how to cast a whiteboard’s viewable component to a Sizeable object and then allow the user to switch between display modes (FIT_TO_DATA and FIT_TO_COMPONENT). // This example class is a sample Whiteboard container. // It is constructed with a Whiteboard object and simply // contains the Whiteboard's viewer as well a Checkbox control // to turn scaling on and off. public class WhiteboardPanel extends Panel implements ItemListener, SizeableListener { private Sizeable Sizeable_Whiteboard_Component = null; public WhiteboardPanel(Whiteboard whiteboard) { // Passing "true" when getting the viewable component // from the Whiteboard object enables the default scrolling. Component whiteboard_viewer = whiteboard.getViewableComponent(true); // Cast the Whiteboard viewable Component to a Sizeable object. Sizeable_Whiteboard_Component = (Sizeable) whiteboard_viewer; // Set the layout, create the checkbox & add ourselves as a // listener, and add the componets to this panel. setLayout(new BorderLayout()); Checkbox scale_checkbox = new Checkbox("Scale Whiteboard Content"); scale_checkbox.addItemListener(this); add("North", scale_checkbox); add("Center", whiteboard_viewer); } // The ItemListener interface method "itemStateChanged". // This method is called when the user has checked or // unchecked our "scaling" checkbox. public void itemStateChanged(ItemEvent event) { if (event.getStateChange() == ItemEvent.SELECTED) { // The user has "checked" the scaling checkbox— // set the rendering mode of the Sizeable object // to FIT_TO_COMPONENT. This means that the // component will resize its content to fit its // current contained size. In this case whiteboard // will scale the current page image to exactly // fit its current size. Sizeable_Whiteboard_Component.setRenderingMode( Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 175 Chapter 5. Meeting Services Sizeable.FIT_TO_COMPONENT); } else { // The user has "unchecked" the scaling checkbox— // set the rendering mode of the Sizeable object // to FIT_TO_DATA. This means that the component // will ignore its current size and render its // content at its preferred size. In this case, // the Whiteboard component will automatically use // scrollbars if needed. Sizeable_Whiteboard_Component.setRenderingMode( Sizeable.FIT_TO_DATA); } } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 176 Appendix A. Enabling Your Domino Applications This appendix describes the process for enabling a Domino database template with Sametime. The STJavaSample.nsf sample application contains all the agents and script libraries you need to enable your template. The agents do the following: 1. Generate an access token for the user. 2. Locate a Sametime server from which the applet will be loaded. Using Tokens Token authentication allows a user who has logged in to your application to log in to the Sametime server without being challenged to authenticate again. The application generates a token and passes it to the Sametime applet. The applet logs in by token to the Sametime server. The Sametime server includes two separate security features capable of generating the authentication token used by Sametime: • Domino Single Sign-On (SSO) Authentication – This authentication method uses Lightweight Third Party Authentication (LTPA) tokens. • Secrets and Tokens authentication databases – Releases of Sametime before 3.0 used only the Secrets and Tokens authentication databases to create authentication tokens. For this reason, the Sametime server must support both the Domino SSO feature and the Secrets and Tokens authentication system when Sametime operates in environments that include previous versions of Sametime. The recommended authentication mode for applications that work with a Sametime server is LTPA. However, if the Domino server uses a DSAPI filter for authentication instead of LTPA, the application can authenticate with a Secrets and Tokens token. The sample application STJavaSample.nsf first looks for an LTPA token. If the LTPA token cannot be found, a Secrets & Tokens token is generated. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 177 Appendix A. Enabling Your Domino Applications Locating the Sametime Server Sametime-enabled applications running on a non-Sametime server must locate the user's home Sametime server, or a Sametime server in the user's LAN. When the application generates a Web page that contains a Sametime applet, it also needs to know the codebase of the applet – that is, a Sametime server that contains the applet. You must create your application so that it can find the server information it needs. The previous versions of the Java toolkit recommended that you use a LotusScript® agent to look in the Domino Directory for the user's person record and the associated home server. This method currently works only with the Domino Directory. You cannot use it with LDAP directories or for anonymous access. A more reliable, efficient, and flexible method is to deploy a special XML file, hostAddress.xml, on the application server. This file contains a nearby Sametime server location. This method requires some simple administrator intervention; but it uses less code, performs more efficient lookup, works with both Domino and LDAP directories, and works with both anonymous and authenticated access. The format of this XML file is: <?xml version="1.0" encoding="UTF-8" ?> <sametime> <hostAddress>myhost.lotus.com</hostAddress> <httpPort>80</httpPort> </sametime> The Sametime server installation process generates this XML file, inserting the address of the Sametime server on which the toolkits are installed. It then stores the XML file in the "sametime" directory under the HTTP root. If you are using a Sametime 2.5 server, you can create and store the file manually. You must deploy this XML file to the same location (the “sametime” directory under the HTTP root) on all of your application servers. The application can then use HTTP to read the address of the Sametime server from this XML file and load the applet from the server. The Sametime server whose address appears in the XML file is not necessarily the user's home server. However, it will redirect the user to the appropriate home server. Note A Sametime server updates the generated XML file automatically if the host address changes. If your application uses the file, you must then re-deploy the updated file to your application servers. The agent SametimePopulateHostFields in the STJavaSample.nsf sample application works with Sametime servers and the XML file to locate the Sametime server. You can use this agent in your own applications. See the "Using the Sample Domino Application" section that follows. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 178 Appendix A. Enabling Your Domino Applications Using the Sample Domino Application The sample application STJavaSample.nsf is located in the Java Toolkit code directory. It is a Notes and Web application database – it can be viewed both in a browser and in the Notes client. To use this sample, copy it to the Domino Data directory. Open the database using either a browser or the Notes client. If login is successful, you should see your name turn green. The sample uses a sample applet, TokenLoginApplet, that demonstrates login by token. There is a link to the Java source code for this applet in the toolkit Samples Web page. Enabling Your Template The following steps are required to enable an application or template with Sametime: 1. Prepare the template. 2. Enable a form. 3. Test the template. 4. Distribute the template. The Sametime script libraries and agents are required to enable your template with Community and Meeting Services. The processes are slightly different for Web templates and Notes templates; these differences are noted below. Step 1: Prepare the template For the template to be enabled with Sametime, it must contain the Sametime script libraries and agents. Copy the Sametime script libraries to your template Copy the following script libraries from the STJavaSample.nsf database in the Script Libraries view, and paste them into the same view in your template: • SametimeHost • SametimeAgent • SametimeClient • SametimeStrings Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 179 Appendix A. Enabling Your Domino Applications Copy the Sametime agents to your template Copy the following agents from the Sametime Discussion or Teamroom® template in the Agents view and paste them into the same view in the template that you want to enable: • Web templates – SametimePopulateTokenLTPA, SametimePrePopulateTokenST, SametimePopulateTokenST and SametimePopulateHostField agents • Notes templates – SametimeJavaGetLtpaToken and SametimeCreateTokenNotes agents Sign the agents Because of Sametime’s security features, the agent must be signed by an authorized developer to run on a Sametime or Domino server. Your server administrator should grant you the required server access controls. Once you are granted proper access, sign the Sametime agents that you copied to your template. 1. Ask the server administrator to add your name to the “Run unrestricted LotusScript/Java Agents” list in the Agent Manager section of the server document for the Sametime or Domino server where you want to put the application. 2. Choose agents in the enabled database’s client menu. Double-click the agent that you want to sign. 3. Save the agent. The agent is now signed. To verify that the agent was signed successfully: 1. Right-click the agent and choose Properties. 2. Click the Fields tab and check that the $UpdatedBy field contains your name. You might need to repeat the agent-signing procedure for each new server on which the template will be installed. Step 2: Enable a form Enabling a Web form To enable a form in a Web template: 1. Add three hidden computed-for-display text fields. Name them HTTP_Cookie, Server_name, and Server_Port, after the CGI variables that are used by the agents. Specify an empty string as the value formula for each field. Domino will place the CGI variable values in the fields automatically. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 180 Appendix A. Enabling Your Domino Applications 2. Add the following lines to the WebQueryOpen event of the form: @Command([ToolsRunMacro]; "SametimePopulateHostField"); @Command([ToolsRunMacro]; "SametimePopulateTokenLTPA"); @If((SAMETIME_TOKEN=""); @Do(@Command([ToolsRunMacro]; "SametimePrePopulateTokenST"); @Command([ToolsRunMacro]; "SametimePopulateTokenST"));"") Note If you are going to deploy your application on a Sametime server from a previous Sametime release (2.5 or earlier), remove the command that runs the agent SametimePopulateTokenField; LTPA tokens are not supported in previous releases. 3. Use Pass-Thru HTML to add a Sametime applet to the form. Mark the whole paragraph starting with the “<applet>” tag and ending with the “</applet>” tag as Pass-Thru HTML. For the CODEBASE property, use: CODEBASE=http://[SAMETIME_HOST]/sametimeapplets/ The [SAMETIME_HOST] is a computed-for-display text field. The name of the field should be SAMETIME_HOST. Specify an empty string as the value formula. The actual value is computed by the SametimePopulateHostField agent. Note The codebase is set to the directory called “sametimeapplets”on the user’s home Sametime server. Put your applet class and archive files in that directory. If you want to put your applet files in a different directory, change the CODEBASE property accordingly. If your applet uses token-based authentication, it should be given access to the user name and Sametime token by providing the applet with the following parameters: <PARAM NAME="loginName" VALUE="[loginName]"> The loginName is a computed-for-display text field. The value formula is “@UserName.” <PARAM NAME="token" VALUE="[SAMETIME_TOKEN]"> The [SAMETIME_TOKEN] is a computed-for-display text field. The field name should be SAMETIME_TOKEN. Specify an empty string as the value formula. The actual value is computed by the SametimePopulateTokenField agent. Make sure that your applet gets these parameters and uses them to log on to the Sametime server. Enabling a Notes Client form To enable a form in a template for the Notes client: 1. In the (Options) script of the form object, write: Use "SametimeClient" Use "SametimeHost" Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 181 Appendix A. Enabling Your Domino Applications 2. In the PostOpen event of the form, write: Dim token As String Dim host As String ' Get the Authentication token token = SametimeGetToken() Call gSametimeSession.SetEnvironmentVar(ENV_ST_TOKEN, token) ' Get the host name of the sametime server host = SametimeGetHostNotes() Call gSametimeSession.SetEnvironmentVar(ENV_ST_HOST, host) 3. In the QueryClose event of the form, write: the following: Call gSametimeSession.SetEnvironmentVar(ENV_ST_TOKEN, "") Call gSametimeSession.SetEnvironmentVar(ENV_ST_HOST, "") 4. Add a Sametime applet to the form. You can either import the applet, or link to the applet on the Sametime server. 5. Add a parameter named “codebase” to the applet. The parameter formula should be "http://" + @Environment("SThost") + "/sametimeapplets". The codebase parameter is set to the directory called “sametimeapplets ”on the Sametime server. The applet will be loaded from the codebase parameter, so you must put the applet’s class and archive files in that directory. Although you might have imported the applet or linked to another location, the applet will actually be loaded from the computed codebase parameter. 6. If your applet uses token-based authentication, it should be given access to the user name and Sametime token, as follows: • Add a parameter named “loginName” to the applet. The parameter formula should be “@UserName”. • Add a parameter named “token” to the applet. The parameter formula should be @Environment("STtoken"). Your applet should get these parameters and use them to log on to the Sametime server. Note To enable a form for both Web and Notes access, follow the instructions for enabling a Web form and for enabling a Notes form. You will place two copies of the applet on the form, one for Web access and one for Notes access. Use the settings “Hide paragraph from Notes R4.6 or later” and “Hide paragraph from Web browsers” to hide the applets. Step 3: Test the template The last step before deploying the Sametime-enabled application on the Sametime server is to test the application for awareness and conversation capabilities. Typically, this testing means having several users online and having them see each other online and communicate by sending real-time messages. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 182 Appendix A. Enabling Your Domino Applications Step 4: Distribute the template Once the template has been tested, it can be deployed across other Sametime and Domino servers. You might have to repeat the agent-signing procedure for each new server where the template will be installed. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 183 Appendix B. Component Dependencies for Loading and Packaging The first step in using the Sametime Java Toolkit is to create a Sametime session and load the components into it. This appendix describes component dependencies and restrictions, the various ways to load components, and how to load components selectively. Loading a selected group of components allows you to use some of the Sametime capabilities, while removing others. One example is to load only the service components and to implement your own user interface (UI), replacing the standard Sametime UI with your own. Removing unneeded components also allows you to create clients that are more compact. Methods of Loading Components The standard way to load components is by calling STSession.loadAllComponents(). Currently this method is limited to loading only the community components. Alternative ways of loading components are also provided by the toolkit and are described below. Using STSession.loadComponents The STSession.loadComponents() method accepts an array of component names and loads them into the session. The names of the components should be fully qualified Java class names of the classes that implement the component interfaces. (See the “Available Components” section below for a list of these classes.) This method will skip components it cannot load. Note that the meeting components cannot be loaded in this manner since they have unique constructors. An example implementation is: STSession session = new STSession("A name"); String[] components = { "com.lotus.sametime.community.STBase", "com.lotus.sametime.im.ImComp" }; session.loadComponents(components); IMService im = session.getCompApi(IMService.COMP_NAME); Creating Components Directly An alternative way of loading components is to instantiate the component objects yourself, using the “new” operator with the component implementation class. To the component constructor, pass a reference to the containing Sametime session. The component will register itself to that session. You can also keep a pointer to the component while loading it and avoid using the STSession.getCompApi() method. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 184 Appendix B. Component Dependencies for Loading and Packaging An example implementation is: STSession session = new STSession("A name"); new STBase(session); // Keep the reference to the IM component, // instead of calling 'getCompApi'. IMService im = new ImComp(session); Using STSession.loadAllComponents It is possible to load components selectively even if you use the STSession.loadAllComponents() method. This method tries to load all community components. If a component is not found, it will be skipped. Therefore, you can remove unwanted components when packaging your application and those components will not be loaded. Restrictions Keep the following restrictions in mind when loading components: • The meeting components must be loaded explicitly using the new operator. • Dependencies exist between components. When you load a component selectively, you need to make sure that you also load all the components it depends upon. See the section below, “Component Dependencies,” for more details. • The UI dialogs and panels provided with Sametime need to have all the components available. If you use the Sametime UI, you must load all the components. • An STSession cannot hold more than one instance of a component of a given type. Each type of component can only be loaded once. If you try to load a second instance of a component into a session, a DuplicateObjectException will occur. • The Community Services components must be loaded before the session is started. • If you are creating an applet that uses the AwarenessList AWT component, and you want to support file transfer (through the Send File menu option that appears when a user right-clicks an online name in the Awareness List), you must sign the applet, to allow local file access. If you want to use the AwarenessList AWT component in an unsigned applet, file transfer will not be supported. In this case, load the components your applet requires separately (instead of using STSession.loadAllComponents), and omit the FileTransferUI component. Otherwise, the menu option will appear but will not work. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 185 Appendix B. Component Dependencies for Loading and Packaging Available Components The following tables list the available Sametime components, the names of their interfaces, and the implementation class. The implementation class can be passed to the STSession.loadComponents() method or created directly. Service Components Name Component Interface Implementation Class Announcement AnnouncementService com.lotus.sametime.announcement.AnnouncementComp Awareness AwarenessService com.lotus.sametime.awareness.AwarenessComp AppShare AppShareService com.lotus.sametime.appshare.AppShareComp Community CommunityService com.lotus.sametime.community.STBase Conference N/A. For backwards compatibility only. com.lotus.sametime.conf.ConfComp Directory DirectoryService com.lotus.sametime.directory.DirectoryComp File Transfer FileTransferService com.lotus.sametime.filetransfer.FileTransferComp Instant messaging InstantMessaging Service com.lotus.sametime.im.ImComp Lookup LookupService com.lotus.sametime.lookup.LookupComp Meeting Factory MeetingFactoryService com.lotus.sametime.conference.MeetingFactoryComp Names NamesService com.lotus.sametime.names.NamesComp Places PlacesService com.lotus.sametime.places.PlacesComp Post PostService com.lotus.sametime.post.PostComp Storage StorageService com.lotus.sametime.storage.StorageComp Streamed Media StreamedMediaService com.lotus.sametime.streamedmedia.StreamedMediaComp Token TokenService com.lotus.sametime.token.TokenComp Whiteboard WhiteboardService com.lotus.sametime.whiteboard.WhiteboardComp Who is here WihService com.lotus.sametime.wih.WihComp UI Components Announcement UI AnnouncementUI com.lotus.sametime.announcementui. AnnouncementUIComp Community UI CommUI com.lotus.sametime.commui.CommUIComp Chat UI ChatUI com.lotus.sametime.chatui.ChatUIComp FileTransfer UI FileTransferUI com.lotus.sametime.filetransferui.FileTransferUIComp Resource loader N/A. Used internally by the UI components. com.lotus.sametime.resourceloader.ResourceLoaderComp Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 186 Appendix B. Component Dependencies for Loading and Packaging Component Dependencies Components are interdependent. When loading a component selectively, make sure that all the components it depends on are also loaded. The table below lists the component dependencies. Service Components Component Name Depends on Announcement Community AppShare Community, Places, Meeting Factory Awareness Community Buddy List Community, Storage Community - Conference Community Directory Community FileTransfer Community Instant messaging Community Lookup Community Meeting Factory Community, Places Names - Places Community Post Community, Im Storage Community Streamed Media Community, Places, MeetingFactory Token Community Whiteboard Community, Places, MeetingFactory Who is here Community UI Components Announcement UI Announcement, Community, Chat UI Community UI Community, Resource loader Chat UI All FileTransfer UI FileTransfer, Community, Awareness Resource loader - Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 187 Appendix C. Meeting Services and PAC Support Deployment Issues This appendix covers several important issues concerning deploying Sametime-enabled applets built with the Sametime Meeting Services. These issues arise from the fact that the Meeting Services require the use of native code and other “out of the Java sandbox.” Most of this appendix is intended for use when deploying new applets that use the Application Sharing Service and the StreamedMedia Service. Most of the examples in this appendix are from the Meeting Room Sample applet, which should serve as a deployment reference for developers. Supplied Files The table below lists and describes the files that provide Meeting Services. File Name Description STMeetingRoomClient.cab This file contains all files needed to run a Java applet using the Meeting Services under Internet Explorer (IE). This file includes the classes from the community toolkit and the files needed for using Proxy Auto Configuration (PAC) files. STMeetingRoomClient651.jar This file contains all files needed to run a Java applet using the Meeting Services, including the classes from the Community Services. This JAR file does not include the files needed for PAC file support. STMeetingPACSupport.jar provides PAC file support. STJNILoader.cab This file contains all of the native files needed to run an applet using the Meeting Services under Internet Explorer. See the Installing the Native DLLs for Internet Explorer section below for installation and usage. STBroadcastClient.cab This file contains all of the Java files needed to run a broadcast receiver applet under Internet Explorer. Note that the community and meeting toolkit archives are not needed to write a broadcast receiver solution. This archive includes the files that provide PAC file support. STBroadcastClient.jar This file contains all of the Java files needed to run a broadcast receiver applet under Mozilla. Note that the community and meeting toolkit archives are not needed to write a broadcast receiver solution. Also, this file does not include the files needed for PAC file support. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 188 Appendix C. Meeting Services and PAC Support Deployment Issues File Name Description STBroadcastPACSupport.jar provides PAC file support. MeetRes.cab This file contains all native resource files needed to run a Java applet using the Meeting Services under Internet Explorer (IE). MeetRes.jar This file contains all resource files needed to run a Java applet using the Meeting Services. STMRCPACSupport.jar This file contains all of the Java files required to support PAC files. Note that PAC files are supported for both Internet Explorer and Mozilla. However, these files must not be installed for Mozilla, which is why they are in a separate jar file. STBCCPACSupport.jar This file contains all of the Java files required to support PAC files. Note that PAC files are supported for both Internet Explorer and Mozilla. However, these files must not be installed for Mozilla, which is why they are in a separate jar file. STMeetingRoomClientInstall.ja r This contains the Java files for installing the Meeting Room Client. STMeetingRoomClientInstallAI X.xpi This file contains OS-specific native code required for the Meeting Room Client. STMeetingRoomClientInstallLi nux.xpi This file contains OS-specific native code required for the Meeting Room Client. STMeetingRoomClientInstallSu nOS.xpi This file contains OS-specific native code required for the Meeting Room Client. STMeetingRoomClientInstallWi n32.xpi This file contains OS-specific native code required for the Meeting Room Client. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 189 Appendix C. Meeting Services and PAC Support Deployment Issues File Names and Version Numbers The following table lists the version-specific strings that are used in Sametime. They are taken from the stappletver.txt file typically found at http://<sametimeservername>/sametime/stappletver.txt. Key Name Description Value STDirectoryApplet_Version This key represents the version number of the Directory applet that runs in a Web browser. The Directory applet launches whenever the user schedules a meeting. 6,05,01,nn∗ STDirectoryApplet_Version_ Java2 This key represents the version number of the Directory applet that runs in a Web browser when using the Java plug-in. The Directory applet launches whenever the user schedules a meeting 6.05.01.nn STMRC_Version This key represents the version number of the MRC that runs in a Web browser. The MRC launches whenever the user attends an instant or scheduled meeting. 6,05,01,nn* STMRC_Version_Java2 This key represents the version number of the MRC that runs in a Web browser when using the Java plug-in. The MRC launches whenever the user attends an instant or scheduled meeting. 6.05.01.nn STBC_Version This key represents the version number of the Broadcast Client used by the Meeting Services under Internet Explorer. 6,05,01,nn* STBC_Version_Java2 This key represents the version number of the Broadcast Client that runs in a Web browser when using the Java plug-in. 6.05.01.nn ∗ The value of the key is shown as 6,05,01,nn; where 6 represents the release number (major), 05 represents the version number (minor), 01 represents the patch number, and nn represents the build number. The build number may vary depending on the build that you install. Please be sure to enter the correct build number when assigning a value. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 190 Appendix C. Meeting Services and PAC Support Deployment Issues Key Name Description Value STJNILoader_Version This key represents the version number of the Native File Controller used by the Meeting Services under Internet Explorer. 6,05,01,nn* STNMPlugin_Version This key represents the version number of the Native File Controller used by the Meeting Services under Mozilla. 6,05,01,nn* STMRCNameSpace This key represents the version number of the Resource Namespace for the MRC. Sametime MRC 651 STBCNameSpace This key represents the version number of the Namespace for the Broadcast Client. Sametime BC 651 STDirectoryAppletNameSpace This key represents the version number of the Namespace for the Directory Applet. Sametime DA 651 STMTKNameSpace This key represents the version number of the Namespace for the Sametime Meeting Toolkit. Sametime MT 651 STBCTKNameSpace This key represents the version number of the Namespace for the Sametime Broadcast Toolkit. Sametime BT 651 STMRCResourceNameSpace This key represents the version number of the Namespace for the MRC. STMRCRes651 STBCResourceNameSpace This key represents the version number of the Namespace for the Broadcast Client. STBCCRes651 STDirectoryAppletResourceN ameSpace This key represents the version number of the Namespace for the Directory Applet. STDirAppRes651 STVMVerifierResourceNameSp ace This key represents the version number of the Namespace for the VM Verifier Applet. STVMVRes651 STMRCRegistryPath This key represents the version number of the internal registry path name for the install of the MRC. /java/download/SametimeMRC65 1/ Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 191 Appendix C. Meeting Services and PAC Support Deployment Issues Key Name Description Value ST_Appshare_Dll This key represents the name of the application sharing dll. stas651.dll ST_AV_Dll This key represents the name of the audio/video dll. stsm651.dll ST_FONT_Dll This key represents the name of the font manager dll. Stfm651.dll STJNILoader_GUID This key represents the version number of the globally unique ID (GUID). 6CEDB6B5-4859-4e3a-BCA2FB8E565B8AD9 STNativeRegistryPath This key represents the Mozilla internal registry path name for the install of the native meeting dlls. /java/download/SametimeNative6 51/ Native Code Dependencies Parts of the Sametime Meeting Toolkit use the Java Native Interface (JNI) to communicate with native system libraries. Other native code is used to control the proper loading and unloading of the JNI libraries. This section describes the native libraries and how they should be handled. • stas651.dll, stsm651.dll, and stfm651.dll – These JNI libraries are used to gain access to the system’s native multimedia services. These DLLs are installed in the Windows System directory for use with Internet Explorer (IE) and Mozilla. • STJNILoader.ocx (IE only) and npstloader.dll (Mozilla only) – These controls are installed and used to control the proper loading and unloading of the JNI libraries. The controls must be used in conjunction with Sametime meeting applets. Not using these controls in certain scenarios can result in the browser crashing. Installing the Native DLLs for Internet Explorer The following example shows how to install and reference the native DLLs for Internet Explorer. Note that the nn in the version number must match the proper build number of the product. View the build version number of the various parts of the product by issuing the following URL, to access the Java properties file stappletver.txt: http://<your_Sametime_server_name>/sametime/stappletver.txt The following example code installs the Meeting Services native DLLs for IE: <BODY onload="loadNativeLibs()"> … <OBJECT CLASSID="clsid:STJNILoader_GUID" WIDTH=0 HEIGHT=0 name=loader Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 192 Appendix C. Meeting Services and PAC Support Deployment Issues CODEBASE="/sametime/YourApplet/STJNILoader.cab#Version= STJNILoader_Version"> </OBJECT> <SCRIPT LANGUAGE="JavaScript"> <!-- function loadNativeLibs() { document.all["loader"].loadLibrary[“ST_AV_dll"]; document.all["loader"].loadLibrary["ST_Appshare_dll"]; } // --> </SCRIPT> In the preceding code, replace the bold key names with their actual values, found in stappletver.txt. Upgrading Internet Explorer’s JVM for JNI Support Some releases of Internet Explorer 4.x ship with a Java Virtual Machine (VM) that does not support JNI. Microsoft® offers a free patch to solve this problem. Add the following HTML code to your applet’s HTML file to upgrade Internet Explorer’s VM to a version supporting JNI: <OBJECT CLASSID="clsid:08B0E5C0-4FCB-11CF-AAA5-00401C608500" WIDTH=0 HEIGHT=0 CODEBASE="/sametime/MSJavX86.exe#Version=5,0,3182,0"> </OBJECT> Installing the Native DLLs for Mozilla The following example shows how to use Mozilla’s XPInstall mechanism to install the native DLLs for Mozilla. Note that the nn in the version number should match the proper build number of the product. View the build version number of the various parts of the product by issuing the following URL, to access the Java properties file stappletver.txt: http://<your_Sametime_server_name>/sametime/stappletver.txt Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 193 Appendix C. Meeting Services and PAC Support Deployment Issues The following example code installs the Meeting Services native DLLs for Mozilla (see Mozilla documentation for more information on using the XPInstall mechanism): <script language="JavaScript"> function getOS() { var OS = navigator.platform.toLowerCase(); var STOSTest = new Array("win","aix","sun","inux"); // Look for this var STOSPackage = new Array("Win32","AIX","SunOS","Linux"); // Treat it as this var supportedOS = ""; for (var i=0;i<STOSTest.length;i++) { if (OS.indexOf(STOSTest[i]) != -1) { supportedOS = STOSPackage[i]; break; } } return supportedOS; } function xpinstallCallback(url, status) { if (status!=0) { // Something failed... handle it alert("Failure: " + status); } else { //alert("It's installed."); } } function installFiles() { var OS = getOS(); var rn = "/java/download/yourpath/"+OS; var file_name = "STMeetingRoomClientInstall" + OS + ".xpi"; // get the file location from the URL, // we need this to reference the Jar file var file_location = "/sametime/yourapplet/" + file_name; if (InstallTrigger.enabled()) { var xpi = { "Yourappletname": file_location }; InstallTrigger.install(xpi, xpinstallCallback); } else { alert("Could not install.\n Enable automatic software installation in your browser's advanced preferences and try again."); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 194 Appendix C. Meeting Services and PAC Support Deployment Issues </script> The following example code shows how to reference the native DLLs for Mozilla from your applet’s HTML file (for Windows only): <EMBED type="application/x-Sametime-Loader" pluginurl= "/sametime/STMeetingRoomClient/STMeetingRoomClientInstallWin32.xpi" hidden="TRUE" name="loader" NativeLibraryCount="2" NativeLibrary0="ST_AV_Dll" NativeLibrary1="ST_Appshare_Dll"> </EMBED> Installing Java Code for Internet Explorer (Microsoft Native VM) With Internet Explorer (IE), installing the Java code is not required in order to access native libraries. However, installation is recommended to avoid repeated downloads. Installing the code for IE does not require the browser to be restarted. Internet Explorer provides a way for installed classes to use a name space upon installation. The following approach is required in order to avoid name space collisions. 1. Build the archive using the free dubuild tool (from Microsoft). Example: dubuild YourApplet.cab ".\build_directory" /N "Your Namespace" /D "Your Friendly Name" /I *.class /I *.gif /I *.properties /V 1,0,0,0 2. Reference your specific name space from HTML and the applet tags, for example: <APPLET code=YourApplet width=200 height=200 MAYSCRIPT> <PARAM NAME=useslibrary VALUE="Your Applet"> <PARAM NAME=namespace VALUE="Your Namespace"> <PARAM NAME=useslibrarycodebase VALUE="YourApplet.cab"> <PARAM NAME=useslibraryversion VALUE="1,0,0,0"> ... </APPLET> Note that the MAYSCRIPT tag is required for IE only when PAC file support is required. See the following link for more information: http://www.microsoft.com/Java/sdk/40/pg/pg_pkgdist_dubld_3.htm Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 195 Appendix C. Meeting Services and PAC Support Deployment Issues Considerations when Obfuscating Classes The following class names found in STMeeting.jar affect bindings to native libraries and are controlled by Lotus. These classes should not be renamed or obfuscated: com.lotus.sametime.appshare.host.stn6511 com.lotus.sametime.appshare.host.stn6512 com.lotus.sametime.appshare.host.stn6513 com.lotus.sametime.streamedmedia.recorder.stn6514 com.lotus.sametime.streamedmedia.recorder.stn6515 com.lotus.sametime.streamedmedia.recorder.stn6516 com.lotus.sametime.streamedmedia.interactive.stn6517 com.lotus.sametime.streamedmedia.interactive.stn6518 com.lotus.sametime.gdk.font.stn6519 The following classes are passed as parameters into the native libraries. Their fields cannot be obfuscated or renamed. com.lotus.sametime.streamedmedia.VideoDeviceInfo com.lotus.sametime.streamedmedia.AudioDeviceInfo The following classes are used to provide support for PAC files. Their methods must remain unobfuscated. com.lotus.sametime.tunnelsocket.jvm_utils.ExplorerVMHandler com.lotus.sametime.tunnelsocket.jvm_utils.VMHandler com.lotus.sametime.tunnelsocket.jvm_utils.NetscapeVMHandler Signing Java Archives In order to support specific features of the Sametime Meeting Services, Java applets must be signed before running in the browser. This requirement is due to the Java Virtual Machine’s security restrictions on applets. Therefore, a developer’s application will require signing in order to achieve full functionality. Applet signing is implemented differently in IE and Mozilla. For more information on using signcode to sign a Java archive for Internet Explorer, see: http://www.microsoft.com/java/sdk/40/pg/tools_swd_signcode.htm For more information on using signtool to sign a Java archive for Mozilla, see: http://developer.netscape.com/software/signedobj/jarpack.html Proxy Auto Configuration (PAC) Support Issues When deploying Sametime applets with PAC support enabled, the HTML code for the Applet tag must include a NAME parameter and the MAYSCRIPT tag: <APPLET codebase="/samples/MySampleApplet/" code=MySampleApplet name=MySampleApplet MAYSCRIPT> Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 196 Appendix C. Meeting Services and PAC Support Deployment Issues Resource File Usage and Deployment The resource files for the Meeting Services include images and property files. All resource files (images and property) are located in the MeetRes.cab and MeetRes.jar files. The only images used by the Meeting Services are required by the Whiteboard Service. The property files are also provided in the ../properties directory (part of the toolkit install). The developer can access the property files by either of the following two methods: Provide a relative URL to the location of this directory Pass null to access the property files from the archives The toolkit provides a resource namespace parameter that allows the developer to solve a namespace collision problem for resources (property and image files). The following example demonstrates this: MeetingFactoryService meeting_factory = new MeetingFactoryComp( Session, this.getCodeBase(), // applet's codebase "MyNameSpace", // resource namespace this); // PAC file applet This will allow an applet located in ../sametime/MyApplet/ to place its resources on the server or in an archive in a subdirectory named ../sametime/MyApplet/MyNameSpace/properties/. Namespace parameters are optional. If they are not present, namespace will not be used for resources (property files and images). If these parameters are used, then all property files and images must reside in the specified namespace. Summary of Recommended Applet Deployment Steps For Microsoft Internet Explorer The following summarizes the recommended applet deployment steps for Internet Explorer: 1. Design the project with PAC files and resource name spaces in mind. 2. Build the project and collect all toolkit classes and resources needed to run the applet. 3. Build an archive using “dubuild.” Use the namespace option. Adding the meeting toolkit property files is also an option that is available. 4. Sign the archive using “signcode.” 5. Reference your applet from an HTML page that also installs and loads native code. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 197 Appendix C. Meeting Services and PAC Support Deployment Issues For Mozilla The following summarizes the recommended applet deployment steps for Mozilla: 1. Design the project with PAC files and resource name spaces in mind. 2. Build the project and collect all toolkit classes and resources needed to run applet. 3. Uniquely obfuscate class names (not required for IE). Do not obfuscate listed files (see the sections “Considerations when Obfuscating Classes” and “PAC Support Issues,” above). 4. Split out the PAC file classes into their own Archive. 5. Build signed archives using “signtool.” 6. Reference your applet from an HTML page with code that installs and loads native code. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 198 Appendix D. Proxy Auto Configuration (PAC) Support Obtaining a PACService Object The PACService interface contains methods to aid in the processing of PAC files and find proxy hosts for a given address. Both the Community Services and Meeting Services require an object that implements the PACService interface in order to support the PAC system. The two ways to obtain the required PACService object are as follows: 1. The developer’s applet can simply extend the supplied com.lotus.com.sametime.applet.STApplet class (which implements PACService), and the applet can be cast as a PACService object and used accordingly. 2. The developer can write an applet that implements the PACService interface. This is done by instantiating a PACServiceProvider object that implements the PACService interface and contains the required functionality. This approach is modeled after the STApplet class, and example code is provided below. (See the Sametime Java Toolkit Javadoc Reference for details on the STApplet class and PACService interface.) import import import import import import netscape.javascript.JSObject; java.applet.Applet; java.util.Vector; java.net.URL; com.lotus.sametime.util.pac.PACService; com.lotus.sametime.util.pac.PACServiceProvider; public class PACSupportApplet extends Applet implements PACService { private PACServiceProvider Pacfile_Processor = null; public void init() { try { super.init(); Pacfile_Processor = new PACServiceProvider( this ); } catch(Exception e) { e.printStackTrace(); } } public void destroy() { if( Pacfile_Processor != null ) Pacfile_Processor.cleanup(); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 199 Appendix D. Proxy Auto Configuration (PAC) Support } super.destroy(); public Vector findProxyForURL( URL host_url ) { Vector proxy_info = null; if( Pacfile_Processor != null ) proxy_info = Pacfile_Processor. findProxyForURL( host_url ); } return proxy_info; public Object getPacFileMethodProvider() { return( PACServiceProvider. getPacFileMethodProvider() ); } } Enabling PAC Support with the Community Services Enabling PAC support with the Community Services involves the following: 1. Using the PACService to determine any proxies to be used for the given host URL. 2. Creating the appropriate array of community Connection objects. 3. Setting the CommunityService connectivity with the array of community Connection objects. The following code (taken from the Meeting Room Sample applet) shows how this process works: // // Get the Proxy settings from the browser. // Vector proxies = null; URL url = new URL("http", host, direct_port, ""); proxies = getMeetingContainer().getPACService().findProxyForURL(url); // // Determine out the HTTP and SOCKS proxies settings. // if (proxies.size() > 0) { Enumeration iterator = proxies.elements(); while (iterator.hasMoreElements()) { ProxyInfo proxy = (ProxyInfo) iterator.nextElement(); if (proxy.getType() == ProxyInfo.HTTP) Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 200 Appendix D. Proxy Auto Configuration (PAC) Support { httpProxyHost = proxy.getHost(); httpProxyPort = proxy.getPort(); } else if (proxy.getType() == ProxyInfo.SOCKS) { socksProxyHost = proxy.getHost(); socksProxyPort = proxy.getPort(); } } } // // Direct connection. // connections_vector.addElement(new DirectSocketConnection( direct_port, direct_timeout)); // // Socks connection (if available). // if (socksProxyHost != null) { connections_vector.addElement(new Socks4Connection( direct_port, socksProxyHost, socksProxyPort, null, direct_timeout)); } // // Tunnel connection. // if (httpProxyHost != null) { connections_vector.addElement(new HttpConnection( tunnel_port, tunnel_timeout, httpProxyHost, httpProxyPort)); } Connection[] connections_array = new Connection[connections_vector.size()]; connections_vector.copyInto(connections_array); // // Set the connectivity information on the CommunityService. // community_service.setConnectivity(connections_array); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 201 Appendix D. Proxy Auto Configuration (PAC) Support Enabling PAC Support with the Meeting Services Enabling PAC support with the Meeting Services involves the following: 1. Enabling PAC support for the Community Service. The Meeting Services make use of the Community Service, so PAC support must be enabled for both. See the “Enabling PAC Support with the Community Service” section above for more information. 2. When constructing a MeetingFactoryComp and/or StreamedMediaBroadcast object, the PACService object must be passed in as a parameter. PAC Support Deployment Issues When including PAC support with your Sametime applet, deployment issues must also be addressed. See “Appendix C. Meeting Services and PAC Support Deployment Issues” for more information. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 202 Appendix E. Sametime Identifiers Sametime services use identifiers for many purposes. Among them: • Online users’ and servers’ attribute keys • Instant Message types, data message types and sub-types • Persistent user storage attribute keys • Post types It is important that Sametime-enabled applications do not conflict with each other by using the same identifier for different purposes. That can happen, for example, if two separate companies produce Sametime-enabled products that use the same identifier for two different purposes. That is why the following conventions have been established for all Sametime identifier types: • The range 0 – 100,000 is reserved for internal Sametime/Lotus/IBM use • Any third-party developers who want to allocate an identifier range for their Sametime enabled applications should email [email protected] This Appendix lists the identifiers that might be useful to developers using the Sametime Toolkits. The identifiers are already in use by Sametime applications such as Sametime Connect and Meeting Room Client. The identifiers are grouped by service. Please see the relevant chapter in this Developer’s Guide for more information on how these identifiers are used. Awareness Service Attribute Key ID Attribute Name User/ Server Attribute Type Value Format 1 Have I set my A/V Preferences? User Existential Identifies whether the attributes 0002-0004 have been set by the user. 2 Do I have a Mic? User Existential Identifies whether the user has a microphone. 3 Do I have Speakers? User Existential Identifies whether the user has speakers. 4 Do I have a Video Camera? User Existential Identifies whether the user has a video camera. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide Comments 203 Appendix E. Sametime Identifiers Attribute Key ID Attribute Name User/ Server Attribute Type Value Format Comments 6 Do I Support File Transfer User Existential Set by the toolkit UI or application level. Used to let other clients know whether a user supports file transfer, prior to sending a file. 9001 Are meeting services available? Server Existential Will not be set for customers that do not have meeting services (like IBM etc.). 9002 Is Audio enabled? Server Existential Requires the A/V Add-on to be installed and Audio enabled by the admin. 9003 Is Video Enabled? Server Existential Requires the A/V Add-on to be installed and Video enabled by the admin. 9004 Can we browse the directory? Server Existential Will not be set in LDAP environment in Watson. 9005 Automatic Nicknames delimiter Server String Usually “/” 9006 AppShare Can View Setting Server Byte 0 or 1 Identifies whether users connecting to this server can view appshare content. 9007 AppShare Can Host Setting Server Byte 0 or 1 Identifies whether users connecting to this server can host appshare content. 9008 AppShare Can Drive Setting Server Byte 0 or 1 Identifies whether users connecting to this server can drive shared applications 9009 Is File Transfer Enabled and max file size allowed? Server Integer (4 bytes) Set if the administrator allows File Transfer in the community. Value is the max allowed file size in K. 0 or a negative value means that the file size is Value Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 204 Appendix E. Sametime Identifiers Attribute Key ID Attribute Name User/ Server Attribute Type Value Format Comments unlimited. 9015 Is there a SIP Gateway in the community? Server Existential Set by the SIP Gateway to let the clients know that user can add, be aware of, and interact with external SIMPLE users. Instant Messaging Service IM Type 1 25 Used for Chat IM Used as post type for invitations in Post Service. Data Type Data Sub-Type 1 0 Empty Respond Start 1 Empty Respond Stop N/A N/A Data N/A Comments N/A Storage Service Attribute Key ID Value Types Comments 0 String 1 Boolean Indicates whether to blink the Sametime Connect icon when a person becomes active. 2 Boolean Indicates whether to play a sound when a person becomes active. 3 Boolean Indicates whether the IM window should blink on a new incoming message. 4 Boolean Indicates whether the IM window should come to front on a new incoming message. 5 Boolean Indicates whether to display a sound for a new incoming message. 6 String 7 Boolean The user’s contact list. Contains a list of users and groups as they appear in Sametime Connect. Default text for invite to chat. Indicates whether to show the away message for editing when the user Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 205 Appendix E. Sametime Identifiers Attribute Key ID Value Types Comments selects to change his status to away. If true, a dialog will be opened prior to setting the user status. 8 Boolean Indicates whether to show the DND message for editing when the user selects to change his status to DND. If true, a dialog will be opened prior to setting the user status. 10 Boolean Indicates whether the contact list in Sametime Connect is displayed in show all mode (true) or show online only mode (false). In show online only mode, users that are currently offline are not displayed in the view. 11 Boolean Indicates whether to show the active message for editing when the user selects to change his status to active. If true a dialog will be opened prior to setting the user status. 12 Boolean Indicates whether to display an informational dialog box after adding a new user/group to the contact list. 13 Boolean Indicates whether to ask the user before sending unsecured messages. 14 String 15 Boolean Indicates whether the contact list view in connect is displayed sorted in alphabetical order (true) or at its original order (false). 16 Boolean Indicates whether the names in the contact list are displayed fully (false) or truncated to short names (true) using a specified delimiter. 17 Boolean Indicates whether to start secure messages or not. 19 Boolean Indicates whether to show the “Invitation has been sent” dialog when invite other people to join to a meeting. 30 Boolean Indicates whether the search for users in the community is in exhaustive mode (true) on not (false). 31 Boolean Indicates whether to show a dialog when a user who is already in the contact list is added a second time. True for displaying the dialog, false for not showing the dialog. 70 String The sound file path to play when a person become active. 71 String The sound file path to play when an invitation or new message arrives. 80 String A list of the user’s away messages. The list contains the last five messages that were used by the user. The messages are separated using a semicolon. The first message in the list is the default message. Default text for invite to a meeting. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 206 Appendix E. Sametime Identifiers Attribute Key ID Value Types Comments 90 String A list of the user’s DND messages. The list contains the last five messages that were used by the user. The messages are separated using a semicolon. The first message in the list is the default message. 100 String A list of the user’s active messages. The list contains the last five messages that were used by the user. The messages are separated using a semicolon. The first message in the list is the default message. 110 Integer Indicates the number of minutes to wait before changing automatically, the user status from Active to Away. 111 Boolean Indicates whether to automatically change the user status from Active to Away when the user is not using the mouse or keyboard for a while. 112 Boolean Indicates whether to change the user status from Away to Active when the user uses the mouse or keyboard. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 207 Appendix E. Sametime Identifiers User In Place Attributes Attribute Key 8 Comments Used for start/stop responding Place Activity Types Attribute ID Name 37121 Whiteboard 37122 Appshare 37123 Audio 37124 Video 37125 Reserved 37126 Chat 37127 Web Collaboration 37128 Reserved 37129 URL Push 37130 Question and Answer 37131 Shared Objects 37132 Moderation (user roles) Post Service Post Type ID 25 Name Invitations for meeting and n-way chat Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 208 Appendix F. Representing External Users Overview An external user is a user from another community. Using the Java Toolkit, you can get these services involving an external user: • Awareness services – You can add an external user to your WatchList and get updates on his status. • Privacy services – You can add an external user to your privacy list. • Instant messaging service – You can send and receive an instant message. The STUser object is used for representing external users in the API. Certain functionality in the STUser definition handles external users: • boolean isExternalUser() This method indicates whether or not this is an external user. • void setExternalUser() This method is used to designate this user as an external user. When to use the isExternalUser() method If you are getting an ImReceived notification from the API and you want to know if the user who started the IM with you is from another community, you should run the following code: /** * Adds a new External User to the buddyList * @param String externalId */ void addExternalUser(String externalId) { STId stId = new STId(externalId,""); STUser user = new STUser(stId,externalId,""); user.setExternalUser(); m_whatList.addItem(user); } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 209 Appendix F. Representing External Users When to use the setExternalUser() method Whenever you create an STUser object for passing in the API and you need to indicate that this user is an External user, you should use the method. For example, if you would like to add an external user to your watch list, you need to call the method WatchList.addItem(STObject stObject). The object should be an STUser. You need to create the STUser with the user ID and name that you have. (Remember that there is no resolving service for an external user; so you should know an external user's ID in advance.) Then you should call the method STUser.setExternalUser(). This tells the Awareness Service that it is an external user, and you will get his status. If you do not call this method, the Awareness Service will think that it is a Sametime internal user, and his status will always be offline. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 210 Appendix G. Sametime Connectivity Overview In general, the two ways to connect to the Sametime server are: • Sametime Protocol connection – The client connects by opening a TCP/IP socket to the server. Different kinds of proxies (socks4, socks5, and https) are supported using this method. • HTTP Tunneling connection – The client opens what seems like an ordinary HTTP connection, but “tunnels” the Sametime protocol inside the HTTP protocol. This type of connection enables connecting through firewalls that only allow HTTP connections. HTTP tunneling connectivity must address limits imposed by the browser on the number of connections that a Java applet can open using URLConnection. When using its native JVM, Internet Explorer limits the number to two connections per Internet Explorer process. In many situations, Sametime connectivity demands will quickly exceed these browser-imposed limits. The Sun Java Plugin does not limit the number of connections. To address the Internet Explorer connection limitation, Sametime uses a tunneling mechanism called hybrid polling, which requires only a single HTTP connection. Hybrid polling is provided by the HybridPollingConnection class. Note Sametime also supports a last-resort tunneling mechanism called full polling, in which HTTP connections are opened and closed intermittently. It is also available as a solution for unsigned applets that cannot use the Hybrid Polling Connection's 'use WinInet' option, because the framework requires access to local machine resources (specifically to a native DLL). However, full polling creates a heavy load on the server and degrades the user’s experience. The HybridPollingConnection class As its name implies, the HybridPollingConnection class implements the hybrid polling strategy described above. The Hybrid PollingConnection class can be used in two modes – it can either use the standard Java URLConnection class to perform the connection, or use a DLL to connect through Window's WinInet library. The second option is only available on Windows platform; to use it, you must install the file sturlcon10.dll. Code running on Internet Explorer with a native JVM must use this option, to bypass the two-connection limit of the browser. Using the WinInet option may sometimes be advisable even when using the Java Plugin, because it makes the HybridPollingConnection's behavior a bit more like that of Internet Explorer. (For example, it makes the connection use the browser's certificate store instead of the Plugin's store for authentication.) The other mode, the URLConnection mode, also has its advantages: It is pure Java, it does not require DLL installation, and it can be used by unsigned applets, since it does not require access to native code. It is up to the developer to decide which connection mode to use. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 211 Appendix G. Sametime Connectivity Note also that code that uses WinInet on Windows will still run on non-Windows platforms (though it will use the Java URLConnection class instead). Deciding to use the WinInet option on Windows does not mean restricting your code to that platform. The connectivity agent framework To address Internet Explorer connectivity limitations, Sametime 3.x introduced a connectivity agent framework that multiplexed multiple Sametime connections over a single HTTP connection. The connectivity features in the current version of Sametime make this solution unnecessary; however, it is still included in the toolkit, and you may still encounter application code that uses the framework. This section is provided for your reference in such cases. It describes the framework and its usage. This framework comprises three major elements: • Agent executable – This client-side executable is responsible for opening HTTP connections to the Sametime server and multiplexing different client messages (community and/or meeting) and responses. Note that these messages could also be coming from multiple clients. The HTTP connections are implemented using wininet.dll. • Agent native DLL – This client-side DLL is used by signed applets (and specifically by Java Connect and the MRC) to access the agent executable and thereby send information to the Sametime server and receive information from it. The C++ Toolkit (including C++ Connect) does not need this DLL because it links statically with code that behaves similarly to the DLL. • Polling server application – This server-side component supports the incoming connection requests and messages from the connectivity agent executable. This server application forwards the incoming messages to either the community server or the meeting server. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 212 Appendix G. Sametime Connectivity The diagram below shows the framework in the context of client machine and Sametime server. Client 1 Client 2 Client Machine Agent Framewor k Client 3 MUX Community Server Sametime Server Polling Meeting Server Server Application Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 213 Appendix G. Sametime Connectivity The next diagram below is an example scenario using the connectivity agent framework. Here, two browser instances are running on the client machine, each with its own process running a Java Virtual Machine (VM). • The first browser has two Sametime clients: client A and client B. • The second browser has only one Sametime client, namely client C. Each of the three clients launches the agent framework by using the AgentConnection class. This class loads the agent DLL (a Java native DLL) in order to send and receive Sametime messages using the agent framework. Since only one such agent DLL is needed per VM, the AgentConnection class loads only one such DLL, Agent DLL X, for the two clients A and B. namely Agent DLL X. For client C, the AgentConnection class loads one agent DLL, Agent DLL Y. The connectivity agent framework creates one agent executable for each Sametime server that the clients try to connect to. The agent executable is the module that actually implements the hybrid polling mechanism to the Sametime server. In this example, the following is assumed: • Client A wants to connect to Sametime server S. • Clients B and C want to connect to Sametime server T. Two agent executables are needed: one for server S and one for server T. The agent executables are Agent Exe ES and Agent Exe ET. Therefore: • Agent DLL X, attempting to connect both client A to server S and client B to server T, needs to find or load both Agent Exe ES and Agent Exe ET, as shown by the arrows in the diagram. • Agent DLL Y, attempting to connect client C to server T, needs to communicate only with Agent Exe ET, as the diagram shows. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 214 Appendix G. Sametime Connectivity In the diagram, only browser clients are shown. But the same model is true both for Java applications and Windows applications (such as Sametime Connect) that use the connectivity agent framework. In the case of C++ applications using the connectivity agent framework, the agent DLL is not required. VM 1 Client A Client B Agent DLL X Agent Exe ES ST Server S Agent Exe ET ST Server T VM 2 Client C Agent DLL Y Client Machine When to use the connectivity agent framework You should use the connectivity agent framework whenever you want to connect to a Sametime 3.0 or later server using HTTP tunneling. This can be because of user settings or firewall issues that your application will need to deal with in its production environment. The connectivity agent framework is exposed in the Java Toolkit by the AgentConnection class. In general, you can use this class to create three different kinds of HTTP tunneling connections: • Direct HTTP tunneling • HTTP tunneling through an HTTP proxy • HTTP tunneling using the HTTP setting of Microsoft Internet Explorer Please see the Javadoc of the AgentConnection class in the com.lotus.sametime.core.util.connection package for more details. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 215 Appendix G. Sametime Connectivity Deployment in your application to use the connectivity agent framework You have three deployment issues to consider, depending on the type of application and browser you are using: • A Java application • A Java applet to be run in Internet Explorer • A Java applet to be run in Mozilla The following describes what needs to be done to deploy the connectivity agent framework executable and the DLL in each of the above application/applet types. Deploying the connectivity agent framework for a Java application In order to use the connectivity agent framework in a Java application, you must install the framework EXE and DLL as part of your application and register the EXE. You can find both files in the binaries download package available from the Java Toolkit home page. The files are called STConnAgentXXX.dll and STConnAgentXXX.exe, where XXX is the release number of the toolkit (for example, STConnAgent651.dll). Installation You can install the EXE file in any directory. We recommend that you install it in the application directory, since each application should have its own copy. The DLL must be installed in the system path, so that it can be loaded from inside the AgentConnection class code. Registration When an application needs the connectivity abilities of the EXE, it searches the registry for its location. Since each application has its own copy of the file, the application needs to register its copy during installation. To do this, launch the EXE with the parameter @REGISTER_SERVER, followed by your application name. Your application name should be unique; we recommend using the form ‘com.company.appname.version’. For example: StConnAgent651.exe @REGISTER_SERVER com.ibm.sametime.connect.651 Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 216 Appendix G. Sametime Connectivity Deploying the connectivity agent framework for an Internet Explorer Java applet To use the connectivity agent framework in a Java applet run inside Internet Explorer, add the following HTML code to your HTML file: <OBJECT WIDTH=0 HEIGHT=0 CLASSID="clsid:08B0E5C0-4FCB-11CF-AAA5-00401C608500" CODEBASE="/sametime/MSJavX86.exe#Version=5,0,3182,0"> </OBJECT> <OBJECT ID="StConnAgent651" WIDTH=0 HEIGHT=0 CLASSID="clsid:0D359092-CD24-483C-9FA0-4C71BF388905" CODEBASE="/sametime/javaconnect/InstallSTConnAgent.cab#Version=3,1 ,12,1"> </OBJECT> The first object tag ensures that you have an updated Java Virtual Machine that supports use of Java Native DLLs. The second object tag downloads and installs the connectivity agent framework files on the fly, so that your applet can use them. Deploying the connectivity agent framework for a Mozilla Java applet To use the connectivity agent framework in a Java applet run inside Netscape Navigator, add the following JavaScript code to your HTML file: <script language="JavaScript"> function installFiles() { var version_information = new netscape.softupdate.VersionInfo(1,0,0,1); var rn = "sametime/javaconnect/" var file_name = "InstallSTConnAgent.jar"; var trigger = netscape.softupdate.Trigger; // get the file location from the URL, // we need this to reference the Jar file var host_name = location.host; // the following path describes the location of jar contains the dll file var file_location = location.protocol+"//" + host_name + "/sametime/javaconnect/" + file_name; if (trigger.UpdateEnabled()) { trigger.ConditionalSoftwareUpdate(file_location, rn, version_information, trigger.DEFAULT_MODE); } else { alert("SmartUpdate is not enabled"); } } Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 217 Appendix G. Sametime Connectivity </script> <BODY onload="installFiles()" > </body> Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 218 Appendix H. Core Types Overview This section describes the core types used in the Java Toolkit. Each core type represents a Sametime entity that is used and shared by several or all of the Sametime services provided in the toolkit. You might never work directly with the Sametime core types. However, if you debug your programs and inspect your Sametime objects, you will encounter core type objects. Sametime ID Types The Sametime identification classes are mainly for internal use; they are not exposed at the API level. The Sametime API uses more high-level entity definitions that encapsulate the Sametime ID. STId STId represents a Sametime entity identification. Every Sametime entity has a unique persistent ID within the Sametime community. The format and content of the ID can vary between communities. It is dependent on the company’s directory that is integrated with Sametime (Domino or LDAP). STLoginId STLoginId represents a Sametime entity’s runtime session identification. While every Sametime entity has its STId, some entities will also have session IDs assigned to them during runtime. For example, a user has his own fixed ID, such as John Smith/IBM. When the user logs in to Sametime, an STLoginId will be assigned to him. (Multiple concurrent logins will result in different login IDs.) This information can be used to access a specific login of the user. It is valid only for the duration of the login. Please see the Sametime Java Toolkit Tutorial or the Sametime C++ Toolkit Tutorial for more information on the Sametime user model. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 219 Appendix H . Core Types Sametime Object Types STUser STUser represents a Sametime user in the community. Since Sametime provides user-to-user interaction, this structure is the most commonly used one. In order to interact with other users in the community, the application needs to obtain a valid STUser object in one of two ways: • Start with a user name and resolve it to the matching STUser object, using the Lookup Service to find the object. • Create an STUser object from scratch. This option is advanced and requires knowledge of the specific ID allocated for the user. This information can vary between different Sametime installation environments, and therefore should only be used by advanced developers who have intimate knowledge of the directory used by Sametime. Once the STUser object is available, the application can perform user-to-user interactions such as watching the user’s online status and sending instant messages to the user. STServer STServer represents a Sametime server. Once a user logs in to the community, he is connected to a specific Sametime server. Using the Java toolkit, you can get the STServer object once you are logged in to the server. To do this, call the Login.GetServer() function. STUserInstance STUserInstance represents a single login of a Sametime user. Once logged on to Sametime, a user is assigned an STLoginId that is valid for the duration of the login. The STLoginId is contained by the STUserInstance object. An application can choose to use this information to contact a specific login of the user, instead of relying on the server to choose the appropriate login. However, we recommend that the developer not use STLoginId or rely on it, because it is transient. By contrast, the STUser object holds persistent information. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 220 Appendix I. Multiple Language Support By default, Sametime Java Toolkit UI components use the system-specified encoding to display standard text. This can mean that a Java Toolkit application displays its text in a different language from that used for UI text. For example, a custom window title might appear in German, while standard field labels and help text appear in English. To make the UI components use the same language encoding as the program, modify the program as follows: 1. Add the following import statement: import com.lotus.sametime.resourceloader.*; 2. Get a reference to the resource loader service: ResourceLoaderService resourceSvc = (ResourceLoaderService) m_session.getCompApi(ResourceLoaderService.COMP_NAME); 3. Set the locale used by the resource loader. For example: resourceSvc.setLocale(Locale.GERMANY); Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 221 Appendix J . Signing Applets Appendix J. Signing Applets When you use the Sametime Java toolkit to create an applet, you must sign the applet in certain circumstances. As with any applet, a Sametime applet must be signed to allow out of sandbox operations like clipboard operations, connections to servers other than the one from which the applet is downloaded, access to local file systems, and so on. However, you must also sign the applet in the following Sametime-specific situations: • If your applet provides support for file transfer operations. For more information about adding file transfer support, see the descriptions of the FileTransfer UI component in Chapter 3 and the FileTransfer Service in Chapter 4. You may also want to read about the AwarenessList AWT component in Chapter 2. The AwarenessList component lets users initiate file transfers to online names. • If you use the connectivity agent framework. For more information about the framework and when to use it, see Appendix G. Instant Messaging and Web Conferencing Java Toolkit Developer’s Guide 222