0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.lib.collab.xmpp;
0043:
0044: import java.util.*;
0045: import java.io.*;
0046: import java.net.*;
0047:
0048: import java.nio.channels.*;
0049: import javax.security.auth.callback.Callback;
0050: import javax.security.auth.callback.CallbackHandler;
0051: import javax.security.auth.callback.NameCallback;
0052: import javax.security.auth.callback.PasswordCallback;
0053: import javax.security.auth.callback.UnsupportedCallbackException;
0054: import org.jabberstudio.jso.sasl.SASLClientInfo;
0055: import org.jabberstudio.jso.sasl.SASLFeatureConsumer;
0056: import org.jabberstudio.jso.sasl.SASLMechanism;
0057: import org.jabberstudio.jso.sasl.SASLMechanismManager;
0058: import org.jabberstudio.jso.sasl.SASLMechanismsFeature;
0059: import org.jabberstudio.jso.tls.StartTLSFeature;
0060: import org.jabberstudio.jso.tls.StartTLSSocketFeatureConsumer;
0061: import org.jabberstudio.jso.tls.StartTLSSocketStreamSource;
0062: import org.jabberstudio.jso.util.XPathListener;
0063: import org.jabberstudio.jso.x.core.BindQuery;
0064: import org.netbeans.lib.collab.MediaService;
0065: import org.saxpath.SAXPathException;
0066: import org.jabberstudio.jso.xpath.XPathSupport;
0067: import org.jabberstudio.jso.tls.StartTLSPacket;
0068:
0069: import org.netbeans.lib.collab.*;
0070: import org.netbeans.lib.collab.util.*;
0071: import org.netbeans.lib.collab.xmpp.jingle.*;
0072:
0073: import org.jabberstudio.jso.*;
0074: import org.jabberstudio.jso.event.*;
0075: import org.jabberstudio.jso.io.*;
0076: import org.jabberstudio.jso.io.src.ChannelStreamSource;
0077: import org.jabberstudio.jso.x.core.*;
0078: import org.jabberstudio.jso.x.core.AuthQuery.Method;
0079: import org.jabberstudio.jso.x.si.SIQuery;
0080: import org.jabberstudio.jso.x.sift.FileTransferProfile;
0081: import org.jabberstudio.jso.x.disco.*;
0082: import org.jabberstudio.jso.x.xdata.*;
0083: import org.jabberstudio.jso.util.*;
0084: import org.jabberstudio.jso.util.ByteCodec;
0085: import org.jabberstudio.jso.x.info.OutOfBandExtension;
0086:
0087: import org.netbeans.lib.collab.xmpp.jso.iface.x.muc.*;
0088: import org.netbeans.lib.collab.xmpp.jso.iface.x.pubsub.*;
0089: import org.netbeans.lib.collab.xmpp.jso.iface.x.event.*;
0090: import org.netbeans.lib.collab.xmpp.jso.iface.x.amp.*;
0091:
0092: import org.apache.log4j.*;
0093:
0094: /**
0095: *
0096: * @author Vijayakumar Palaniappan
0097: * @author Rahul Shah
0098: * @author Jacques Belissent
0099: * @author Mridul Muralidharan
0100: */
0101: public class XMPPSession implements CollaborationSession {
0102:
0103: /**
0104: * Creates a new instance of XMPPSession
0105: *
0106: * 1. open XML Ouptut stream to server and write:
0107: * <pre>
0108: * C: <?xml version='1.0'?>
0109: * <stream:stream
0110: * to='server'
0111: * xmlns='jabber:client'
0112: * xmlns:stream='http://etherx.jabber.org/streams'
0113: * version='1.0'>
0114: * </pre>
0115: * 2. read response from server
0116: * <pre>
0117: * S: <?xml version='1.0'?>
0118: * <stream:stream
0119: * from='shakespeare.lit'
0120: * id='id_123456789'
0121: * xmlns='jabber:client'
0122: * xmlns:stream='http://etherx.jabber.org/streams'
0123: * version='1.0'>
0124: * </pre>
0125: *
0126: * 3. server sends features (starttls + SASL mechanisms)
0127: * <pre>
0128: * <stream:features>
0129: * <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
0130: * <required/>
0131: * </starttls>
0132: * <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
0133: * <mechanism>DIGEST-MD5</mechanism>
0134: * <mechanism>PLAIN</mechanism>
0135: * </mechanisms>
0136: * </stream:features>
0137: * </pre>
0138: * 4. start tls if requested by either client or server
0139: * 5. authenticate
0140: *
0141: */
0142: static Logger xmpplogger = LogManager
0143: .getLogger("org.netbeans.lib.collab.xmpp.traffic");
0144:
0145: public long getShortRequestTimeout() {
0146: return shortRequestTimeout;
0147: }
0148:
0149: protected void setShortRequestTimeout(long timeout) {
0150: this .shortRequestTimeout = timeout;
0151: }
0152:
0153: class DebugPacketListenerClass implements
0154: org.jabberstudio.jso.event.PacketListener {
0155:
0156: public void packetTransferred(PacketEvent evt) {
0157: try {
0158: org.jabberstudio.jso.Packet packet = evt.getData();
0159: if (packet instanceof org.jabberstudio.jso.Message) {
0160: Extension ext = null;
0161: if ((ext = packet.getExtension(IBB_NAMESPACE)) != null) {
0162: Packet temp = (Packet) packet.copy();
0163: temp.getExtension(IBB_NAMESPACE).clearText();
0164: packet = temp;
0165: }
0166: }
0167:
0168: if (evt.getType() == PacketEvent.RECEIVED) {
0169: xmpplogger.debug("[" + getCurrentUserJID() + "]"
0170: + " Received a packet: "
0171: + packet.toString());
0172: } else if (evt.getType() == PacketEvent.SENT) {
0173: if (!((packet instanceof InfoQuery)
0174: && packet.getType().equals(InfoQuery.SET) && ((packet
0175: .getExtension(AuthQuery.NAMESPACE) != null) || (packet
0176: .getExtension(RegisterQuery.NAMESPACE) != null)))) {
0177: xmpplogger.debug("[" + getCurrentUserJID()
0178: + "]" + " Sent a packet: "
0179: + packet.toString());
0180: }
0181: } else {
0182: xmpplogger.debug("packet: " + packet.toString());
0183: }
0184: } catch (Exception e) {
0185: XMPPSessionProvider.error(e.toString(), e);
0186: }
0187: }
0188: }
0189:
0190: class ServerRedirectionListenerClass implements
0191: org.jabberstudio.jso.event.PacketListener {
0192:
0193: public void packetTransferred(PacketEvent evt) {
0194: final org.jabberstudio.jso.Packet packet = evt.getData();
0195:
0196: if ((packet instanceof StreamError) && (!_logout)) {
0197: if (StreamError.SEE_OTHER_HOST_CONDITION
0198: .equals(((StreamError) packet)
0199: .getDefinedCondition())) {
0200: _see_other_host = (StreamError) packet;
0201: XMPPSessionProvider
0202: .debug("Connection Redirect received");
0203: }
0204: // When we get a stream error from the server , notify only if not in legacy mode.
0205: else if (!isAuthLegacyModeEnabled()) {
0206:
0207: notifyStreamError((StreamError) packet);
0208: }
0209: }
0210: }
0211: }
0212:
0213: class PacketListenerClass implements
0214: org.jabberstudio.jso.event.PacketListener {
0215:
0216: public void packetTransferred(PacketEvent evt) {
0217: final org.jabberstudio.jso.Packet packet = evt.getData();
0218:
0219: // if sendAndWatch was used then let this packet be
0220: // handled by other listener registered by sendAndWatch.
0221: if (removeSendAndWatchID(packet))
0222: return;
0223:
0224: if (packet instanceof org.jabberstudio.jso.Message) {
0225: //(new Thread(new Runnable() {
0226: // public void run() {
0227: // processMessage(packet);
0228: // }
0229: //})).start();
0230: processMessage(packet);
0231:
0232: } else if (packet instanceof PrivacyQuery) {
0233: //_presenceService.processPrivacyQuery((PrivacyQuery)packet);
0234: } else if (packet instanceof InfoQuery) {
0235: //(new Thread(new Runnable() {
0236: // public void run() {
0237: // processInfoQuery(packet);
0238: // }
0239: //})).start();
0240: processInfoQuery(packet);
0241: } else if (packet instanceof org.jabberstudio.jso.Presence) {
0242: try {
0243: processPresence((org.jabberstudio.jso.Presence) packet);
0244: } catch (CollaborationException e) {
0245: XMPPSessionProvider.error(e.toString(), e);
0246: } catch (Exception e) {
0247: XMPPSessionProvider.error(e.toString(), e);
0248: }
0249: } else if ((packet instanceof StreamError) && (!_logout)) {
0250: if (StreamError.SEE_OTHER_HOST_CONDITION
0251: .equals(((StreamError) packet)
0252: .getDefinedCondition())) {
0253: _see_other_host = (StreamError) packet;
0254: XMPPSessionProvider
0255: .debug("Connection Redirect received");
0256: } else {
0257: notifyStreamError((StreamError) packet);
0258: }
0259: } else {
0260: XMPPSessionProvider
0261: .debug("UnSupported XMPP XML Stanza : "
0262: + packet.toString());
0263: // throw new CollaborationException("UnSupported XMPP XML Stanza: " + packet.toString());
0264: }
0265: }
0266: }
0267:
0268: class StatusListenerClass implements
0269: org.jabberstudio.jso.event.StreamStatusListener {
0270: public void statusChanged(StreamStatusEvent evt) {
0271: if (evt.getContext().isInbound()) {
0272: if (evt.getNextStatus() == Stream.DISCONNECTED) {
0273: xmpplogger.info("disconnected");
0274: if ((!_logout) && (!evt.isExceptional())) {
0275: notifyStreamError(null);
0276: }
0277: }
0278: if (evt.getNextStatus() == Stream.CLOSED) {
0279: xmpplogger.info("closed");
0280: }
0281: if (evt.getNextStatus() == Stream.CONNECTED) {
0282: xmpplogger.info("connected");
0283: }
0284: if (evt.getNextStatus() == Stream.OPENED) {
0285: xmpplogger.info("opened ");
0286: }
0287: }
0288: }
0289: }
0290:
0291: /*
0292: * The packetListner thread locks the stream, so the operations which could take
0293: * more time should be launched in a separate thread
0294: * Launch the registration notification in a separate thread
0295: *
0296: */
0297: class RegisterNotifier implements Runnable {
0298:
0299: private InfoQuery _iqPacket;
0300:
0301: public RegisterNotifier(InfoQuery iq) {
0302: _iqPacket = iq;
0303: }
0304:
0305: public void run() {
0306: try {
0307: processRegisterQuery(_iqPacket);
0308: } catch (CollaborationException ce) {
0309: ce.printStackTrace();
0310: }
0311: }
0312:
0313: }
0314:
0315: class ServiceDiscovery implements MonitorListener {
0316: DiscoItem item;
0317: XMPPSession session;
0318:
0319: public ServiceDiscovery(XMPPSession s, DiscoItem di) {
0320: item = di;
0321: session = s;
0322: }
0323:
0324: public void monitorFailed(MonitorEvent evt) {
0325: }
0326:
0327: public void monitorFound(MonitorEvent evt) {
0328: try {
0329: Packet packet = evt.getActualPacket();
0330: if (packet.getType() == Packet.ERROR) {
0331: return;
0332: }
0333: DiscoInfoQuery diq = (DiscoInfoQuery) packet
0334: .listExtensions(DiscoInfoQuery.NAMESPACE)
0335: .get(0);
0336: for (Iterator iter = diq.listIdentities().iterator(); iter
0337: .hasNext();) {
0338: DiscoIdentity discoIdentity = (DiscoIdentity) iter
0339: .next();
0340: String category = discoIdentity.getCategory();
0341: String type = discoIdentity.getType();
0342: if (PersonalStoreEntry.GATEWAY.equals(category)) {
0343: if ("voip".equals(type)) {
0344: // if the server has a voip gateway, we need to hold on to its JID
0345: // This is needed by the client, so that it can redirect request to
0346: // this gateway
0347: _voipComponent = item.getJID();
0348: } else {
0349: PersonalGateway pse = new XMPPPersonalGateway(
0350: session, discoIdentity.getName(),
0351: item.getJID().toString(),
0352: discoIdentity.getType());
0353: try {
0354: for (Iterator i = diq.getFeatures()
0355: .iterator(); i.hasNext();) {
0356: ((XMPPPersonalGateway) pse)
0357: .addSupportedFeature((String) i
0358: .next());
0359: }
0360: synchronized (_jabberServiceLock) {
0361: _gateways.put(item.getJID()
0362: .toString(), pse);
0363: }
0364: } catch (CollaborationException e) {
0365: XMPPSessionProvider.error(e.toString(),
0366: e);
0367: continue;
0368: }
0369: }
0370: } else if (PersonalStoreEntry.CONFERENCE
0371: .equals(category)) {
0372: synchronized (_jabberServiceLock) {
0373: _mucService = item.getJID();
0374: }
0375:
0376: if (_conferenceService != null) {
0377: synchronized (_conferenceService) {
0378: _conferenceService
0379: .updateExtendedSearchSupport(
0380: item.getJID(), diq);
0381: _conferenceService.notifyAll();
0382: }
0383: }
0384: } else if ("pubsub".equals(category)) {
0385: synchronized (_jabberServiceLock) {
0386: _pubsubService = item.getJID();
0387: }
0388: if (_newsService != null) {
0389: synchronized (_newsService) {
0390: _newsService.notifyAll();
0391: }
0392: }
0393: } else if ("directory".equals(category)) {
0394: synchronized (_jabberServiceLock) {
0395: _judService = item.getJID();
0396: }
0397: if (_personalStoreService != null) {
0398: synchronized (_personalStoreService) {
0399: _personalStoreService.notifyAll();
0400: }
0401: }
0402: } else if ("server".equals(category)
0403: || "service".equals(category)) {
0404: // remote jabber server. Find out more in the background
0405: // in the background because the remote server may be
0406: // unreachable. Choosing not to hold response waiting
0407: // for another server.
0408: if (!_remoteServices.contains(item.getJID())) {
0409: new Thread(new DiscoRunnable(item.getJID()))
0410: .start();
0411: }
0412: } else {
0413: XMPPSessionProvider.debug("Category "
0414: + category + " is not known");
0415: }
0416: _discoveredServices.add(item.getJID());
0417: }
0418: } catch (Exception e) {
0419: e.printStackTrace();
0420: }
0421: }
0422:
0423: public void monitorTimeout(MonitorEvent evt) {
0424: }
0425:
0426: }
0427:
0428: private List _sessionListeners = Collections
0429: .synchronizedList(new ArrayList());
0430: private Map _regisListeners = new HashMap();
0431: Stream _connection;
0432: private boolean channelRegistered = false;
0433:
0434: XMPPPrincipal _client;
0435:
0436: JID _server;
0437: private String _sessionID, _loginName;
0438: protected boolean uidHasDomain = false;
0439:
0440: private TreeMap _namespaces = new java.util.TreeMap();
0441:
0442: private XMPPSessionProvider _provider;
0443: private XMPPPersonalStoreService _personalStoreService;
0444: private XMPPPresenceService _presenceService;
0445: private XMPPNewsService _newsService;
0446: private XMPPConferenceService _conferenceService;
0447: private XMPPNotificationService _notificationService;
0448: private XMPPStreamingService _streamingService;
0449:
0450: private StreamSource _css;
0451: private Object _selectionKey;
0452:
0453: private Set _remoteServices = Collections
0454: .synchronizedSet(new HashSet());
0455:
0456: String keyValue;
0457: boolean ampSupported = false;
0458: boolean ampCondDeliverSupported = false;
0459: boolean ampCondExpireAtSupported = false;
0460: boolean ampCondMatchResourceSupported = false;
0461: boolean ampActionDropSupported = false;
0462: boolean ampActionErrorSupported = false;
0463: boolean ampActionNotifySupported = false;
0464: boolean ampActionAlertSupported = false;
0465:
0466: private static final long DEFAULT_REQUEST_TIMEOUT = 50000;
0467: private static final long DEFAULT_SHORT_REQUEST_TIMEOUT = 5000;
0468: private static final long DEFAULT_FEATURE_TIMEOUT = 1500;
0469:
0470: private long requestTimeout = getLongProperty(
0471: "org.netbeans.lib.collab.xmpp.XMPPSession.REQUEST_TIMEOUT",
0472: DEFAULT_REQUEST_TIMEOUT);
0473: private long shortRequestTimeout = getLongProperty(
0474: "org.netbeans.lib.collab.xmpp.XMPPSession.SHORT_REQUEST_TIMEOUT",
0475: DEFAULT_SHORT_REQUEST_TIMEOUT);
0476: private long featureTimeout = getLongProperty(
0477: "org.netbeans.lib.collab.xmpp.XMPPSession.FEATURE_TIMEOUT",
0478: DEFAULT_FEATURE_TIMEOUT);
0479:
0480: public static int IBB_MESSAGE_SIZE = 4096;
0481: //public static int NUM_WORKER_THREAD = 2;
0482:
0483: private volatile boolean _logout = false;
0484:
0485: static JSOImplementation _jso = JSOImplementation.getInstance();
0486: static StreamDataFactory _sdf = _jso.getDataFactory();
0487:
0488: // implied namespace
0489: public static final NSI IQ_NAME = new NSI("iq", null);
0490: public static final NSI MESSAGE_NAME = new NSI("message", null);
0491: public static final NSI PRESENCE_NAME = new NSI("presence", null);
0492: public static final NSI STORAGE_NAME = new NSI("storage", null);
0493: public static final NSI STORAGE_BOOKMARK_NAME = new NSI("storage",
0494: "storage:bookmarks");
0495: public static final String PRIVATE_NAMESPACE = "jabber:iq:private";
0496: public static final String IBB_NAMESPACE = "http://jabber.org/protocol/ibb";
0497: public static final NSI IBB_OPEN = _sdf.createNSI("open",
0498: IBB_NAMESPACE);
0499: public static final NSI IBB_CLOSE = _sdf.createNSI("close",
0500: IBB_NAMESPACE);
0501: public static final NSI IBB_DATA = _sdf.createNSI("data",
0502: IBB_NAMESPACE);
0503: public static final XMPPMessagePart.Base64Cod BASE64 = new XMPPMessagePart.Base64Cod();
0504: // new ByteCodec.Base64Codec();
0505:
0506: public static final String SUN_PRIVATE_NAMESPACE = "sun:xmpp:properties";
0507: public static final NSI SUN_PRIVATE_NAME = new NSI("x",
0508: SUN_PRIVATE_NAMESPACE);
0509: public static final NSI SUN_PRIVATE_SUNMSGR_NAME = new NSI(
0510: "sunmsgr", SUN_PRIVATE_NAMESPACE);
0511: public static final NSI SUN_PRIVATE_POLICY_NAME = new NSI(
0512: "sunmsgrpolicy", SUN_PRIVATE_NAMESPACE);
0513: public static final NSI SEARCH_QUERY_NAME = new NSI("query",
0514: "jabber:iq:search");
0515: public static final NSI SUN_ATTACH_NAME = new NSI("attach",
0516: "sun:xmpp:attach");
0517:
0518: public static final String DEFAULT_CLIENT_CATEGORY = "client";
0519: public static final String DEFAULT_CLIENT_TYPE = "pc";
0520: public static final String DEFAULT_CLIENT_NAME = "SJSClient";
0521: public static final NSI SUN_PRIVATE_LDAPGROUP_NAME = new NSI(
0522: "sunldapgrp", "sun:xmpp:ldapgroups");
0523:
0524: //public static final String AMP_NAMESPACE = "http://jabber.org/protocol/amp";
0525: public static final String AMP_ACTION_DROP_NAMESPACE = AMPExtension.NAMESPACE
0526: + "?action=drop";
0527: public static final String AMP_ACTION_ERROR_NAMESPACE = AMPExtension.NAMESPACE
0528: + "?action=error";
0529: public static final String AMP_ACTION_NOTIFY_NAMESPACE = AMPExtension.NAMESPACE
0530: + "?action=notify";
0531: public static final String AMP_ACTION_ALERT_NAMESPACE = AMPExtension.NAMESPACE
0532: + "?action=drop";
0533: public static final String AMP_COND_EXPIREAT_NAMESPACE = AMPExtension.NAMESPACE
0534: + "?condition=expire-at";
0535: public static final String AMP_COND_DELIVER_NAMESPACE = AMPExtension.NAMESPACE
0536: + "?condition=deliver";
0537: public static final String AMP_COND_MATCHRES_NAMESPACE = AMPExtension.NAMESPACE
0538: + "?condition=match-resource";
0539:
0540: // boolean variable set to true once the listPrivacyLists is invoked
0541: private boolean privacyListsListed = false;
0542:
0543: private Hashtable _ibbMessages = new Hashtable();
0544: private StreamSourceCreator _streamSrcCreator;
0545:
0546: //A list of id's for which there are already some send and watch call's
0547: private Map _sendAndWatchIDs = new HashMap();
0548: private Map inboundSendAndWatch = new HashMap();
0549:
0550: //list of the services which are already discovered
0551: private List _discoveredServices = new LinkedList();
0552:
0553: protected String _activePrivacyList = null;
0554: protected String _defaultPrivacyList = null;
0555:
0556: JID _mucService = null;
0557: JID _pubsubService = null;
0558: JID _judService = null;
0559: JID _voipComponent = null;
0560: Map _gateways = new Hashtable();
0561:
0562: private boolean _loadingServices = false;
0563:
0564: //The lock use to synchronize the access the jabber services
0565: private Object _jabberServiceLock = new Object();
0566: //The lock use to synchronize calls to loadJabberServices method
0567: private Object _loadingServiceLock = new Object();
0568:
0569: private ServerRedirectionListenerClass redirectionListener = null;
0570: private volatile StreamError _see_other_host;
0571: // private Worker _worker = new Worker(NUM_WORKER_THREAD);
0572:
0573: private boolean _serverFeaturesDiscovered = false;
0574:
0575: private static String _nonce = "";
0576: private boolean _authenticated = false;
0577:
0578: static {
0579: // get a unique id root
0580: try {
0581: _nonce = Integer.toString(InetAddress.getLocalHost()
0582: .hashCode());
0583: } catch (Exception e) {
0584: }
0585: }
0586:
0587: protected XMPPSession() {
0588:
0589: }
0590:
0591: /*public XMPPSession(XMPPSessionProvider fac, String serviceUrl, StreamSourceCreator streamSrcCreator) throws CollaborationException {
0592: init(fac, serviceUrl,null, null, -1, null, streamSrcCreator);
0593: connect(serviceUrl);
0594: try {
0595: registerChannelWithProvider();
0596: } catch(IOException ioe) {
0597: throw new CollaborationException(ioe);
0598: }
0599: }*/
0600:
0601: /** Creates new XMPPSession */
0602: public XMPPSession(XMPPSessionProvider fac, String serviceUrl,
0603: String destination, String loginName, String password,
0604: int loginType, CollaborationSessionListener listener,
0605: StreamSourceCreator streamSrcCreator)
0606: throws CollaborationException {
0607:
0608: init(fac, serviceUrl, destination, loginName, password,
0609: loginType, listener, streamSrcCreator);
0610: _connectAndAuthenticate(serviceUrl, password);
0611: // Dont initialise features for new user registeration
0612: if (null != _loginName) {
0613: _initFeaturesSupported();
0614: }
0615: }
0616:
0617: private void _connectAndAuthenticate(String serviceUrl,
0618: String password) throws CollaborationException {
0619:
0620: try {
0621: // Connect and open stream
0622: connect(serviceUrl);
0623:
0624: // For new user registeration , the login name will be null.
0625: // for all other cases , it should be non-null.
0626: // In case the custom provider does not require a login name ,
0627: // then pass on "" or some custom empty string which indicates to the
0628: // provider to ignore the value.
0629: if (_loginName != null) {
0630: // Disable legacy mode by default
0631: disableAuthLegacyMode();
0632: authenticate(password);
0633: }
0634: // Get some stream stats
0635: registerChannelWithProvider();
0636: start();
0637: } catch (CollaborationException ce) {
0638: if (null != _fi) {
0639: try {
0640: _fi.release();
0641: } catch (StreamException stEx) {
0642: }
0643: _fi = null;
0644: }
0645: logout();
0646: if (null != _see_other_host) {
0647: disableAuthLegacyMode();
0648: setAuthLegacyModeActive(false);
0649: }
0650: if (_see_other_host != null ||
0651: // We can come here also 'cos legacy mode was enabled .. in which case
0652: // retry auth with older server's semantics which are :
0653: // 1) Always ignore SASL.
0654: // 2) Always try jabber:iq auth - irrespective of whether it is advertised or not.
0655: isAuthLegacyModeEnabled()) {
0656: //because connection is closed, collaborationException
0657: //is thrown for sure
0658: _logout = false;
0659:
0660: StreamElement ele = null;
0661:
0662: if (_see_other_host != null) {
0663: ele = _see_other_host.getFirstElement(
0664: StreamError.SEE_OTHER_HOST_CONDITION,
0665: StreamError.CONDITION_NAMESPACE);
0666: }
0667: _connection = _jso.createStream(getStreamNameSpace());
0668: if (!isAuthLegacyModeEnabled()) {
0669: _connection.getOutboundContext().setVersion("1.0");
0670: } else {
0671: assert (!isAuthLegacyModeActive());
0672: _see_other_host = null;
0673: // Activate legacy mode.
0674: setAuthLegacyModeActive(true);
0675: _connectAndAuthenticate(serviceUrl, password);
0676: return;
0677: }
0678: if (ele == null && null != _see_other_host) {
0679: ele = _see_other_host.getFirstElement("text");
0680: }
0681: _see_other_host = null;
0682:
0683: if (ele != null) {
0684: String redirectedHost = ele.normalizeText();
0685: XMPPSessionProvider
0686: .debug("Connection Redirected : "
0687: + redirectedHost);
0688:
0689: setRedirectedHost(redirectedHost);
0690: _connectAndAuthenticate(redirectedHost, password);
0691: } else {
0692: XMPPSessionProvider
0693: .error("Unable to get the Redirected Host");
0694: throw new CollaborationException(
0695: "Unable to get the Redirected Host");
0696: }
0697: } else {
0698: throw ce;
0699: }
0700: } catch (Exception e) {
0701: logout();
0702: throw new CollaborationException(e);
0703: } finally {
0704: if (null != _fi) {
0705: try {
0706: _fi.release();
0707: } catch (StreamException stEx) {
0708: }
0709: }
0710: // Disable legacy mode.
0711: disableAuthLegacyMode();
0712: setAuthLegacyModeActive(false);
0713: }
0714: }
0715:
0716: protected void setRedirectedHost(String host) {
0717: /*
0718: CollaborationSessionListener listener = getSessionListener();
0719:
0720: if (listener instanceof ServerNotificationsListener){
0721: ((ServerNotificationsListener) listener).serverRedirected(host);
0722: }
0723: */
0724: }
0725:
0726: public CollaborationSessionListener getSessionListener() {
0727: return (CollaborationSessionListener) _sessionListeners.get(0);
0728: }
0729:
0730: private void init(XMPPSessionProvider fac, String serviceUrl,
0731: String destination, String loginName, String password,
0732: int loginType, CollaborationSessionListener listener,
0733: StreamSourceCreator streamSrcCreator)
0734: throws CollaborationException {
0735: _provider = fac;
0736: _sessionListeners.add(0, listener);
0737: _connection = _jso.createStream(getStreamNameSpace());
0738: _connection.getOutboundContext().setVersion("1.0");
0739: _streamSrcCreator = streamSrcCreator;
0740: if (loginName != null) {
0741: _loginName = loginName;
0742: uidHasDomain = (StringUtility.getDomainFromAddress(
0743: loginName, null) != null);
0744: }
0745:
0746: XMPPSessionProvider.debug("destination : " + destination);
0747:
0748: if (destination != null)
0749: setClientJID(new JID(destination));
0750: /*
0751: if (!Utilities.isValidString(_client.getNode()) ||
0752: !Utilities.isValidString(_client.getResource())) {
0753: throw new IllegalArgumentException("Client JID does not include a node and/or resource");
0754: }
0755: */
0756:
0757: }
0758:
0759: protected int getConnectParameters(String serviceUrl,
0760: StringBuffer hostSb, StringBuffer domainSb)
0761: throws CollaborationException {
0762:
0763: String domain = "";
0764: String host = "";
0765: int port = 5222;
0766:
0767: int startIndex = serviceUrl.indexOf(":");
0768: if (startIndex > 0) {
0769: host = serviceUrl.substring(0, startIndex);
0770: domain = host;
0771: port = Integer.parseInt(serviceUrl
0772: .substring(startIndex + 1));
0773: } else {
0774: InetSocketAddress isa = SRVLookup.XMPPClient(serviceUrl);
0775: domain = serviceUrl;
0776: host = isa.getHostName();
0777: port = isa.getPort();
0778: }
0779:
0780: domain = validateDomain(domain);
0781:
0782: hostSb.setLength(0);
0783: hostSb.append(host);
0784: domainSb.setLength(0);
0785: domainSb.append(domain);
0786:
0787: return port;
0788: }
0789:
0790: protected String validateDomain(String domain) {
0791: String retval = null;
0792: if (null != _client) {
0793: retval = _client.getDomainName();
0794: }
0795: if (!Utilities.isValidString(retval)) {
0796: retval = domain;
0797: }
0798: return retval;
0799: }
0800:
0801: /**
0802: * This methods connects to the server and
0803: * and exchanges the initial stream headers
0804: */
0805:
0806: private void connect(String serviceUrl)
0807: throws CollaborationException {
0808:
0809: // Validate server host info
0810: String domain, host;
0811: int port;
0812:
0813: StringBuffer domainSb = new StringBuffer();
0814: StringBuffer hostSb = new StringBuffer();
0815: port = getConnectParameters(serviceUrl, hostSb, domainSb);
0816:
0817: domain = domainSb.toString();
0818: host = hostSb.toString();
0819:
0820: _server = _sdf.createJID(domain);
0821:
0822: if (Utilities.isValidString(_server.getNode())
0823: || Utilities.isValidString(_server.getResource())) {
0824:
0825: throw new IllegalArgumentException(
0826: "Host JID cannot include a node or resource");
0827: }
0828:
0829: try {
0830: channelRegistered = false;
0831: _css = _streamSrcCreator.createStreamSource(host, port);
0832: /*
0833: Socket soc = _streamSrcCreator.getSocket();
0834: if(soc != null) {
0835: XMPPSessionProvider.debug(
0836: "SO_SNDBUF " + soc.getSendBufferSize());
0837: XMPPSessionProvider.debug(
0838: "SO_RCVBUF " + soc.getReceiveBufferSize());
0839: }
0840: */
0841: _connection.connect(_css);
0842: redirectionListener = new ServerRedirectionListenerClass();
0843: _connection.addPacketListener(PacketEvent.RECEIVED,
0844: redirectionListener);
0845:
0846: } catch (CollaborationException e) {
0847: //if it is collaborationException or subclasses of it
0848: //then propagate as it is
0849: throw e;
0850: } catch (Exception e) {
0851: //se.printStackTrace();
0852: throw new CollaborationException(e);
0853: }
0854:
0855: // do the initial stream header exchange
0856: open();
0857: }
0858:
0859: protected void configureTimeouts() {
0860: //setRequestTimeout(DEFAULT_REQUEST_TIMEOUT);
0861: //setShortRequestTimeout(DEFAULT_SHORT_REQUEST_TIMEOUT);
0862: setRequestTimeout(requestTimeout);
0863: setShortRequestTimeout(shortRequestTimeout);
0864: setFeatureTimeout(featureTimeout);
0865: }
0866:
0867: /**
0868: * This method does the initial stream header exchange.
0869: * This method can be overridden by the subclasses of this class.
0870: * The parameters of this method are not used by this method, but could be used
0871: * by the subclass which overrides this method to modify stream context objects.
0872: */
0873: protected void open() throws CollaborationException {
0874: findFeaturesInit();
0875: openImpl(15000);
0876: configureTimeouts();
0877: XMPPSessionProvider.debug("Opened");
0878: // Get some stream stats
0879: _server = _connection.getInboundContext().getFrom();
0880:
0881: setClientJID();
0882:
0883: /*
0884: if ((!uidHasDomain) && (_client != null)) {
0885: JID jid = new JID(_client.getJID().getNode(),
0886: _server.getDomain(),
0887: _client.getJID().getResource());
0888: _client.setJID(jid);
0889: }
0890: */
0891: XMPPSessionProvider.debug("FROM == " + _server);
0892: _sessionID = _connection.getInboundContext().getID();
0893: XMPPSessionProvider.debug("ID == " + _sessionID);
0894:
0895: findFeatures(getFeatureTimeout());
0896: processTLS();
0897: }
0898:
0899: protected void configureOutboundContext() {
0900: if (_server != null) {
0901: _connection.getOutboundContext().setTo(_server);
0902: } else {
0903: _connection.getOutboundContext().setTo(
0904: new JID(_client.getJID().getDomain()));
0905: }
0906: }
0907:
0908: protected void openImpl(long timeout) throws CollaborationException {
0909:
0910: configureOutboundContext();
0911:
0912: try {
0913: XMPPSessionProvider.debug("openImpl() being invoked : "
0914: + timeout);
0915: _connection.open(timeout);
0916: } catch (StreamException se) {
0917: //se.printStackTrace();
0918: throw new CollaborationException(se);
0919: }
0920: }
0921:
0922: protected void setFeatureTimeout(long timeout) {
0923: this .featureTimeout = timeout;
0924: }
0925:
0926: public long getFeatureTimeout() {
0927: return featureTimeout;
0928: }
0929:
0930: private FeatureIdentifier _fi = null;
0931:
0932: protected void findFeaturesInit() throws CollaborationException {
0933: try {
0934: _fi = new FeatureIdentifier(getConnection());
0935: _fi.initialise();
0936: } catch (StreamException stEx) {
0937: throw new CollaborationException(stEx);
0938: }
0939: }
0940:
0941: // A simple , "find if feature is present in stream" identifier.
0942: // We will wait until all of the 'reqd nsi list' is satisfied or
0943: // timeout happens.
0944: protected void findFeatures(long timeout)
0945: throws CollaborationException {
0946:
0947: try {
0948: _fi.process(timeout);
0949: } catch (StreamException stEx) {
0950: throw new CollaborationException(stEx);
0951: }
0952: return;
0953: }
0954:
0955: protected void processTLS() throws CollaborationException {
0956:
0957: // Dont do tls if in legacy mode.
0958: if (isAuthLegacyModeActive()) {
0959: return;
0960: }
0961:
0962: boolean tlsPresent = false;
0963: StartTLSFeature tlsfeature = null;
0964:
0965: Iterator iter = _fi.getFeatureList().iterator();
0966:
0967: while (iter.hasNext()) {
0968: Object obj = iter.next();
0969:
0970: if (obj instanceof StartTLSFeature) {
0971: // remove it from the feature list.
0972: iter.remove();
0973: tlsPresent = true;
0974: tlsfeature = (StartTLSFeature) obj;
0975: break;
0976: }
0977: }
0978:
0979: CollaborationSessionListener listener = getSessionListener();
0980:
0981: // If the listener does not implement SecurityListener or the
0982: // StreamSource is not an instance of StartTLSSocketStreamSource
0983: // we will not handle tls.
0984: // If the server specified tls as mandatory behaviour , then
0985: // we throw appropriate exception.
0986: boolean useTLS = (null != listener)
0987: && (listener instanceof SecurityListener)
0988: && _streamSrcCreator.isTLSSupported()
0989: && ((SecurityListener) listener).useTLS();
0990:
0991: XMPPSessionProvider.debug("tlsPresent : " + tlsPresent
0992: + " , useTLS : " + useTLS);
0993:
0994: if (!useTLS) {
0995: if (tlsPresent && tlsfeature.isRequired()) {
0996: throw new CollaborationException(
0997: "TLS support required by server");
0998: }
0999:
1000: if (listener instanceof SecurityListener) {
1001: if (!((SecurityListener) listener).continueInClear()) {
1002: throw new CollaborationException(
1003: "continueInClear == false and tls not supported");
1004: }
1005: }
1006:
1007: // Fine, we dont want to support tls and tls is not mandatory for server
1008: // so proceed in clear text.
1009: // We continue using the same set of features !
1010: return;
1011: }
1012:
1013: assert (listener instanceof SecurityListener);
1014:
1015: if (!tlsPresent) {
1016: if (!((SecurityListener) listener).continueInClear()) {
1017: throw new CollaborationException(
1018: "tls not supported by server");
1019: }
1020: } else {
1021: startTLSImpl();
1022: }
1023: }
1024:
1025: protected void resetConnection() throws CollaborationException {
1026: // our server throws up on this :(
1027: try {
1028: List bak = _fi.getFeatureList();
1029: _fi.resetFeatureList();
1030: _connection.drop();
1031: openImpl(0);
1032: findFeatures(getFeatureTimeout());
1033: List n = _fi.getFeatureList();
1034: if (null == n || 0 == n.size()) {
1035: _fi.setFeatureList(bak);
1036: }
1037: } catch (StreamException stEx) {
1038: throw new CollaborationException("tls error");
1039: }
1040: }
1041:
1042: protected void startTLSImpl() throws CollaborationException {
1043:
1044: StartTLSHandler handler = new StartTLSHandler(_sdf,
1045: _connection, _streamSrcCreator, _css);
1046: handler.process();
1047: // reopen stream.
1048: resetConnection();
1049: CollaborationSessionListener listener = getSessionListener();
1050: if (listener instanceof SecurityListener) {
1051: ((SecurityListener) listener).securityHandshakeComplete();
1052: }
1053:
1054: }
1055:
1056: protected String getLoginName() {
1057: return _loginName;
1058: }
1059:
1060: protected String getStreamNameSpace() {
1061: return Utilities.CLIENT_NAMESPACE;
1062: }
1063:
1064: protected void setClientJID() throws AuthenticationException {
1065: if ((!uidHasDomain) && (_client != null)) {
1066: try {
1067: JID jid = new JID(_client.getJID().getNode(), _server
1068: .getDomain(), _client.getJID().getResource());
1069: _client.setJID(jid);
1070: } catch (JIDFormatException jfe) {
1071: throw new AuthenticationException(jfe);
1072: }
1073: }
1074: }
1075:
1076: protected void setClientJID(JID jid) throws AuthenticationException {
1077: try {
1078: if (_client == null) {
1079: _client = new XMPPPrincipal(jid);
1080: } else {
1081: _client.setJID(jid);
1082: }
1083: } catch (JIDFormatException jfe) {
1084: throw new AuthenticationException(jfe);
1085: }
1086: }
1087:
1088: protected void fireAuthSuccessEvent() {
1089: _authenticated = true;
1090: CollaborationSessionListener listener = getSessionListener();
1091: if (null != listener
1092: && listener instanceof AuthenticationListener) {
1093: ((AuthenticationListener) listener)
1094: .authenticationComplete();
1095: }
1096: }
1097:
1098: /**
1099: * Jabber authentication
1100: */
1101: protected void authenticate(String password)
1102: throws CollaborationException {
1103:
1104: List activeFeatureList = _fi.getFeatureList();
1105: if (null == activeFeatureList || activeFeatureList.isEmpty() ||
1106: // force fallback to jabber:iq auth
1107: isAuthLegacyModeActive()) {
1108: // fall back on old method of doing jabber query auth.
1109: doAuthQueryLogin(password);
1110: fireAuthSuccessEvent();
1111: return;
1112: }
1113:
1114: // Get list of the supported mechanism's , query user which one to use.
1115: Iterator iter = activeFeatureList.iterator();
1116: int valid = 0;
1117: List mechList = new ArrayList();
1118: Map authProviders = _provider.getAuthProviderMap();
1119:
1120: while (iter.hasNext()) {
1121: Object obj = iter.next();
1122:
1123: if (obj instanceof SASLMechanismsFeature) {
1124: valid++;
1125: SASLMechanismsFeature feature = (SASLMechanismsFeature) obj;
1126: Iterator iter1 = feature.getMechanismNames().iterator();
1127: while (iter1.hasNext()) {
1128: String mechName = (String) iter1.next();
1129: if (null != authProviders.get(mechName)) {
1130: // supported.
1131: mechList.add(mechName);
1132: }
1133: }
1134: } else if (obj instanceof AuthStreamFeature) {
1135: valid++;
1136: // always supported :-)
1137: mechList
1138: .add(AuthenticationListener.JABBER_IQ_AUTH_MECHANISM);
1139: }
1140: }
1141:
1142: if (mechList.size() > 0) {
1143: CollaborationSessionListener listener = getSessionListener();
1144: // Default to using the most preffered mechanism as sent by server.
1145: int mechanismToUse = 0;
1146:
1147: if (null != listener
1148: && listener instanceof AuthenticationListener) {
1149: mechanismToUse = ((AuthenticationListener) listener)
1150: .useAuthenticationMechanism((String[]) mechList
1151: .toArray(new String[0]));
1152: }
1153:
1154: if (mechanismToUse < 0 || mechanismToUse >= mechList.size()) {
1155: throw new AuthenticationException(
1156: "All handlers rejected");
1157: }
1158:
1159: String mechName = (String) mechList.get(mechanismToUse);
1160: if (!mechName
1161: .equals(AuthenticationListener.JABBER_IQ_AUTH_MECHANISM)) {
1162:
1163: XMPPSessionProvider.debug("\nUsing SASL mechanism : "
1164: + mechName);
1165: assert (authProviders.get(mechName) instanceof SASLClientProviderFactory);
1166:
1167: SASLClientProviderFactory providerFactory = (SASLClientProviderFactory) authProviders
1168: .get(mechName);
1169: assert (null != providerFactory);
1170:
1171: SASLClientProvider provider = providerFactory
1172: .createInstance(mechName);
1173: try {
1174: provider.init();
1175: } catch (SASLProviderException spEx) {
1176: throw new CollaborationException(
1177: "sasl provider exception in init", spEx);
1178: }
1179: provider.setLoginName(_loginName);
1180: provider.setPassword(password);
1181:
1182: String toServer = null;
1183: if (null != _server) {
1184: toServer = _server.getDomain();
1185: } else if (null != _client) {
1186: toServer = _client.getJID().getDomain();
1187: }
1188: provider.setServer(toServer);
1189:
1190: AuthProcessor authproc = new AuthProcessor();
1191: authproc.setStreamDataFactory(_sdf);
1192: authproc.setStream(_connection);
1193: authproc.saslAuthenticate(provider, mechName);
1194: resetConnection();
1195: bindResource(_client);
1196: // Always starting a session !
1197: startSession();
1198: fireAuthSuccessEvent();
1199: XMPPSessionProvider
1200: .debug("\nSUCESS Using SASL mechanism : "
1201: + mechName + " !!\n");
1202: return;
1203: }
1204:
1205: doAuthQueryLogin(password);
1206: fireAuthSuccessEvent();
1207: } else if (valid > 0) {
1208: throw new AuthenticationException(
1209: "No valid auth handler found");
1210: } else {
1211: // fallback for old behaviour
1212: doAuthQueryLogin(password);
1213: fireAuthSuccessEvent();
1214: }
1215: return;
1216: }
1217:
1218: protected boolean isBindFeatureSupported()
1219: throws CollaborationException {
1220:
1221: List activeFeatureList = _fi.getFeatureList();
1222: XMPPSessionProvider
1223: .debug("isBindFeatureSupported : activeFeatureList == "
1224: + activeFeatureList);
1225: if (null == activeFeatureList || activeFeatureList.isEmpty()) {
1226: return false;
1227: }
1228:
1229: Iterator iter = activeFeatureList.iterator();
1230: while (iter.hasNext()) {
1231: Object obj = iter.next();
1232: if (obj instanceof BindQuery) {
1233: return true;
1234: }
1235: }
1236: return false;
1237: }
1238:
1239: protected boolean isSessionFeatureSupported()
1240: throws CollaborationException {
1241:
1242: List activeFeatureList = _fi.getFeatureList();
1243: XMPPSessionProvider
1244: .debug("isBindFeatureSupported : activeFeatureList == "
1245: + activeFeatureList);
1246: if (null == activeFeatureList || activeFeatureList.isEmpty()) {
1247: return false;
1248: }
1249:
1250: Iterator iter = activeFeatureList.iterator();
1251: while (iter.hasNext()) {
1252: Object obj = iter.next();
1253: if (obj instanceof SessionQuery) {
1254: return true;
1255: }
1256: }
1257: return false;
1258: }
1259:
1260: protected void startSession() throws CollaborationException {
1261:
1262: if (!isSessionFeatureSupported()) {
1263: // Silently ignore ? This should be discussed more ...
1264: // It is not mandatory to support 'session' feature.
1265: //throw new CollaborationException("Session not supported");
1266: return;
1267: }
1268:
1269: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1270: InfoQuery.class);
1271: SessionQuery sq = (SessionQuery) _sdf.createExtensionNode(
1272: SessionQuery.NAME, SessionQuery.class);
1273:
1274: if (null == iq) {
1275: // AuthenticationException ?
1276: throw new CollaborationException(
1277: "Unable to create iq packet");
1278: }
1279: if (null == sq) {
1280: // AuthenticationException ?
1281: throw new CollaborationException(
1282: "Unable to create sessionquery packet");
1283: }
1284:
1285: iq.setTo(_server);
1286: iq.setType(InfoQuery.SET);
1287: iq.setID(nextID("session"));
1288:
1289: iq.add(sq);
1290:
1291: try {
1292: iq = (InfoQuery) sendAndWatch(iq, getRequestTimeout());
1293: } catch (StreamException se) {
1294: XMPPSessionProvider.error(se.toString(), se);
1295: // AuthenticationException ?
1296: throw new CollaborationException(se);
1297: }
1298:
1299: if (null == iq) {
1300: throw new CollaborationException("No reply from server");
1301: }
1302: if (InfoQuery.ERROR == iq.getType()) {
1303: // AuthenticationException ?
1304: throw new CollaborationException(iq.getError().getText());
1305: }
1306: }
1307:
1308: // An extremely dirty set of fallback code in place since we had a nasty
1309: // bug in JES4 server and need to support it in current release for backward
1310: // compatibility reasons :-(
1311: // Essentially , even though the server would advertise bind as a feature, it would
1312: // be unable to actually perform a bind.
1313: private static final boolean supportAuthLegacyMode = System
1314: .getProperty(
1315: "org.netbeans.lib.collab.xmpp.XMPPSession.legacymode",
1316: "true").equalsIgnoreCase("true");
1317:
1318: private boolean legacyModeEnabled = false;
1319: private boolean legacyModeActivate = false;
1320:
1321: protected void enableAuthLegacyMode() {
1322: if (supportAuthLegacyMode) {
1323: legacyModeEnabled = true;
1324: }
1325: }
1326:
1327: protected boolean isAuthLegacyModeEnabled() {
1328: return legacyModeEnabled;
1329: }
1330:
1331: protected void disableAuthLegacyMode() {
1332: legacyModeEnabled = false;
1333: }
1334:
1335: private boolean isAuthLegacyModeActive() {
1336: return legacyModeActivate;
1337: }
1338:
1339: private void setAuthLegacyModeActive(boolean actvate) {
1340: this .legacyModeActivate = actvate;
1341: }
1342:
1343: protected void bindResource(XMPPPrincipal client)
1344: throws CollaborationException {
1345:
1346: JID jid = client.getJID();
1347: // initFeatures would be already called - and so the feature will be
1348: // set appropriately.
1349: // initFeatures(true);
1350:
1351: if (!isBindFeatureSupported()) {
1352: throw new CollaborationException("Bind not supported");
1353: }
1354:
1355: InfoQuery iqBind = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1356: InfoQuery.class);
1357: BindQuery bq = (BindQuery) _sdf.createExtensionNode(
1358: BindQuery.NAME, BindQuery.class);
1359:
1360: if (null == iqBind) {
1361: throw new CollaborationException(
1362: "Unable to create iq packet");
1363: }
1364: if (null == bq) {
1365: throw new CollaborationException(
1366: "Unable to create bindquery packet");
1367: }
1368:
1369: iqBind.setTo(_server);
1370: iqBind.setType(InfoQuery.SET);
1371: iqBind.setID(nextID("bind"));
1372:
1373: bq.setJID(jid);
1374:
1375: bq.setResource(jid.getResource());
1376: iqBind.add(bq);
1377:
1378: // This is where the legacy mode actually gets activated.
1379: // In JES4 server , this is the request which could fail.
1380: enableAuthLegacyMode();
1381: try {
1382: iqBind = (InfoQuery) sendAndWatch(iqBind,
1383: getRequestTimeout());
1384: } catch (StreamException se) {
1385: XMPPSessionProvider.error(se.toString(), se);
1386: throw new AuthenticationException(se);
1387: }
1388:
1389: // We passed it , disable legacy mode.
1390: disableAuthLegacyMode();
1391:
1392: if (null == iqBind) {
1393: throw new AuthenticationException("No reply from server");
1394: }
1395: if (InfoQuery.ERROR == iqBind.getType()) {
1396: throw new AuthenticationException(iqBind.getError()
1397: .getText());
1398: }
1399:
1400: // Set the jid to what is specified by the server !
1401: List bqlist = iqBind.listExtensions(BindQuery.NAMESPACE);
1402: if (null == bqlist || 1 != bqlist.size()) {
1403: throw new AuthenticationException(
1404: "BindQuery namespace listextentions returned error : "
1405: + bqlist);
1406: }
1407: bq = (BindQuery) bqlist.get(0);
1408: // Should we set only the resource ? Or the whole jid itself ?
1409: client.setJID(bq.getJID());
1410: //assert (client.getJID().getDomain().equals(_server.getDomain()));
1411: }
1412:
1413: protected void doAuthQueryLogin(String password)
1414: throws CollaborationException {
1415:
1416: InfoQuery iqAuth;
1417: AuthQuery auth;
1418:
1419: // Get Auth Details
1420: try {
1421: registerChannelWithProvider();
1422: } catch (IOException ioEx) {
1423: throw new CollaborationException(ioEx);
1424: }
1425:
1426: iqAuth = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1427: InfoQuery.class);
1428:
1429: iqAuth.setTo(_server);
1430: iqAuth.setType(InfoQuery.GET);
1431: iqAuth.setID(nextID("auth"));
1432:
1433: auth = (AuthQuery) _sdf.createExtensionNode(AuthQuery.NAME,
1434: AuthQuery.class);
1435:
1436: if (auth == null) {
1437: XMPPSessionProvider.debug("Auth is null");
1438: throw new AuthenticationException(
1439: "Unable to create auth packet");
1440: }
1441: if (_client == null) {
1442: XMPPSessionProvider.debug("_client is null");
1443: throw new AuthenticationException("User info not present");
1444: }
1445:
1446: auth.setUsername(_loginName);
1447:
1448: iqAuth.add(auth);
1449: try {
1450: iqAuth = (InfoQuery) sendAndWatch(iqAuth,
1451: getRequestTimeout());
1452: } catch (StreamException se) {
1453: XMPPSessionProvider.error(se.toString(), se);
1454: throw new AuthenticationException(se);
1455: }
1456: if (iqAuth == null) {
1457: throw new AuthenticationException("No reply from server");
1458: }
1459: if ((iqAuth.getType() == InfoQuery.ERROR)
1460: && (iqAuth.getError().getType() == PacketError.AUTH)) {
1461: throw new AuthenticationException(iqAuth.getError()
1462: .getText());
1463: }
1464: /*if ((iqAuth == null) || (iqAuth.getType() != InfoQuery.RESULT)) {
1465: throw new IllegalStateException("Could not authenticate to server iqAuth=" + iqAuth);
1466: }*/
1467:
1468: // Setup authentication
1469: auth = (AuthQuery) iqAuth.listExtensions(AuthQuery.NAMESPACE)
1470: .get(0);
1471: auth.setUsername(_loginName);
1472: auth.setResource(_client.getJID().getResource());
1473: /*
1474: if (AuthQuery.ZERO_KNOWLEDGE.isSupported(auth)) {
1475: Method method = AuthQuery.ZERO_KNOWLEDGE;
1476: Map params = method.setupAuthParams(auth);
1477: params.put("password", password);
1478: auth.setPassword(password);
1479: method.setupAuth(auth, params);
1480: XMPPSessionProvider.info("Authenticating using " + method);
1481: */
1482: if (AuthQuery.DIGEST.isSupported(auth)) {
1483: Method method = AuthQuery.DIGEST;
1484: Map params = method.setupAuthParams(auth);
1485: params.put("sessionid", _sessionID);
1486: params.put("password", password);
1487: method.setupAuth(auth, params);
1488: XMPPSessionProvider.info("Authenticating using " + method);
1489: } else if (AuthQuery.PLAIN.isSupported(auth)) {
1490: Method method = AuthQuery.PLAIN;
1491: Map params = method.setupAuthParams(auth);
1492: params.put("password", password);
1493: method.setupAuth(auth, params);
1494: XMPPSessionProvider.info("Authenticating using " + method);
1495: }
1496:
1497: iqAuth.setTo(_server);
1498: iqAuth.setType(InfoQuery.SET);
1499: iqAuth.setID(nextID("auth"));
1500: try {
1501: iqAuth = (InfoQuery) sendAndWatch(iqAuth,
1502: getRequestTimeout());
1503: } catch (StreamException se) {
1504: XMPPSessionProvider.error(se.toString(), se);
1505: throw new AuthenticationException(se);
1506: }
1507: if (iqAuth == null) {
1508: throw new AuthenticationException("No reply from server");
1509: }
1510: if ((iqAuth.getType() == InfoQuery.ERROR)
1511: && (iqAuth.getError().getType() == PacketError.AUTH)) {
1512: throw new AuthenticationException(iqAuth.getError()
1513: .getText());
1514: }
1515: /*if ((iqAuth == null) || (iqAuth.getType() != InfoQuery.RESULT)) {
1516: throw new IllegalStateException("Could not authenticate to server iqAuth=" + iqAuth);
1517: }*/
1518:
1519: // Is this required ? - Mridul
1520: // re-intialize the server to the domain-name of the authenticated user
1521: _server = new JID(_client.getDomainName());
1522: }
1523:
1524: void start() throws CollaborationException, IOException {
1525:
1526: XMPPSessionProvider.debug("XMPPSession: start()");
1527: setKeepAliveEnabled(true);
1528: //_personalStoreSession = new XMPPPersonalStoreSession(this);
1529: //_personalStoreSession.getProfile();
1530: // load the contact list i.e get the roster
1531: //_personalStoreSession.sendRosterRequest();
1532:
1533: }
1534:
1535: protected void registerChannelWithProvider() throws IOException {
1536: // This will be called after tls negotiation has completed - so no worries.
1537: // start the reader
1538: Runnable packetReader = null;
1539: synchronized (this ) {
1540: if (!channelRegistered) {
1541: packetReader = new Runnable() {
1542: public void run() {
1543: try {
1544: _connection.process();
1545: } catch (StreamException se) {
1546: //se.printStackTrace();
1547: }
1548: }
1549: };
1550: channelRegistered = true;
1551: }
1552: }
1553: if (null != packetReader) {
1554: setupListeners();
1555: registerImpl(packetReader);
1556: }
1557: }
1558:
1559: protected void registerImpl(Runnable packetReader)
1560: throws IOException {
1561: if (_streamSrcCreator instanceof SocketStreamSourceCreator) {
1562: SocketStreamSourceCreator creator = (SocketStreamSourceCreator) _streamSrcCreator;
1563: ByteChannel channel = creator.getBufferedChannel();
1564: SocketChannel socketChannel = creator.getSocketChannel();
1565: if (channel instanceof BufferedByteChannel) {
1566: _selectionKey = _provider.register(socketChannel,
1567: packetReader, (BufferedByteChannel) channel);
1568: } else {
1569: _selectionKey = _provider.register(socketChannel,
1570: packetReader);
1571: }
1572: } else {
1573: // Unhandled case ! subclass should be handling this - so error.
1574: XMPPSessionProvider
1575: .error("Unsupported _streamSrcCreator : "
1576: + _streamSrcCreator);
1577: }
1578: }
1579:
1580: public Map getNameSpaces() {
1581: return _namespaces;
1582: }
1583:
1584: private void setupListeners() {
1585: org.jabberstudio.jso.event.PacketListener watcher;
1586: org.jabberstudio.jso.event.StreamStatusListener statusListener;
1587:
1588: /*Map ns = getNameSpaces();
1589:
1590: //Define namespace mappings
1591: ns.put("app", _connection.getDefaultNamespace());
1592: ns.put("time", "jabber:iq:time");
1593: ns.put("ver", "jabber:iq:version");
1594: ns.put("last", "jabber:iq:last");*/
1595: //watcher.setupNamespaces(ns);
1596: if (null != redirectionListener) {
1597: _connection.removePacketListener(PacketEvent.RECEIVED,
1598: redirectionListener);
1599: redirectionListener = null;
1600: }
1601:
1602: statusListener = new StatusListenerClass();
1603: watcher = new PacketListenerClass();
1604: _connection.addPacketListener(PacketEvent.RECEIVED, watcher);
1605: _connection.addPacketListener(new DebugPacketListenerClass());
1606: _connection.addStreamStatusListener(statusListener);
1607:
1608: }
1609:
1610: public String nextID(String key) {
1611: String u = (new java.rmi.server.UID()).toString() + _nonce;
1612: u = StringUtility.substitute(u, ":", ".");
1613: u = StringUtility.substitute(u, "-", "_");
1614: return u;
1615: }
1616:
1617: public InfoQuery createIBBInfoQuery(JID to, String sid, boolean open) {
1618: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1619: InfoQuery.class);
1620: iq.setType(InfoQuery.SET);
1621: iq.setID(nextID("ibb"));
1622: iq.setTo(to);
1623: iq.setFrom(_client.getJID());
1624: Extension extn;
1625: if (open) {
1626: extn = _sdf.createExtensionNode(IBB_OPEN);
1627: extn.setAttributeValue("block-size", Integer
1628: .toString(IBB_MESSAGE_SIZE));
1629: } else {
1630: extn = _sdf.createExtensionNode(IBB_CLOSE);
1631: }
1632: extn.setAttributeValue("sid", sid);
1633: iq.add(extn);
1634: return iq;
1635: }
1636:
1637: public void sendAllMessageParts(XMPPMessage msg)
1638: throws CollaborationException {
1639: org.jabberstudio.jso.Message xmppMessage = (org.jabberstudio.jso.Message) msg
1640: .getXMPPMessage();
1641: MessagePart parts[] = msg.getParts();
1642: if (parts.length == 1) {
1643: try {
1644: xmppMessage
1645: .add(getPropertiesExtension(msg.getHeaders()));
1646: //Do we need to update the AMPExtensions for all the parts?
1647: msg.updateAMPExtension();
1648: _connection.send(xmppMessage);
1649: } catch (StreamException se) {
1650: XMPPSessionProvider.error(se.toString(), se);
1651: throw new CollaborationException(se.toString());
1652: }
1653: return;
1654: }
1655: //Accumulate all the sid's for the message parts
1656: String[] sid_list = new String[parts.length - 1];
1657: for (int i = 1; i < parts.length; i++) {
1658: String sid = nextID("sid");
1659: InfoQuery iq = createIBBInfoQuery(xmppMessage.getTo(), sid,
1660: true);
1661: try {
1662: iq = (InfoQuery) sendAndWatch(iq, getRequestTimeout());
1663: } catch (StreamException se) {
1664: XMPPSessionProvider.error(se.toString(), se);
1665: }
1666:
1667: if ((iq == null) || (iq.getType() != InfoQuery.RESULT)) {
1668: throw new CollaborationException(
1669: "Failed to open IBB Stream");
1670: }
1671: //if there was a success then send all the message parts.
1672: //first send the actual message(part[0])
1673: try {
1674: Extension data = _sdf.createExtensionNode(IBB_DATA);
1675: data.setAttributeValue("sid", sid);
1676: org.jabberstudio.jso.Message newMsg;
1677: int seqId = 0;
1678: newMsg = (org.jabberstudio.jso.Message) _sdf
1679: .createPacketNode(MESSAGE_NAME,
1680: org.jabberstudio.jso.Message.class);
1681: newMsg.setFrom(xmppMessage.getFrom());
1682: newMsg.setTo(xmppMessage.getTo());
1683: newMsg.setID(nextID("message"));
1684: String contents = parts[i].getContent();
1685: //add the meta data to the packet
1686: newMsg
1687: .addExtension(getPropertiesExtension(((XMPPMessagePart) parts[i])
1688: .getHeaders()));
1689:
1690: int packets = ((int) contents.length() / IBB_MESSAGE_SIZE) + 1;
1691: //data = _sdf.createExtensionNode(IBB_DATA);
1692: //data.setAttributeValue("sid",sid);
1693: newMsg.add(data);
1694: int end = 0;
1695: for (int k = 0; k < packets; k++) {
1696: data.setAttributeValue("seq", Integer
1697: .toString(seqId++));
1698: end = ((end + IBB_MESSAGE_SIZE) <= contents
1699: .length()) ? (end + IBB_MESSAGE_SIZE)
1700: : contents.length();
1701: data.clearText();
1702: data.addText(contents.substring(k
1703: * IBB_MESSAGE_SIZE, end));
1704: _connection.send(newMsg);
1705: }
1706: sid_list[i - 1] = sid;
1707: iq = createIBBInfoQuery(xmppMessage.getTo(), sid, false);
1708: //use send and watch to avoid any threading issues in the server
1709: iq = (InfoQuery) sendAndWatch(iq, getRequestTimeout());
1710: //_connection.send(iq);
1711: } catch (StreamException se) {
1712: XMPPSessionProvider.error(se.toString(), se);
1713: }
1714: }
1715: StringBuffer buf = new StringBuffer(sid_list[0]);
1716: for (int n = 1; n < sid_list.length; n++) {
1717: buf.append("," + sid_list[n]);
1718: }
1719: //finally add the sid list and the headers and send the message
1720: StreamElement attachElem = _sdf
1721: .createElementNode(SUN_ATTACH_NAME);
1722: attachElem.addText(buf.toString());
1723: xmppMessage.add(attachElem);
1724: /*Hashtable ht = msg.getHeaders();
1725: ht.put(XMPPMessage.SID_LIST, buf.toString());
1726: xmppMessage.add(getPropertiesExtension(ht));*/
1727: xmppMessage.add(getPropertiesExtension(msg.getHeaders()));
1728: //send the actual message after all the attachments are sent.
1729: try {
1730: _connection.send(xmppMessage);
1731: } catch (StreamException se) {
1732: XMPPSessionProvider.error(se.toString(), se);
1733: }
1734: }
1735:
1736: private Extension getPropertiesExtension(Hashtable contents) {
1737: if ((contents == null) || (contents.size() == 0))
1738: return null;
1739: Extension x = _sdf.createExtensionNode(SUN_PRIVATE_NAME);
1740: for (Enumeration e1 = contents.keys(); e1.hasMoreElements();) {
1741: String header = (String) e1.nextElement();
1742: String value = (String) contents.get(header);
1743: StreamElement propElem = _sdf.createElementNode(_sdf
1744: .createNSI("property", null));
1745: propElem.setAttributeValue("name", header);
1746: propElem.addElement("value").addText(value);
1747: x.add(propElem);
1748: }
1749: return x;
1750: }
1751:
1752: public CollaborationPrincipal createPrincipal(String uid)
1753: throws CollaborationException {
1754: String fquid = StringUtility.appendDomainToAddress(uid, _server
1755: .getDomain());
1756: return new XMPPPrincipal(new JID(fquid));
1757: }
1758:
1759: /** create a principal object based on a fully-qualified user id
1760: * @param uid FQ user id.
1761: * @param displayName
1762: * @return a new Principal object.
1763: */
1764: public CollaborationPrincipal createPrincipal(String uid,
1765: String displayName) throws CollaborationException {
1766: String fquid = StringUtility.appendDomainToAddress(uid, _server
1767: .getDomain());
1768: return new XMPPPrincipal(new JID(fquid), displayName);
1769: }
1770:
1771: public static String getItemValue(StreamElement node, String name) {
1772: String value = null;
1773: Iterator i = node.listElements(name).iterator();
1774: if (i.hasNext()) {
1775: value = ((StreamElement) i.next()).normalizeTrimText();
1776: }
1777: return value;
1778: }
1779:
1780: /*private JID getConferenceServer() throws CollaborationException {
1781: InfoQuery iq;
1782: DiscoItemsQuery dq;
1783:
1784: dq = sendItemsQuery(_server,null);
1785: Iterator itr = dq.listItems().iterator();
1786: while (itr.hasNext()) {
1787: DiscoItem item = (DiscoItem)itr.next();
1788: if ((item.getName()).equals("Multi User Conference Service"))
1789: return item.getJID();
1790: }
1791: return null;
1792: }*/
1793:
1794: private class DiscoRunnable implements Runnable {
1795: JID _to;
1796:
1797: DiscoRunnable(JID to) {
1798: _to = to;
1799: }
1800:
1801: public void run() {
1802: // query items, and then info for each item
1803: try {
1804: DiscoItemsQuery dq = sendItemsQuery(_to, null);
1805: Iterator itr = dq.listItems().iterator();
1806: XMPPSessionProvider
1807: .debug("Loading Jabber services for " + _to);
1808: while (itr.hasNext()) {
1809: DiscoItem item = (DiscoItem) itr.next();
1810: DiscoInfoQuery diq = null;
1811: try {
1812: diq = sendInfoQuery(item.getJID());
1813: } catch (CollaborationException ce) {
1814: XMPPSessionProvider.debug(null, ce);
1815: continue;
1816: }
1817:
1818: for (Iterator iter = diq.listIdentities()
1819: .iterator(); iter.hasNext();) {
1820: DiscoIdentity discoIdentity = (DiscoIdentity) iter
1821: .next();
1822: String category = discoIdentity.getCategory();
1823: if (PersonalStoreEntry.CONFERENCE
1824: .equals(category)
1825: && _conferenceService != null) {
1826: XMPPSessionProvider
1827: .debug("adding remote conference service "
1828: + item.getJID());
1829: _conferenceService.addRemoteService(item
1830: .getJID());
1831:
1832: } else if ("pubsub".equals(category)
1833: && _newsService != null) {
1834: _newsService
1835: .addRemoteService(item.getJID());
1836:
1837: } else if ("directory".equals(category)
1838: && _personalStoreService != null) {
1839: _personalStoreService.addRemoteService(item
1840: .getJID());
1841:
1842: }
1843: }
1844: }
1845:
1846: // keep track so we don't query twice
1847: _remoteServices.add(_to);
1848:
1849: } catch (Exception e) {
1850: }
1851: }
1852: }
1853:
1854: protected void loadJabberServices() throws CollaborationException {
1855: DiscoItemsQuery dq = sendItemsQuery(_server, null);
1856: Iterator itr = dq.listItems().iterator();
1857: PacketMonitor monitor = new PacketMonitor();
1858: monitor.setRouter(_connection);
1859: monitor.setDispatcher(_connection);
1860: monitor.setTimeout(getRequestTimeout());
1861: while (itr.hasNext()) {
1862: DiscoInfoQuery diq = null;
1863: DiscoItem item = (DiscoItem) itr.next();
1864: if (item.getJID().equals(getCurrentUserJID()))
1865: continue; // no need to discover oneself
1866: if (!_discoveredServices.contains(item.getJID())) {
1867: InfoQuery iq = createDiscoInfoQuery(item.getJID(), null);
1868: try {
1869: monitor.send(iq, new ServiceDiscovery(this , item));
1870: } catch (IllegalStateException e) {
1871: }
1872: }
1873: }
1874: }
1875:
1876: protected DiscoItemsQuery sendItemsQuery(JID server, String node)
1877: throws CollaborationException {
1878: DiscoItemsQuery dq;
1879: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1880: InfoQuery.class);
1881: iq.setType(InfoQuery.GET);
1882: iq.setFrom(_client.getJID());
1883: iq.setTo(server);
1884: iq.setID(nextID("item"));
1885:
1886: dq = (DiscoItemsQuery) _sdf
1887: .createElementNode(DiscoItemsQuery.NAME);
1888: //dq.addIdentity("conference", "text");
1889: if (node != null) {
1890: dq.setNode(node);
1891: }
1892: iq.add(dq);
1893:
1894: try {
1895: iq = (InfoQuery) sendAndWatch(iq, getShortRequestTimeout());
1896: } catch (StreamException se) {
1897: XMPPSessionProvider.error(se.toString(), se);
1898: throw new CollaborationException("Connection Error");
1899: }
1900:
1901: if (iq == null) {
1902: throw new TimeoutException("Request timed out");
1903: } else if (iq.getType() == InfoQuery.RESULT) {
1904: return (DiscoItemsQuery) iq.listExtensions(
1905: DiscoItemsQuery.NAMESPACE).get(0);
1906: } else if (iq.getType() == InfoQuery.ERROR) {
1907: PacketError error = iq.getError();
1908: if (error != null) {
1909: String errorCond = error.getDefinedCondition();
1910: if (errorCond != null
1911: && ((errorCond
1912: .equals(PacketError.FEATURE_NOT_IMPLEMENTED_CONDITION)) || (errorCond
1913: .equals(PacketError.SERVICE_UNAVAILABLE_CONDITION)))) {
1914: throw new ServiceUnavailableException(error
1915: .getText());
1916: }
1917: }
1918: }
1919: throw new CollaborationException(
1920: "Some error has occurred in getting the discovery information : "
1921: + iq.toString());
1922: }
1923:
1924: private InfoQuery createDiscoInfoQuery(JID server, String node) {
1925: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
1926: InfoQuery.class);
1927: iq.setType(InfoQuery.GET);
1928: iq.setFrom(_client.getJID());
1929: iq.setTo(server);
1930: iq.setID(nextID("info"));
1931: DiscoInfoQuery dq = (DiscoInfoQuery) _sdf
1932: .createElementNode(DiscoInfoQuery.NAME);
1933: if (node != null) {
1934: dq.setNode(node);
1935: }
1936: iq.add(dq);
1937: return iq;
1938: }
1939:
1940: protected DiscoInfoQuery sendInfoQuery(JID server, String node)
1941: throws CollaborationException {
1942: InfoQuery inputIq = createDiscoInfoQuery(server, node);
1943: InfoQuery iq = null;
1944: try {
1945: iq = (InfoQuery) sendAndWatch(inputIq,
1946: getShortRequestTimeout());
1947: } catch (StreamException se) {
1948: XMPPSessionProvider.error(se.toString(), se);
1949: throw new IllegalStateException(
1950: "Could not authenticate to server!");
1951: }
1952:
1953: if (iq == null) {
1954: throw new TimeoutException("Request timed out");
1955: } else if (iq.getType() == InfoQuery.RESULT) {
1956: return (DiscoInfoQuery) iq.listExtensions(
1957: DiscoInfoQuery.NAMESPACE).get(0);
1958: } else if (iq.getType() == InfoQuery.ERROR) {
1959: PacketError error = iq.getError();
1960: if (error != null) {
1961: String errorCond = error.getDefinedCondition();
1962: if (errorCond != null
1963: && ((errorCond
1964: .equals(PacketError.FEATURE_NOT_IMPLEMENTED_CONDITION)) || (errorCond
1965: .equals(PacketError.SERVICE_UNAVAILABLE_CONDITION)))) {
1966: throw new ServiceUnavailableException(error
1967: .getText());
1968: }
1969: }
1970: }
1971: throw new CollaborationException(
1972: "Some error has occurred in getting the discovery information : "
1973: + iq.toString());
1974: }
1975:
1976: private DiscoInfoQuery sendInfoQuery(JID server)
1977: throws CollaborationException {
1978: return sendInfoQuery(server, null);
1979: }
1980:
1981: public CollaborationPrincipal getPrincipal()
1982: throws CollaborationException {
1983: return _client;
1984: }
1985:
1986: protected long getLogoutTimeout() {
1987: // Hardcoded for now to point to short req timeout.
1988: return _authenticated ? 10000 : getShortRequestTimeout();
1989: }
1990:
1991: public void logout() {
1992: try {
1993: _provider.cleanupSession(this );
1994: _logout = true;
1995: _connection.close(getLogoutTimeout());
1996: } catch (Exception e) {
1997: XMPPSessionProvider.error(e.toString(), e);
1998: } finally {
1999: _authenticated = false;
2000: _provider.cancel(_selectionKey);
2001: try {
2002: _connection.disconnect();
2003: } catch (Exception e) {
2004: XMPPSessionProvider.error(e.toString(), e);
2005: }
2006: }
2007: }
2008:
2009: public void setSessionListener(CollaborationSessionListener listener) {
2010: _sessionListeners.remove(0);
2011: _sessionListeners.add(0, listener);
2012: }
2013:
2014: private org.netbeans.lib.collab.Presence processPresence(
2015: org.jabberstudio.jso.Presence p)
2016: throws CollaborationException {
2017: if ((p.getType() != null)
2018: && (p.getType()
2019: .equals(org.jabberstudio.jso.Presence.ERROR))) {
2020: //throw new CollaborationException("Error while receiving presence");
2021: XMPPSessionProvider
2022: .error("Recieved a presence packet of type error");
2023: return null;
2024: }
2025: Iterator itr = p.listElements().iterator();
2026: while (itr.hasNext()) {
2027: Object obj = itr.next();
2028: if (obj instanceof MUCUserQuery) {
2029: //It is a MUC User query
2030: //XMPPConference c =
2031: // (XMPPConference)_conferences.get(p.getFrom().toBareJID().toString());
2032: if (_conferenceService != null) {
2033: XMPPConference c = _conferenceService
2034: .getConference(p.getFrom().toBareJID()
2035: .toString());
2036: if (c != null)
2037: c.userStatusChange(p);
2038: } else {
2039: XMPPSessionProvider
2040: .debug("MUC packet received - conference service not initialized");
2041: }
2042: return null;
2043: }
2044: }
2045: XMPPSessionProvider
2046: .debug("Calling process presence in presence session");
2047: if (_presenceService != null) {
2048: return _presenceService.processPresence(p);
2049: }
2050: return null;
2051: }
2052:
2053: /**
2054: * accessor method
2055: **/
2056: public Stream getConnection() {
2057: return _connection;
2058: }
2059:
2060: public StreamDataFactory getDataFactory() {
2061: return _sdf;
2062: }
2063:
2064: private XMPPContentStream getContentStream(String sid) {
2065: XMPPContentStream cs = null;
2066: if (_streamingService != null) {
2067: cs = _streamingService.getContentStream(sid);
2068: }
2069: return cs;
2070: }
2071:
2072: private void processInfoQuery(Packet packet) {
2073:
2074: //Should handle error packets: vijay
2075: try {
2076: if (_streamingService != null
2077: && _streamingService.isStreamingPacket(packet)) {
2078: _streamingService.processSIPackets((InfoQuery) packet);
2079: return;
2080: }
2081: //look for IBB and if present then create a hashtable for it
2082: List elements = packet.listElements("open", IBB_NAMESPACE);
2083: if (elements.size() > 0) {
2084: StreamElement ibb = (StreamElement) elements.get(0);
2085: String sid = ibb.getAttributeValue("sid");
2086: if (sid == null)
2087: return;
2088: XMPPContentStream cs = getContentStream(sid);
2089: if (cs != null) {
2090: cs.process(packet);
2091: return;
2092: }
2093: _ibbMessages.put(sid, new ArrayList());
2094: Packet p = _sdf.createPacketNode(packet.getNSI());
2095: p.setID(packet.getID());
2096: p.setType(InfoQuery.RESULT);
2097: p.setFrom(_client.getJID());
2098: JID from = packet.getFrom();
2099: if (_conferenceService != null
2100: && _conferenceService.getConference(from
2101: .toBareJID().toString()) != null) {
2102: p.setTo(from.toBareJID());
2103: } else {
2104: p.setTo(from);
2105: }
2106: //p.setTo(packet.getFrom());
2107: _connection.send(p);
2108: return;
2109: }
2110: elements = packet.listElements("close", IBB_NAMESPACE);
2111: if (elements.size() > 0) {
2112: StreamElement ibb = (StreamElement) elements.get(0);
2113: String sid = ibb.getAttributeValue("sid");
2114: if (sid == null)
2115: return;
2116: XMPPContentStream cs = getContentStream(sid);
2117: if (cs != null) {
2118: cs.process(packet);
2119: return;
2120: }
2121: ArrayList list = (ArrayList) _ibbMessages.get(sid);
2122: if ((list == null) || (list.size() == 0))
2123: return;
2124: Packet p = _sdf.createPacketNode(packet.getNSI());
2125: p.setID(packet.getID());
2126: p.setType(InfoQuery.RESULT);
2127: p.setFrom(_client.getJID());
2128: JID from = packet.getFrom();
2129: if (_conferenceService != null
2130: && _conferenceService.getConference(from
2131: .toBareJID().toString()) != null) {
2132: p.setTo(from.toBareJID());
2133: } else {
2134: p.setTo(from);
2135: }
2136: //p.setTo(packet.getFrom());
2137: _connection.send(p);
2138: //processMessage((Packet)list.get(0), true);
2139: return;
2140: }
2141:
2142: List rqList = packet.listExtensions(RosterQuery.NAMESPACE);
2143: if (rqList.size() > 0) {
2144: if (_personalStoreService != null) {
2145: if (packet.getType() == InfoQuery.RESULT) {
2146: _personalStoreService
2147: .processAsyncRosterQuery((RosterQuery) rqList
2148: .get(0));
2149: } else if (packet.getType() == InfoQuery.SET) {
2150: _personalStoreService
2151: .processRosterQuery((RosterQuery) rqList
2152: .get(0));
2153: }
2154: }
2155: return;
2156: }
2157:
2158: List pqList = packet.listExtensions(PRIVATE_NAMESPACE);
2159: if (pqList.size() > 0) {
2160: if (_personalStoreService != null) {
2161: List sList = ((StreamElement) pqList.get(0))
2162: .listElements(STORAGE_NAME);
2163: if (sList.size() > 0) {
2164: if (packet.getType() == InfoQuery.RESULT) {
2165: _personalStoreService
2166: .processAsyncBookmarkQuery((StreamElement) sList
2167: .get(0));
2168: } else if (packet.getType() == InfoQuery.SET) {
2169: _personalStoreService
2170: .processBookmarkQuery((StreamElement) sList
2171: .get(0));
2172: }
2173: }
2174:
2175: List gList = ((StreamElement) pqList.get(0))
2176: .listElements(SUN_PRIVATE_LDAPGROUP_NAME);
2177: if (gList.size() > 0) {
2178: if (packet.getType() == InfoQuery.RESULT) {
2179: _personalStoreService
2180: .processAsyncLDAPGroupQuery((StreamElement) gList
2181: .get(0));
2182: } else if (packet.getType() == InfoQuery.SET) {
2183: _personalStoreService
2184: .processLDAPGroupQuery((StreamElement) gList
2185: .get(0));
2186: }
2187: }
2188: }
2189: return;
2190: }
2191:
2192: if (packet.getExtension(DiscoInfoQuery.NAMESPACE) != null) {
2193: processDiscoInfoRequest(packet);
2194: return;
2195: } else if (packet.getExtension(DiscoItemsQuery.NAMESPACE) != null) {
2196: processDiscoItemsRequest(packet);
2197: return;
2198: } else if (packet.getExtension(RegisterQuery.NAMESPACE) != null) {
2199: new Thread(new RegisterNotifier((InfoQuery) packet))
2200: .start();
2201: return;
2202: } else if (_regisListeners.containsKey(packet.getID())) {
2203: new Thread(new RegisterNotifier((InfoQuery) packet))
2204: .start();
2205: return;
2206: } else if (isJinglePacket(packet)) {
2207: processJinglePacket(packet);
2208: }
2209:
2210: XMPPContentStream cs = getContentStream(packet.getID());
2211: if (cs != null) {
2212: cs.process(packet);
2213: return;
2214: }
2215:
2216: // NOTE: The check for oob extensions should be done
2217: // only after check for content stream
2218: List oobList = packet
2219: .listExtensions(OutOfBandExtension.IQ_NAMESPACE);
2220: if (oobList.size() > 0 && packet.getType() == InfoQuery.SET) {
2221: if (_streamingService != null) {
2222: //handle oob packets which were not sent using si extensions.
2223: _streamingService
2224: .processSIPackets((InfoQuery) packet);
2225: }
2226: return;
2227: }
2228:
2229: } catch (StreamException se) {
2230: XMPPSessionProvider.error(se.toString(), se);
2231: } catch (CollaborationException ce) {
2232: XMPPSessionProvider.error(ce.toString(), ce);
2233: }
2234:
2235: }
2236:
2237: protected void processMessage(Packet packet) {
2238: AMPExtension amp = (AMPExtension) packet
2239: .getExtension(AMPExtension.NAMESPACE);
2240: if (amp != null) {
2241: try {
2242: XMPPMessage msg = new XMPPMessage(this , packet);
2243: msg.populateMessageProcessingRules((AMPExtension) amp);
2244: int status = MessageStatus.FAILED;
2245: if ((!Packet.ERROR.equals(packet.getType()))
2246: && msg.processingRulesIterator().hasNext()) {
2247: MessageProcessingRule mpr = (MessageProcessingRule) msg
2248: .processingRulesIterator().next();
2249: MessageProcessingRule.Condition c[] = mpr
2250: .getConditions();
2251: if (c != null
2252: && c.length > 0
2253: && c[0] instanceof MessageProcessingRule.DispositionCondition) {
2254: status = ((MessageProcessingRule.DispositionCondition) c[0])
2255: .getMessageStatus();
2256: }
2257: if (MessageProcessingRule.DEFER.equals(mpr
2258: .getAction())) {
2259: status = MessageStatus.DELAYED;
2260: }
2261: }
2262: fireMessageProcessingListener(msg, status,
2263: getCollaborationException(packet.getError(),
2264: null));
2265: } catch (CollaborationException ce) {
2266: XMPPSessionProvider.error(ce.toString(), ce);
2267: }
2268: return;
2269: }
2270: List elements = packet.listElements("data", IBB_NAMESPACE);
2271: if (elements.size() > 0) {
2272: StreamElement ibb = (StreamElement) elements.get(0);
2273: String sid = ibb.getAttributeValue("sid");
2274: if (sid != null) {
2275: XMPPContentStream cs = getContentStream(sid);
2276: if (cs != null) {
2277: cs.process(packet);
2278: return;
2279: }
2280: ArrayList list = (ArrayList) _ibbMessages.get(sid);
2281: //iib open request was not received by the client
2282: if (list == null)
2283: return;
2284: list.add(packet);
2285: _ibbMessages.put(sid, list);
2286: }
2287: return;
2288: }
2289: org.netbeans.lib.collab.Message message;
2290: org.jabberstudio.jso.Message in = (org.jabberstudio.jso.Message) packet;
2291: try {
2292: XMPPSessionProvider.debug("Incoming message type: "
2293: + in.getType());
2294: if (in.getType() == Packet.ERROR) {
2295: XMPPSessionProvider.error("Error message received: "
2296: + in.toString());
2297: } else if (org.jabberstudio.jso.Message.GROUPCHAT.equals(in
2298: .getType())) {
2299: if (_conferenceService != null
2300: && _conferenceService.getConference(in
2301: .getFrom().toBareJID().toString()) != null) {
2302:
2303: XMPPSessionProvider
2304: .debug("[PacketTransferred] : processing groupchat message");
2305: _conferenceService.processGroupChat(in);
2306: } else {
2307: XMPPSessionProvider
2308: .warning("[PacketTransferred] : chat message received as conference service is not initialized - packet is ignored.");
2309: }
2310: } else if (org.jabberstudio.jso.Message.CHAT.equals(in
2311: .getType())) {
2312: XMPPSessionProvider
2313: .debug("[PacketTransferred] : processing chat message");
2314: if (_conferenceService != null) {
2315: if (in
2316: .getExtension(XMPPConference.MODERATION_NAMESPACE) != null
2317: && _conferenceService.getConference(in
2318: .getFrom().toBareJID().toString()) != null) {
2319: XMPPSessionProvider
2320: .debug("[PacketTransferred] : message for moderation");
2321: _conferenceService.processGroupChat(in);
2322: } else {
2323:
2324: _conferenceService.processChat(in);
2325: }
2326: } else {
2327: XMPPSessionProvider
2328: .warning("[PacketTransferred] : chat message received as conference service is not initialized - packet is ignored.");
2329: }
2330: } else if (in.getExtension(MUCUserQuery.NAMESPACE) != null) {
2331: XMPPSessionProvider
2332: .debug("[PacketTransferred] : processing invite message");
2333: if (_conferenceService != null) {
2334: _conferenceService.processInvite(in);
2335: } else {
2336: XMPPSessionProvider
2337: .warning("[PacketTransferred] : chat message received as conference service is not initialized - packet is ignored.");
2338: }
2339:
2340: } else if (in.getExtension(PubSubEvent.NAMESPACE) != null) {
2341: if (_newsService != null) {
2342: _newsService.processNewsMessage(in);
2343: } else {
2344: XMPPSessionProvider
2345: .warning("[PacketTransferred] pubsub packet received as news service is not initialized - packet is ignored.");
2346: }
2347:
2348: } else {
2349: if (_notificationService != null) {
2350: _notificationService.processNormalMessage(in);
2351: } else {
2352: XMPPSessionProvider
2353: .warning("[PacketTransferred] normal messsage packet received as notification service is not initialized - packet is ignored.");
2354: }
2355:
2356: }
2357: } catch (CollaborationException ce) {
2358: XMPPSessionProvider.error(ce.toString(), ce);
2359: }
2360: }
2361:
2362: protected XMPPMessage assembleMessages(XMPPMessage m)
2363: throws CollaborationException {
2364: org.jabberstudio.jso.Message in = (org.jabberstudio.jso.Message) m
2365: .getXMPPMessage();
2366: m.setHeaders(getPropertiesFromPacket(in));
2367: StreamElement attachElem = in.getFirstElement(SUN_ATTACH_NAME);
2368: if (attachElem == null) {
2369: return m;
2370: }
2371: String sid_list = attachElem.normalizeTrimText();
2372: StringTokenizer st = new StringTokenizer(sid_list, ",");
2373: while (st.hasMoreTokens()) {
2374: String sid = st.nextToken();
2375: ArrayList list = (ArrayList) _ibbMessages.get(sid);
2376: if ((list == null) || (list.size() == 0)) {
2377: continue;//there is no data for this sid.
2378: }
2379: MessagePart part = new XMPPMessagePart();
2380: ((XMPPMessagePart) part)
2381: .setHeaders(getPropertiesFromPacket((Packet) list
2382: .get(0)));
2383: StringBuffer contents = new StringBuffer();
2384: for (int i = 0; i < list.size(); i++) {
2385: in = (org.jabberstudio.jso.Message) list.get(i);
2386: List elements = in.listElements("data", IBB_NAMESPACE);
2387: if (elements.size() == 0)
2388: continue;
2389: contents.append(((StreamElement) elements.get(0))
2390: .normalizeText());
2391: }
2392: part.setContent(contents.toString());
2393: m.addPart(part);
2394: _ibbMessages.remove(sid);
2395: }
2396: return m;
2397: }
2398:
2399: private Hashtable getPropertiesFromPacket(Packet in) {
2400: Extension x = in.getExtension(SUN_PRIVATE_NAMESPACE);
2401: if (x == null)
2402: return null;
2403: Hashtable contents = new Hashtable();
2404: for (Iterator itr = x.listElements("property").iterator(); itr
2405: .hasNext();) {
2406: StreamElement propElem = (StreamElement) itr.next();
2407: String name = propElem.getAttributeValue("name");
2408: StreamElement valueElem = (StreamElement) propElem
2409: .getFirstElement("value");
2410: if (valueElem != null) {
2411: contents.put(name, valueElem.normalizeTrimText());
2412: }
2413: }
2414: return contents;
2415: }
2416:
2417: private void processRegisterQuery(InfoQuery iq)
2418: throws CollaborationException {
2419: XMPPRegistrationListenerWrapper regisListenerWrapper = (XMPPRegistrationListenerWrapper) _regisListeners
2420: .get(iq.getID());
2421: JID server = iq.getFrom();
2422: String serverStr = _server.toString();
2423: RegistrationListener regisListener = null;
2424: if (regisListenerWrapper != null) {
2425: regisListener = regisListenerWrapper.getRegisListener();
2426: } else {
2427: //return;
2428: throw new CollaborationException(
2429: "registration response out of sync");
2430: }
2431: XMPPRegistrationListenerWrapper.RequestType reqType = regisListenerWrapper
2432: .getRequestType();
2433: if (server != null) {
2434: serverStr = server.toString();
2435: }
2436:
2437: /*
2438:
2439: if (iq.getType() == InfoQuery.ERROR) {
2440: XMPPSessionProvider.debug("Error in registration");
2441: PacketError pe = iq.getError();
2442: if (pe != null) {
2443: if (XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE.equals(reqType)) {
2444: regisListener.registrationUpdateFailed(pe.getDefinedCondition(), pe.getText(), serverStr);
2445: } else if (XMPPRegistrationListenerWrapper.GATEWAY_UNREGISTRATION.equals(reqType) ||
2446: XMPPRegistrationListenerWrapper.USER_UNREGISTRATION.equals(reqType)){
2447: regisListener.unregistrationFailed(getRegistrationErrorCondition(pe.getDefinedCondition()),
2448: pe.getText(), serverStr);
2449: } else if (XMPPRegistrationListenerWrapper.GATEWAY_REGISTRATION.equals(reqType) ||
2450: XMPPRegistrationListenerWrapper.USER_REGISTRATION.equals(reqType)) {
2451: regisListener.registrationFailed(getRegistrationErrorCondition(pe.getDefinedCondition()),
2452: pe.getText(), serverStr);
2453: }
2454: } else {
2455: XMPPSessionProvider.debug("Packet error is null");
2456: }
2457: _regisListeners.remove(iq.getID());
2458: return;
2459: }
2460: */
2461:
2462: RegisterQuery registerQuery = (RegisterQuery) iq
2463: .getExtension(RegisterQuery.NAMESPACE);
2464:
2465: if (registerQuery != null
2466: && registerQuery.listElements().size() > 0) {
2467: processRegisterResponse(iq, registerQuery,
2468: regisListenerWrapper, serverStr);
2469: /*
2470: if (iq.getType() == InfoQuery.RESULT && registerQuery != null) {
2471: if (registerQuery.isRegistered()) {
2472:
2473: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION.equals(reqType)) {
2474: regisListener.registered(serverStr);
2475: return;
2476: }
2477: // it is a gateway re-registration
2478: }
2479: keyValue = registerQuery.getKey();
2480: registerQuery.clearKey();
2481: Set fields = registerQuery.getFieldNames();
2482:
2483: Map fieldValuePairs = new HashMap();
2484: for (Iterator iter = fields.iterator(); iter.hasNext();) {
2485: String fieldName = (String)iter.next();
2486: fieldValuePairs.put(fieldName, registerQuery.getField(fieldName)); // put the value also if any
2487: }
2488: boolean filled = regisListener.fillRegistrationInformation(fieldValuePairs,
2489: serverStr);
2490: if (!filled) {
2491: // do not do anything
2492: return;
2493: } else {
2494: String userName = (String)fieldValuePairs.get(RegistrationListener.USERNAME);
2495: String password = (String)fieldValuePairs.get(RegistrationListener.PASSWORD);
2496: if (userName == null || userName.equals("") || password == null
2497: || password.equals("")) {
2498: regisListener.registrationFailed(RegistrationListener.MISSING_DATA, "Empty username or password is not allowed",
2499: serverStr);
2500: logout();
2501: return;
2502: }
2503: }
2504:
2505: if (iq.getFrom() != null) {
2506: sendRegistration(iq.getFrom(), fieldValuePairs, iq.getID());
2507: } else {
2508: sendRegistration(_server, fieldValuePairs, iq.getID());
2509: }
2510: }
2511: */
2512: } else {
2513: processRegisSuccessFailure(iq, regisListenerWrapper,
2514: serverStr);
2515:
2516: /*
2517: if (iq.getType() == InfoQuery.RESULT) {
2518:
2519: */
2520:
2521: /*
2522: JID sender = packet.getFrom();
2523: String senderServer = _server.toString();
2524: if (sender != null) {
2525: senderServer = sender.toString();
2526: }
2527: if (!senderServer.equalsIgnoreCase(_server.toString())) { */
2528:
2529: /*
2530: if (XMPPRegistrationListenerWrapper.GATEWAY_REGISTRATION.equals(reqType)) {
2531: postGatewayRegistration(serverStr);
2532: regisListener.registered(serverStr);
2533: } else if (XMPPRegistrationListenerWrapper.USER_REGISTRATION.equals(reqType)) {
2534: regisListener.registered(serverStr);
2535: logout();
2536: } else if (XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE.equals(reqType)) {
2537: regisListener.registrationUpdated(serverStr);
2538: } else if (XMPPRegistrationListenerWrapper.GATEWAY_UNREGISTRATION.equals(reqType)) {
2539: postGatewayUnregistration(serverStr);
2540: regisListener.unregistered(serverStr);
2541: } else if (XMPPRegistrationListenerWrapper.USER_UNREGISTRATION.equals(reqType)) {
2542: regisListener.unregistered(serverStr);
2543: }
2544: _regisListeners.remove(packet.getID());
2545:
2546: } else if (iq.getType() == InfoQuery.ERROR) {
2547: XMPPSessionProvider.debug("Error in registration");
2548: PacketError pe = packet.getError();
2549:
2550: if (pe != null) {
2551: if (XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE.equals(reqType)) {
2552: regisListener.registrationUpdateFailed(pe.getDefinedCondition(), pe.getText(), serverStr);
2553: } else if (XMPPRegistrationListenerWrapper.GATEWAY_UNREGISTRATION.equals(reqType) ||
2554: XMPPRegistrationListenerWrapper.USER_UNREGISTRATION.equals(reqType)){
2555: regisListener.unregistrationFailed(getRegistrationErrorCondition(pe.getDefinedCondition()),
2556: pe.getText(), serverStr);
2557: } else if (XMPPRegistrationListenerWrapper.GATEWAY_REGISTRATION.equals(reqType) ||
2558: XMPPRegistrationListenerWrapper.USER_REGISTRATION.equals(reqType)) {
2559: regisListener.registrationFailed(getRegistrationErrorCondition(pe.getDefinedCondition()),
2560: pe.getText(), serverStr);
2561: }
2562: } else {
2563: XMPPSessionProvider.debug("Packet error is null");
2564: }
2565: _regisListeners.remove(iq.getID());
2566: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION.equals(reqType)) {
2567: logout();
2568: }
2569: return;
2570: }
2571: */
2572: }
2573:
2574: }
2575:
2576: private String getRegistrationErrorCondition(String condition) {
2577: if (PacketError.CONFLICT_CONDITION.equals(condition)) {
2578: return RegistrationListener.ALREADY_REGISTERED;
2579: } else if ((PacketError.NOT_AUTHORIZED_CONDITION
2580: .equals(condition))
2581: || (PacketError.FORBIDDEN_CONDITION.equals(condition))) {
2582: return RegistrationListener.NOT_AUTHORIZED;
2583: } else if ((PacketError.NOT_ACCEPTABLE_CONDITION
2584: .equals(condition))
2585: || (PacketError.BAD_REQUEST_CONDITION.equals(condition))) {
2586: return RegistrationListener.MISSING_DATA;
2587: } else if (PacketError.REGISTRATION_REQUIRED_CONDITION
2588: .equals(condition)) {
2589: return RegistrationListener.NOT_REGISTERED;
2590: } else if ((PacketError.FEATURE_NOT_IMPLEMENTED_CONDITION
2591: .equals(condition))
2592: || (PacketError.UNEXPECTED_REQUEST_CONDITION
2593: .equals(condition))
2594: || (PacketError.NOT_ALLOWED_CONDITION.equals(condition))) {
2595: return RegistrationListener.SERVICE_UNAVAILABLE;
2596: }
2597: return RegistrationListener.UNKNOWN_ERROR_CONDITION;
2598: }
2599:
2600: public static String access2Affiliation(int access) {
2601: String affiliation = null;
2602: if (access <= 0) {
2603: affiliation = "none";
2604: } else if (access < Conference.LISTEN) {
2605: affiliation = "outcast";
2606: } else if (access < Conference.PUBLISH) {
2607: affiliation = "none";
2608: } else if (access < Conference.MANAGE) {
2609: affiliation = "publisher";
2610: } else {
2611: affiliation = "owner";
2612: }
2613: return affiliation;
2614: }
2615:
2616: public static int affiliation2Access(String affiliation) {
2617: int access = 0;
2618: int defaultAccess = Conference.NONE;
2619:
2620: if (affiliation == null) {
2621: access = defaultAccess;
2622: } else if (affiliation.equals("outcast")) {
2623: access = Conference.NONE;
2624: } else if (affiliation.equals("publisher")) {
2625: access = Conference.PUBLISH | Conference.LISTEN
2626: | Conference.INVITE;
2627: } else if (affiliation.equals("owner")) {
2628: access = Conference.PUBLISH | Conference.LISTEN
2629: | Conference.INVITE | Conference.MANAGE;
2630: } else if (affiliation.equals("none")) {
2631: // assume read as the access
2632: access = Conference.LISTEN;
2633: /*
2634: if (getPublishModel().equals("open")) {
2635: access = AccessControlItem.WRITE;
2636: } else {
2637: access = AccessControlItem.READ;
2638: }
2639: */
2640: }
2641: return access;
2642: }
2643:
2644: public void addConference(XMPPConference c) {
2645: _conferenceService.addConference(c);
2646: }
2647:
2648: public void removeConference(String str) {
2649: _conferenceService.removeConference(str);
2650: }
2651:
2652: public void addRemoteServices(Set set) {
2653: if (!set.isEmpty())
2654: this ._remoteServices.addAll(set);
2655: }
2656:
2657: public void register(String serviceURL,
2658: XMPPRegistrationListenerWrapper listener)
2659: throws CollaborationException {
2660: JID dest = null;
2661:
2662: if (null != serviceURL) {
2663: int indx = serviceURL.indexOf(':');
2664: if (-1 != indx) {
2665: serviceURL = serviceURL.substring(0, indx);
2666: }
2667: dest = new JID(serviceURL);
2668: }
2669: if (null == dest && null != _client && null != _client.getJID()) {
2670: dest = new JID("", _client.getJID().getDomain(), "");
2671: }
2672: getRegistrationFields(dest, listener);
2673: }
2674:
2675: public void changePassword(String password,
2676: RegistrationListener listener)
2677: throws CollaborationException {
2678: XMPPRegistrationListenerWrapper regisListenerWrapper = new XMPPRegistrationListenerWrapper(
2679: listener);
2680: regisListenerWrapper
2681: .setRequestType(XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE);
2682: InfoQuery iqQuery = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
2683: InfoQuery.class);
2684: iqQuery.setTo(_server);
2685: iqQuery.setType(InfoQuery.SET);
2686: iqQuery.setID(nextID("register"));
2687: XMPPRegistrationListenerWrapper regisListener = new XMPPRegistrationListenerWrapper(
2688: listener);
2689: _regisListeners.put(iqQuery.getID(), regisListenerWrapper);
2690: RegisterQuery rQuery = (RegisterQuery) _sdf
2691: .createExtensionNode(RegisterQuery.NAME,
2692: RegisterQuery.class);
2693: rQuery.setUsername(getPrincipal().getName());
2694: rQuery.setPassword(password);
2695: iqQuery.addExtension(rQuery);
2696:
2697: try {
2698: _connection.send(iqQuery);
2699: } catch (StreamException se) {
2700: throw new CollaborationException(se.getMessage());
2701: }
2702: }
2703:
2704: void getRegistrationFields(JID recipient,
2705: XMPPRegistrationListenerWrapper listener)
2706: throws CollaborationException {
2707: InfoQuery iqQuery = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
2708: InfoQuery.class);
2709:
2710: iqQuery.setTo(recipient);
2711: iqQuery.setType(InfoQuery.GET);
2712: iqQuery.setID(nextID("register"));
2713: _regisListeners.put(iqQuery.getID(), listener);
2714:
2715: RegisterQuery rQuery = (RegisterQuery) _sdf
2716: .createExtensionNode(_sdf.createNSI("query",
2717: "jabber:iq:register"), RegisterQuery.class);
2718: if (rQuery == null) {
2719: }
2720: iqQuery.addExtension(rQuery);
2721:
2722: try {
2723: _connection.send(iqQuery);
2724: } catch (StreamException se) {
2725: throw new CollaborationException(se.getMessage());
2726: }
2727:
2728: }
2729:
2730: void sendRegistration(JID jid, Map values, String ID)
2731: throws CollaborationException {
2732:
2733: XMPPRegistrationListenerWrapper regisListener = (XMPPRegistrationListenerWrapper) _regisListeners
2734: .get(ID);
2735: InfoQuery iqQuery = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
2736: InfoQuery.class);
2737: iqQuery.setTo(jid);
2738: iqQuery.setType(InfoQuery.SET);
2739: iqQuery.setID(nextID("register"));
2740: _regisListeners.remove(ID);
2741: _regisListeners.put(iqQuery.getID(), regisListener);
2742: RegisterQuery rQuery = (RegisterQuery) _sdf
2743: .createExtensionNode(RegisterQuery.NAME,
2744: RegisterQuery.class);
2745:
2746: if (keyValue != null) {
2747: values.put("key", keyValue);
2748: }
2749:
2750: for (Iterator i = values.keySet().iterator(); i.hasNext();) {
2751: String fieldName = (String) i.next();
2752: rQuery.setField(fieldName, (String) values.get(fieldName));
2753: }
2754: iqQuery.addExtension(rQuery);
2755:
2756: try {
2757: // _connection.send(iqQuery);
2758: // sendAndWatch is required as the subscribe after the registration is
2759: // reaching before registration is completed.
2760: /*
2761: InfoQuery iq = (InfoQuery)ReqRespMEP.sendAndWatch(this, iqQuery);
2762: if ((iq == null) || (iq.getType() != InfoQuery.RESULT)) {
2763: throw new CollaborationException("Could not register to the server");
2764: }
2765: */
2766: _connection.send(iqQuery);
2767:
2768: } catch (StreamException se) {
2769: throw new CollaborationException(se.getMessage());
2770: } finally {
2771: keyValue = null;
2772: }
2773:
2774: }
2775:
2776: public void unregister(RegistrationListener listener)
2777: throws CollaborationException {
2778: XMPPRegistrationListenerWrapper regisListenerWrapper = new XMPPRegistrationListenerWrapper(
2779: listener);
2780: regisListenerWrapper
2781: .setRequestType(XMPPRegistrationListenerWrapper.USER_UNREGISTRATION);
2782: unregister(_server, regisListenerWrapper);
2783: }
2784:
2785: void unregister(JID recipient,
2786: XMPPRegistrationListenerWrapper regisListener)
2787: throws CollaborationException {
2788: InfoQuery iqQuery = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
2789: InfoQuery.class);
2790:
2791: iqQuery.setTo(recipient);
2792: iqQuery.setType(InfoQuery.SET);
2793: iqQuery.setID(nextID("unregister"));
2794: _regisListeners.put(iqQuery.getID(), regisListener);
2795:
2796: RegisterQuery rQuery = (RegisterQuery) _sdf
2797: .createExtensionNode(RegisterQuery.NAME,
2798: RegisterQuery.class);
2799: rQuery.setRemove(true);
2800: iqQuery.addExtension(rQuery);
2801:
2802: try {
2803: _connection.send(iqQuery);
2804: } catch (StreamException se) {
2805: throw new CollaborationException(se.getMessage());
2806: }
2807: // TODO delete all the legacy accounts of the corresponding legacy Service.
2808: }
2809:
2810: protected XMPPConference getConference(String id) {
2811: return _conferenceService.getConference(id);
2812: }
2813:
2814: private void postGatewayRegistration(String senderServer)
2815: throws CollaborationException {
2816: _presenceService.subscribe(senderServer);
2817: // Not sure how to get rid of this extra search
2818: // One approach could be to save the PersonalStoreGateway entry in the
2819: // RegistrationListener
2820: /*
2821: PersonalStoreEntry[] gwlist =
2822: _personalStoreSession.search(PersonalStoreSession.SEARCHTYPE_CONTAINS,
2823: "*", PersonalStoreEntry.GATEWAY);
2824: PersonalStoreEntry gw = null;
2825: for (int i = 0; i < gwlist.length; i++) {
2826: if (gwlist[i].getEntryId().equals(senderServer)) {
2827: gw = gwlist[i];
2828: break;
2829: }
2830: }
2831: */
2832:
2833: PersonalGateway gw = _personalStoreService
2834: .getGatewayEntry(senderServer);
2835:
2836: PersonalStoreFolder folder = (PersonalStoreFolder) _personalStoreService
2837: .getEntry(PersonalStoreEntry.CONTACT_FOLDER,
2838: XMPPPersonalGateway.GATEWAY_FOLDER);
2839: if (folder == null) {
2840: folder = (PersonalStoreFolder) _personalStoreService
2841: .createEntry(PersonalStoreEntry.CONTACT_FOLDER,
2842: XMPPPersonalGateway.GATEWAY_FOLDER);
2843: folder.save();
2844: }
2845: if (gw != null) {
2846: gw.addToFolder(folder);
2847: gw.save();
2848: }
2849:
2850: }
2851:
2852: private void postGatewayUnregistration(String gatewayJID)
2853: throws CollaborationException {
2854: // remove all the legacy users from the roster
2855: for (Iterator i = _personalStoreService.getEntries(
2856: PersonalStoreEntry.CONTACT).iterator(); i.hasNext();) {
2857: PersonalContact pc = (PersonalContact) i.next();
2858: String domain = pc.getPrincipal().getDomainName();
2859: if (domain != null && domain.equalsIgnoreCase(gatewayJID)) {
2860: pc.remove();
2861: }
2862: }
2863: }
2864:
2865: /**
2866: * @return PrivacyList
2867: *
2868: */
2869: public org.netbeans.lib.collab.PrivacyList getPrivacyList(
2870: String name) throws CollaborationException {
2871: PrivacyQuery pq = getPrivacyQueryResult(name);
2872: if (pq == null) {
2873: return null;
2874: }
2875: org.jabberstudio.jso.x.core.PrivacyList xmppPL = pq
2876: .getPrivacyList(name);
2877:
2878: if (xmppPL == null) {
2879: return null;
2880: }
2881: org.netbeans.lib.collab.PrivacyList list = new XMPPPrivacyList(
2882: name);
2883: Iterator itr = xmppPL.listElements().iterator();
2884: while (itr.hasNext()) {
2885: addPrivacyItemToList(list,
2886: (org.jabberstudio.jso.x.core.PrivacyItem) itr
2887: .next());
2888: }
2889: return list;
2890: }
2891:
2892: private void addPrivacyItemToList(
2893: org.netbeans.lib.collab.PrivacyList list,
2894: org.jabberstudio.jso.x.core.PrivacyItem xmppItem)
2895: throws CollaborationException {
2896: org.netbeans.lib.collab.PrivacyItem item = new XMPPPrivacyItem();
2897: if (xmppItem.getAction().equals(
2898: org.jabberstudio.jso.x.core.PrivacyItem.ALLOW)) {
2899: item.setAccess(org.netbeans.lib.collab.PrivacyItem.ALLOW);
2900: } else {
2901: item.setAccess(org.netbeans.lib.collab.PrivacyItem.DENY);
2902: }
2903: String subject = null;
2904: if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.SUBSCRIPTION) {
2905: item
2906: .setType(org.netbeans.lib.collab.PrivacyItem.TYPE_SUBSCRIPTION);
2907: subject = xmppItem.getValue();
2908: } else if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.GROUP) {
2909: item
2910: .setType(org.netbeans.lib.collab.PrivacyItem.TYPE_GROUP);
2911: subject = xmppItem.getValue();
2912: } else if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.JID) {
2913: item
2914: .setType(org.netbeans.lib.collab.PrivacyItem.TYPE_IDENTITIES);
2915: subject = JIDUtil.decodedJID(xmppItem.getValue());
2916: }
2917:
2918: item.setSubject(subject);
2919: boolean resourcePresent = false;
2920: if (xmppItem.isAppliedToPresenceIn()) {
2921: resourcePresent = true;
2922: item
2923: .setResource(org.netbeans.lib.collab.PrivacyItem.PRESENCE_IN);
2924: list.addPrivacyItem(item);
2925: }
2926: if (xmppItem.isAppliedToPresenceOut()) {
2927: resourcePresent = true;
2928: item
2929: .setResource(org.netbeans.lib.collab.PrivacyItem.PRESENCE_OUT);
2930: list.addPrivacyItem(item);
2931: }
2932: if (xmppItem.isAppliedToMessage()) {
2933: resourcePresent = true;
2934: item
2935: .setResource(org.netbeans.lib.collab.PrivacyItem.MESSAGE);
2936: list.addPrivacyItem(item);
2937: }
2938: if (xmppItem.isAppliedToIQ()) {
2939: resourcePresent = true;
2940: item.setResource(org.netbeans.lib.collab.PrivacyItem.IQ);
2941: list.addPrivacyItem(item);
2942: }
2943: if (!resourcePresent) {
2944: list.addPrivacyItem(item);
2945: }
2946: }
2947:
2948: /**
2949: * @param lst sets this users privacy list
2950: *
2951: */
2952: public void addPrivacyList(org.netbeans.lib.collab.PrivacyList lst)
2953: throws CollaborationException {
2954: //PrivacyListNode list = new PrivacyListNode(_sdf);
2955: org.jabberstudio.jso.x.core.PrivacyList list = (org.jabberstudio.jso.x.core.PrivacyList) _sdf
2956: .createElementNode(
2957: org.jabberstudio.jso.x.core.PrivacyList.NAME,
2958: org.jabberstudio.jso.x.core.PrivacyList.class);
2959: ((net.outer_planes.jso.x.core.PrivacyListNode) list)
2960: .setName(lst.getName());
2961:
2962: int order = 0;
2963: Collection c = lst.getPrivacyItems();
2964: for (Iterator itr = c.iterator(); itr.hasNext();) {
2965: org.netbeans.lib.collab.PrivacyItem pi = (org.netbeans.lib.collab.PrivacyItem) itr
2966: .next();
2967: org.jabberstudio.jso.x.core.PrivacyItem item = null;
2968: if (pi.getAccess() == org.netbeans.lib.collab.PrivacyItem.ALLOW) {
2969: item = list.addItem(
2970: org.jabberstudio.jso.x.core.PrivacyItem.ALLOW,
2971: order);
2972: } else if (pi.getAccess() == org.netbeans.lib.collab.PrivacyItem.DENY) {
2973: item = list.addItem(
2974: org.jabberstudio.jso.x.core.PrivacyItem.DENY,
2975: order);
2976: }
2977:
2978: String subject = null;
2979: if (org.netbeans.lib.collab.PrivacyItem.TYPE_SUBSCRIPTION
2980: .equals(pi.getType())) {
2981: item
2982: .setType(org.jabberstudio.jso.x.core.PrivacyItem.SUBSCRIPTION);
2983: subject = pi.getSubject();
2984: } else if (org.netbeans.lib.collab.PrivacyItem.TYPE_GROUP
2985: .equals(pi.getType())) {
2986: item
2987: .setType(org.jabberstudio.jso.x.core.PrivacyItem.GROUP);
2988: subject = pi.getSubject();
2989: } else if (org.netbeans.lib.collab.PrivacyItem.TYPE_IDENTITIES
2990: .equals(pi.getType())) {
2991: item
2992: .setType(org.jabberstudio.jso.x.core.PrivacyItem.JID);
2993: //should encode and send the value
2994: subject = JIDUtil.encodedJID(pi.getSubject())
2995: .toString();
2996: }
2997: item.setValue(subject);
2998: setItemResource(pi, item);
2999: order++;
3000: }
3001: setPrivacyQuery(list, null, null);
3002: }
3003:
3004: public List listPrivacyLists() throws CollaborationException {
3005:
3006: //XMPPSessionProvider.debug(com.iplanet.im.client.manager.Manager.getStackTrace());
3007:
3008: PrivacyQuery pq = getPrivacyQueryResult(null);
3009:
3010: //mark it as privacy lists have been listed once
3011: privacyListsListed = true;
3012:
3013: // set the default and active lists
3014: _activePrivacyList = pq.getActive();
3015: _defaultPrivacyList = pq.getDefault();
3016: List l = pq.listPrivacyLists();
3017: List ret = new ArrayList();
3018: for (Iterator i = l.iterator(); i.hasNext();) {
3019: org.jabberstudio.jso.x.core.PrivacyList pl = (org.jabberstudio.jso.x.core.PrivacyList) i
3020: .next();
3021: String name = pl.getName();
3022: // make the local cache consistent using the list of privacylists
3023: ret.add(name);
3024: }
3025: return ret;
3026: }
3027:
3028: public void removePrivacyList(String name)
3029: throws CollaborationException {
3030: if (name.equals(_defaultPrivacyList)) {
3031: _defaultPrivacyList = null;
3032: }
3033: if (name.equals(_activePrivacyList)) {
3034: _activePrivacyList = null;
3035: }
3036: net.outer_planes.jso.x.core.PrivacyListNode list = new net.outer_planes.jso.x.core.PrivacyListNode(
3037: _sdf);
3038: list.setName(name);
3039: setPrivacyQuery(list, null, null);
3040: }
3041:
3042: protected PrivacyQuery getPrivacyQueryResult(String listName)
3043: throws CollaborationException {
3044: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3045: InfoQuery.class);
3046: iq.setType(InfoQuery.GET);
3047: iq.setID(nextID("privacy"));
3048:
3049: org.jabberstudio.jso.x.core.PrivacyQuery node = (org.jabberstudio.jso.x.core.PrivacyQuery) _sdf
3050: .createExtensionNode(
3051: org.jabberstudio.jso.x.core.PrivacyQuery.NAME,
3052: org.jabberstudio.jso.x.core.PrivacyQuery.class);
3053:
3054: if (listName != null) {
3055: node.addPrivacyList(listName);
3056: }
3057:
3058: iq.add(node);
3059: try {
3060: iq = (InfoQuery) sendAndWatch(iq, getRequestTimeout());
3061: } catch (StreamException se) {
3062: //se.printStackTrace();
3063: }
3064: if (iq == null) {
3065: throw new TimeoutException(
3066: "Timeout while getting the privacy list from server!");
3067: } else if (iq.getType() == InfoQuery.RESULT) {
3068: return (PrivacyQuery) iq.listExtensions(
3069: PrivacyQuery.NAMESPACE).get(0);
3070: } else if (iq.getType() == InfoQuery.ERROR) {
3071: PacketError error = iq.getError();
3072: if ((error != null)
3073: && PacketError.ITEM_NOT_FOUND_CONDITION
3074: .equals(error.getDefinedCondition())) {
3075: return null;
3076: }
3077: }
3078: throw new CollaborationException(
3079: "Could not get the privacy list from server!");
3080: }
3081:
3082: private void setPrivacyQuery(
3083: org.jabberstudio.jso.x.core.PrivacyList list,
3084: String active, String def) throws CollaborationException {
3085: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3086: InfoQuery.class);
3087: org.jabberstudio.jso.x.core.PrivacyQuery node = (org.jabberstudio.jso.x.core.PrivacyQuery) _sdf
3088: .createExtensionNode(
3089: org.jabberstudio.jso.x.core.PrivacyQuery.NAME,
3090: org.jabberstudio.jso.x.core.PrivacyQuery.class);
3091:
3092: if (list != null) {
3093: node.add(list);
3094: node.addPrivacyList(list.getName());
3095: }
3096: sendPrivacyQuery(iq, node);
3097: }
3098:
3099: private void sendPrivacyQuery(InfoQuery iq, PrivacyQuery node)
3100: throws CollaborationException {
3101: iq.addExtension(node);
3102: iq.setType(InfoQuery.SET);
3103: iq.setFrom(_client.getJID());
3104: iq.setID(nextID("privacy"));
3105: try {
3106: InfoQuery response = (InfoQuery) sendAndWatch(iq,
3107: getShortRequestTimeout());
3108: if (null == response) {
3109: throw new TimeoutException("No reply from server");
3110: } else if (InfoQuery.ERROR.equals(response.getType())) {
3111: throw new CollaborationException(response.getError()
3112: .getText());
3113: }
3114: } catch (StreamException se) {
3115: throw new CollaborationException(se.getMessage());
3116: }
3117: }
3118:
3119: public org.netbeans.lib.collab.PrivacyList createPrivacyList(
3120: String name) throws CollaborationException {
3121: return new XMPPPrivacyList(name);
3122: }
3123:
3124: /**
3125: * gets this users default privacy list
3126: * @return Name of the Privacy List
3127: *
3128: */
3129: public String getDefaultPrivacyListName()
3130: throws CollaborationException {
3131: // return it from the cache if there is one
3132: // this might cause cache consistency issues
3133: // in case of multiple resources/sessions
3134: if (_defaultPrivacyList == null) {
3135: _defaultPrivacyList = getPrivacyQueryResult(null)
3136: .getDefault();
3137: }
3138: return _defaultPrivacyList;
3139: }
3140:
3141: /**
3142: * sets this users default privacy list
3143: * @param name Name of the Privacy List
3144: *
3145: */
3146: public void setDefaultPrivacyListName(String name)
3147: throws CollaborationException {
3148: _defaultPrivacyList = name;
3149: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3150: InfoQuery.class);
3151: org.jabberstudio.jso.x.core.PrivacyQuery node = (org.jabberstudio.jso.x.core.PrivacyQuery) _sdf
3152: .createExtensionNode(
3153: org.jabberstudio.jso.x.core.PrivacyQuery.NAME,
3154: org.jabberstudio.jso.x.core.PrivacyQuery.class);
3155: if (name == null) {
3156: node.addElement("default");
3157: } else {
3158: node.setDefault(name);
3159: }
3160: //node.setDefault(_defaultPrivacyList);
3161: sendPrivacyQuery(iq, node);
3162: }
3163:
3164: /**
3165: * gets this users active privacy list
3166: * @return name Name of the PrivacyList
3167: *
3168: */
3169:
3170: public String getActivePrivacyListName()
3171: throws CollaborationException {
3172: // return it from the cache if there is one
3173: // this might cause cache consistency issues
3174: // in case of multiple resources/sessions
3175: if (_activePrivacyList == null && !privacyListsListed) {
3176: _activePrivacyList = getPrivacyQueryResult(null)
3177: .getActive();
3178: }
3179: return _activePrivacyList;
3180: }
3181:
3182: /**
3183: * sets this users active privacy list
3184: * @param name Name of the PrivacyList
3185: *
3186: */
3187: public void setActivePrivacyListName(String name)
3188: throws CollaborationException {
3189: _activePrivacyList = name;
3190: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3191: InfoQuery.class);
3192: org.jabberstudio.jso.x.core.PrivacyQuery node = (org.jabberstudio.jso.x.core.PrivacyQuery) _sdf
3193: .createExtensionNode(
3194: org.jabberstudio.jso.x.core.PrivacyQuery.NAME,
3195: org.jabberstudio.jso.x.core.PrivacyQuery.class);
3196: //node.setActive(name);
3197: if (name == null) {
3198: node.addElement("active");
3199: } else {
3200: node.setActive(name);
3201: }
3202: sendPrivacyQuery(iq, node);
3203: }
3204:
3205: /*protected void processPrivacyQuery(PrivacyQuery query) {
3206: List l = query.listPrivacyLists();
3207: for(Iterator i = l.iterator(); i.hasNext();) {
3208: org.jabberstudio.jso.x.core.PrivacyList list =
3209: (org.jabberstudio.jso.x.core.PrivacyList)i.next();
3210: List itemList = list.listItems();
3211: for(Iterator j = itemList.iterator(); j.hasNext();) {
3212: org.jabberstudio.jso.x.core.PrivacyItem item =
3213: (org.jabberstudio.jso.x.core.PrivacyItem)j.next();
3214: }
3215: }
3216: }*/
3217:
3218: private void setItemResource(
3219: org.netbeans.lib.collab.PrivacyItem pi,
3220: org.jabberstudio.jso.x.core.PrivacyItem item) {
3221: switch (pi.getResource()) {
3222: case org.netbeans.lib.collab.PrivacyItem.PRESENCE_IN:
3223: /*if (pi[i].getAccess() == org.netbeans.lib.collab.PrivacyItem.ALLOW)
3224: */
3225: item.setAppliedToPresenceIn(true);
3226: /*
3227: else
3228: item.setAppliedToPresenceIn(false);
3229: */
3230: break;
3231: case org.netbeans.lib.collab.PrivacyItem.PRESENCE_OUT:
3232: //if (pi[i].getAccess() == org.netbeans.lib.collab.PrivacyItem.ALLOW)
3233: item.setAppliedToPresenceOut(true);
3234: /*
3235: else
3236: item.setAppliedToPresenceOut(false);
3237: */
3238: break;
3239: case org.netbeans.lib.collab.PrivacyItem.MESSAGE:
3240: //if (pi[i].getAccess() == org.netbeans.lib.collab.PrivacyItem.ALLOW)
3241: item.setAppliedToMessage(true);
3242: /*
3243: else
3244: item.setAppliedToMessage(false);
3245: */
3246: break;
3247: }
3248: }
3249:
3250: /*private org.netbeans.lib.collab.PrivacyItem getPrivacyItem(StringBuffer id,
3251: Hashtable ht,
3252: org.jabberstudio.jso.x.core.PrivacyItem xmppItem)
3253: {
3254: org.netbeans.lib.collab.PrivacyItem item =
3255: (org.netbeans.lib.collab.PrivacyItem)ht.get(id.toString());
3256: if (item == null) {
3257: int access;
3258: if (xmppItem.getAction().equals(org.jabberstudio.jso.x.core.PrivacyItem.ALLOW)) {
3259: access = org.netbeans.lib.collab.PrivacyItem.ALLOW;
3260: } else {
3261: access = org.netbeans.lib.collab.PrivacyItem.DENY;
3262: }
3263: String type = null;
3264: if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.SUBSCRIPTION) {
3265: type = org.netbeans.lib.collab.PrivacyItem.TYPE_SUBSCRIPTION;
3266: } else if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.GROUP) {
3267: type = org.netbeans.lib.collab.PrivacyItem.TYPE_GROUP;
3268: } else if (xmppItem.getType() == org.jabberstudio.jso.x.core.PrivacyItem.JID) {
3269: type = org.netbeans.lib.collab.PrivacyItem.TYPE_IDENTITIES;
3270: }
3271: item = new org.netbeans.lib.collab.PrivacyItem(type, access);
3272:
3273: ht.put(id.toString(), item);
3274: }
3275: return item;
3276: }*/
3277:
3278: synchronized void addSendAndWatchID(String id) {
3279: if (null == id) {
3280: return;
3281: }
3282: _sendAndWatchIDs.put(id, id);
3283: if (null != inboundSendAndWatch.get(id)) {
3284: // This should not happen - debug statement.
3285: // Our id generation gaurentee's uniqueness for a box ...
3286: xmpplogger.debug("addSendAndWatchID for id : " + id
3287: + " which is already in c !");
3288: inboundSendAndWatch.remove(id);
3289: }
3290: }
3291:
3292: synchronized void forceRemoveSendAndWatch(String id) {
3293: _sendAndWatchIDs.remove(id);
3294: inboundSendAndWatch.remove(id);
3295: }
3296:
3297: synchronized boolean isSendAndWatchIDRecievedOnce(String id) {
3298: boolean retval = null == id ||
3299: // not in sendAndWatch list !
3300: null == _sendAndWatchIDs.get(id) ||
3301: // Has it been recieved at least once ?
3302: null != inboundSendAndWatch.get(id);
3303:
3304: return retval;
3305: }
3306:
3307: synchronized boolean removeSendAndWatchID(
3308: final org.jabberstudio.jso.Packet packet) {
3309: String id = packet.getID();
3310:
3311: if (null == id) {
3312: return false;
3313: }
3314:
3315: // This is handleed below.
3316: /*
3317: if (packet instanceof InfoQuery){
3318: InfoQuery iq = (InfoQuery)packet;
3319: if (iq.getType() == InfoQuery.GET ||
3320: iq.getType() == InfoQuery.SET){
3321: // Should be a inbound request ... ignore.
3322:
3323: if (null != inboundSendAndWatch.get(id)){
3324: // interesting ! bug ?!
3325: xmpplogger.debug("removeSendAndWatchID for id : " + id +
3326: " coming in multiple times ! packet : " + packet);
3327: }
3328: inboundSendAndWatch.put(id , id);
3329: return false;
3330: }
3331: }
3332: */
3333:
3334: if (null == packet.getFrom()
3335: || null == _client
3336: || null == _client.getJID()
3337: || !packet.getFrom().toBareJID().equals(
3338: _client.getJID().toBareJID()) ||
3339: // We have already had this dispatched to us once !
3340: null != inboundSendAndWatch.get(id)) {
3341: inboundSendAndWatch.remove(id);
3342: return null != _sendAndWatchIDs.remove(id);
3343: }
3344:
3345: if (null != _sendAndWatchIDs.get(id)) {
3346: // This is a packet which is getting dispatched back to us.
3347: // We sent this packet , and we are the reciepent of this
3348: // packet while we are doing a sendAndWatch over it - so expecting a
3349: // response back from ourself - ya , I know this sounds backward !
3350: // So , we just 'mark' this id as already processed.
3351: inboundSendAndWatch.put(id, id);
3352: }
3353: return false;
3354: }
3355:
3356: void cancelSubscription(String uid) throws CollaborationException {
3357: if (_presenceService != null) {
3358: _presenceService.cancel(uid);
3359: }
3360: }
3361:
3362: public void processJinglePacket(Packet packet)
3363: throws CollaborationException {
3364: _p2pservice.processPacket(packet);
3365: }
3366:
3367: public long getRequestTimeout() {
3368: return requestTimeout;
3369: }
3370:
3371: protected void setRequestTimeout(long REQUEST_TIMEOUT) {
3372: this .requestTimeout = REQUEST_TIMEOUT;
3373: }
3374:
3375: public NotificationService getNotificationService()
3376: throws CollaborationException {
3377: if (_notificationService == null) {
3378: _notificationService = new XMPPNotificationService(this );
3379: }
3380: return _notificationService;
3381: }
3382:
3383: public synchronized ConferenceService getConferenceService()
3384: throws CollaborationException {
3385: if (_conferenceService == null) {
3386: _conferenceService = new XMPPConferenceService(this );
3387: }
3388: return _conferenceService;
3389: }
3390:
3391: public ExtendedConferenceService getExtendedConferenceService()
3392: throws CollaborationException {
3393: return (ExtendedConferenceService) getConferenceService();
3394: }
3395:
3396: public NewsService getNewsService() throws CollaborationException {
3397: if (_newsService == null) {
3398: _newsService = new XMPPNewsService(this );
3399: }
3400:
3401: return _newsService;
3402: }
3403:
3404: public PersonalStoreService getPersonalStoreService()
3405: throws CollaborationException {
3406: if (_personalStoreService == null) {
3407: _personalStoreService = new XMPPPersonalStoreService(this );
3408: }
3409:
3410: return _personalStoreService;
3411: }
3412:
3413: public PresenceService getPresenceService()
3414: throws CollaborationException {
3415: if (_presenceService == null) {
3416: _presenceService = new XMPPPresenceService(this );
3417: }
3418: return _presenceService;
3419: }
3420:
3421: public StreamingService getStreamingService()
3422: throws CollaborationException {
3423: if (_streamingService == null) {
3424: _streamingService = new XMPPStreamingService(this );
3425: }
3426: return _streamingService;
3427: }
3428:
3429: public Collection listNewsChannels(String domain)
3430: throws CollaborationException {
3431: return _newsService.listNewsChannels();
3432: }
3433:
3434: protected void addNewsChannel(XMPPNewsChannel nc) {
3435: if (_newsService != null) {
3436: _newsService.addNewsChannel(nc);
3437: }
3438: }
3439:
3440: protected void removeNewsChannel(XMPPNewsChannel nc) {
3441: if (_newsService != null) {
3442: _newsService.removeNewsChannel(nc);
3443: }
3444: }
3445:
3446: public boolean isCurrentUser(JID jid) {
3447: if (jid == null)
3448: return false;
3449: return _client.getJID().toBareJID().equals(jid.toBareJID());
3450: }
3451:
3452: public JID getCurrentUserJID() {
3453: return (_client == null) ? null : _client.getJID();
3454: }
3455:
3456: ApplicationInfo getApplicationInfo() throws CollaborationException {
3457: return _provider.getApplicationInfo();
3458: }
3459:
3460: private void processDiscoInfoRequest(Packet packet)
3461: throws CollaborationException {
3462:
3463: DiscoInfoQuery query = (DiscoInfoQuery) packet
3464: .getExtension(DiscoInfoQuery.NAMESPACE);
3465:
3466: if (InfoQuery.RESULT.equals(packet.getType())
3467: || InfoQuery.ERROR.equals(packet.getType())
3468: || InfoQuery.SET.equals(packet.getType())) {
3469: // for now don't process the disco#result packets
3470: return;
3471: }
3472: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3473: InfoQuery.class);
3474: iq.setTo(packet.getFrom());
3475: iq.setType(InfoQuery.RESULT);
3476: iq.setID(packet.getID());
3477: DiscoInfoQuery disco = (DiscoInfoQuery) _sdf
3478: .createExtensionNode(DiscoInfoQuery.NAME,
3479: DiscoInfoQuery.class);
3480:
3481: try {
3482: if (InfoQuery.GET.equals(packet.getType())) {
3483: XMPPApplicationInfo appinfo = (XMPPApplicationInfo) _provider
3484: .getApplicationInfo();
3485: appinfo.fillDiscoResponse(disco, query
3486: .getAttributeValue("node"));
3487:
3488: } else {
3489: // todo decide what to do for a set request
3490: return;
3491: }
3492: iq.add(disco);
3493: _connection.send(iq);
3494: } catch (StreamException se) {
3495: throw new CollaborationException(se.toString());
3496: }
3497: }
3498:
3499: private void processDiscoItemsRequest(Packet packet)
3500: throws CollaborationException {
3501: if (InfoQuery.RESULT.equals(packet.getType())
3502: || InfoQuery.ERROR.equals(packet.getType())
3503: || InfoQuery.SET.equals(packet.getType())) {
3504: // for now don't process the disco#result packets
3505: return;
3506: }
3507: InfoQuery iq = (InfoQuery) _sdf.createPacketNode(IQ_NAME,
3508: InfoQuery.class);
3509: iq.setFrom(packet.getTo());
3510: iq.setTo(packet.getFrom());
3511: iq.setType(InfoQuery.RESULT);
3512: iq.setID(packet.getID());
3513: try {
3514: DiscoItemsQuery disco = (DiscoItemsQuery) _sdf
3515: .createExtensionNode(DiscoItemsQuery.NAME,
3516: DiscoItemsQuery.class);
3517: iq.add(disco);
3518: _connection.send(iq);
3519: } catch (StreamException se) {
3520: throw new CollaborationException(se.toString());
3521: }
3522: }
3523:
3524: public boolean isGatewayEntry(JID jid) {
3525: try {
3526: if ((jid != null)
3527: && (_personalStoreService != null)
3528: && _personalStoreService.isGatewayEntry(jid
3529: .toBareJID())) {
3530: return true;
3531: }
3532: } catch (Exception e) {
3533: }
3534: return false;
3535: }
3536:
3537: private void notifyStreamError(StreamError error) {
3538: if (getSessionListener() != null) {
3539: _provider.cleanupSession(XMPPSession.this );
3540: _provider.cancel(_selectionKey);
3541: CollaborationException e = null;
3542: if (error != null) {
3543: String errorCond = error.getDefinedCondition();
3544: String errorText = error.getText();
3545: if (errorText == null)
3546: errorText = "Server Disconnected";
3547: if (StreamError.CONFLICT_CONDITION.equals(errorCond)) {
3548: e = new ConflictException(
3549: "Duplicate Connection detected");
3550: } else if (StreamError.CONNECTION_TIMEOUT_CONDITION
3551: .equals(errorCond)) {
3552: e = new TimeoutException(errorText);
3553: } else if (StreamError.HOST_GONE_CONDITION
3554: .equals(errorCond)
3555: || StreamError.HOST_UNKNOWN_CONDITION
3556: .equals(errorCond)
3557: || StreamError.SYSTEM_SHUTDOWN_CONDITION
3558: .equals(errorCond)) {
3559: e = new ServiceUnavailableException(errorText);
3560: } else if (StreamError.IMPROPER_ADDRESSING_CONDITION
3561: .equals(errorCond)) {
3562: e = new ItemNotFoundException(errorText);
3563: } else if (StreamError.INVALID_FROM_CONDITION
3564: .equals(errorCond)
3565: || StreamError.INVALID_ID_CONDITION
3566: .equals(errorCond)
3567: || StreamError.NOT_AUTHORIZED_CONDITION
3568: .equals(errorCond)) {
3569: e = new AuthorizationException(errorText);
3570: } else if (StreamError.REMOTE_CONNECTION_FAILED_CONDITION
3571: .equals(errorCond)) {
3572: e = new RoutingException(errorText);
3573: } else {
3574: e = new CollaborationException(errorText);
3575: }
3576: } else {
3577: e = new CollaborationException("Server Disconnected");
3578: }
3579: fireCollaborationSessionListener(e);
3580: } else {
3581: //check for the registerListeners
3582: for (Iterator itr = _regisListeners.entrySet().iterator(); itr
3583: .hasNext();) {
3584: Map.Entry entry = (Map.Entry) itr.next();
3585: XMPPRegistrationListenerWrapper listener = (XMPPRegistrationListenerWrapper) entry
3586: .getValue();
3587: if (listener != null) {
3588: String condition = RegistrationListener.SERVICE_UNAVAILABLE;
3589: if ((error != null)
3590: && (error
3591: .getFirstElement(
3592: null,
3593: StreamError.NOT_AUTHORIZED_CONDITION) != null)) {
3594: condition = RegistrationListener.NOT_AUTHORIZED;
3595: }
3596: listener.getRegisListener().registrationFailed(
3597: condition, "Stream error", null);
3598: _regisListeners.remove(entry.getKey());
3599: }
3600: }
3601: }
3602: }
3603:
3604: private boolean keepAliveEnabled = false;
3605:
3606: public void setKeepAliveEnabled(boolean keepAliveEnabled) {
3607: this .keepAliveEnabled = keepAliveEnabled;
3608: }
3609:
3610: public boolean isKeepAliveEnabled() {
3611: return keepAliveEnabled;
3612: }
3613:
3614: static private byte[] keepAliveBuffer = { ' ', ' ' };
3615:
3616: protected void sendKeepAlive() {
3617: if (isKeepAliveEnabled()) {
3618: synchronized (_connection) {
3619: try {
3620: _css.write(keepAliveBuffer, 0, 2);
3621: } catch (IOException ioe) {
3622: // close???
3623: }
3624: }
3625: }
3626: }
3627:
3628: private boolean _PEPEnabled = true;
3629:
3630: void supportsPersonalEvents(boolean b) {
3631: _PEPEnabled = b;
3632: }
3633:
3634: boolean supportsPersonalEvents() {
3635: return _PEPEnabled;
3636: }
3637:
3638: protected boolean _initFeaturesSupported() {
3639: if (_serverFeaturesDiscovered)
3640: return true;
3641: DiscoInfoQuery diq = null;
3642: try {
3643: diq = sendInfoQuery(_server);
3644: } catch (CollaborationException ce) {
3645: XMPPSessionProvider.debug(null, ce);
3646: _serverFeaturesDiscovered = false;
3647: }
3648:
3649: if (diq != null) {
3650: // discover PEP support
3651: if (diq.getIdentity("pubsub", "pep") == null) {
3652: _PEPEnabled = false;
3653: }
3654:
3655: boolean capsSupported = false;
3656: for (Iterator i = diq.getFeatures().iterator(); i.hasNext();) {
3657: String feature = (String) i.next();
3658: if (AMPExtension.NAMESPACE.equals(feature)) {
3659: ampSupported = true;
3660: } else if (XMPPSessionProvider.CAPS_NAMESPACE
3661: .equals(feature)) {
3662: capsSupported = true;
3663: }
3664:
3665: // todo : there are many other features to assert, like
3666: // search, version, etc...
3667:
3668: }
3669: _serverFeaturesDiscovered = true;
3670:
3671: try {
3672: ((XMPPApplicationInfo) _provider.getApplicationInfo())
3673: .supportsCaps(capsSupported);
3674: } catch (Exception e) {
3675: }
3676:
3677: } /* else {
3678: serviceFailed = true;
3679: }
3680: */
3681: if (ampSupported) {
3682: try {
3683: diq = sendInfoQuery(_server, AMPExtension.NAMESPACE);
3684: } catch (CollaborationException ce) {
3685: XMPPSessionProvider.debug(null, ce);
3686: //_serverFeaturesDiscovered = false;
3687: }
3688: for (Iterator i = diq.getFeatures().iterator(); i.hasNext();) {
3689: String feature = (String) i.next();
3690: if (AMP_COND_DELIVER_NAMESPACE.equals(feature)) {
3691: ampCondDeliverSupported = true;
3692: } else if (AMP_COND_EXPIREAT_NAMESPACE.equals(feature)) {
3693: ampCondExpireAtSupported = true;
3694: } else if (AMP_COND_MATCHRES_NAMESPACE.equals(feature)) {
3695: ampCondMatchResourceSupported = true;
3696: } else if (AMP_ACTION_DROP_NAMESPACE.equals(feature)) {
3697: ampActionDropSupported = true;
3698: } else if (AMP_ACTION_ALERT_NAMESPACE.equals(feature)) {
3699: ampActionAlertSupported = true;
3700: } else if (AMP_ACTION_NOTIFY_NAMESPACE.equals(feature)) {
3701: ampActionNotifySupported = true;
3702: } else if (AMP_ACTION_ERROR_NAMESPACE.equals(feature)) {
3703: ampActionErrorSupported = true;
3704: }
3705: }
3706: }
3707: return _serverFeaturesDiscovered;
3708: }
3709:
3710: protected void waitForServiceInitialization(Object service) {
3711: try {
3712: if (!_loadingServices) {
3713: // make sure this is it not called multiple times
3714: // concurrently.
3715: synchronized (_loadingServiceLock) {
3716: if (!_loadingServices) {
3717: _loadingServices = true;
3718: loadJabberServices();
3719: }
3720: }
3721: }
3722: synchronized (service) {
3723: long waitTime = getShortRequestTimeout();
3724: long start = System.currentTimeMillis();
3725: while (!isServiceInitialized(service)) {
3726: try {
3727: service.wait(waitTime);
3728: } catch (InterruptedException ie) {
3729: XMPPSessionProvider.debug(ie.toString(), ie);
3730: }
3731: if (!isServiceInitialized(service)) {
3732: long end = System.currentTimeMillis();
3733: int slept = (int) (end - start);
3734: if (slept >= waitTime)
3735: break;
3736: else {
3737: waitTime -= slept;
3738: start = end;
3739: }
3740: }
3741: }
3742: }
3743: } catch (Exception e) {
3744: XMPPSessionProvider.debug(e.toString(), e);
3745: }
3746: synchronized (_loadingServiceLock) {
3747: _loadingServices = false;
3748: }
3749: }
3750:
3751: private boolean isServiceInitialized(Object service) {
3752: synchronized (_jabberServiceLock) {
3753: if (service instanceof ConferenceService) {
3754: return (_mucService != null);
3755: }
3756: if (service instanceof NewsService) {
3757: return (_pubsubService != null);
3758: }
3759: if (service instanceof PersonalStoreService) {
3760: return (_judService != null);
3761: }
3762: return false;
3763: }
3764: }
3765:
3766: private void processRegisterResponse(InfoQuery iq,
3767: RegisterQuery registerQuery,
3768: XMPPRegistrationListenerWrapper regisListenerWrapper,
3769: String serverStr) throws CollaborationException {
3770: RegistrationListener regisListener = regisListenerWrapper
3771: .getRegisListener();
3772: XMPPRegistrationListenerWrapper.RequestType reqType = regisListenerWrapper
3773: .getRequestType();
3774:
3775: if (iq.getType() == InfoQuery.RESULT && registerQuery != null) {
3776: if (registerQuery.isRegistered()) {
3777: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION
3778: .equals(reqType)) {
3779: regisListener.registered(serverStr);
3780: return;
3781: }
3782: // it is a gateway re-registration
3783: }
3784: keyValue = registerQuery.getKey();
3785: registerQuery.clearKey();
3786: Set fields = registerQuery.getFieldNames();
3787:
3788: Map fieldValuePairs = new HashMap();
3789: for (Iterator iter = fields.iterator(); iter.hasNext();) {
3790: String fieldName = (String) iter.next();
3791: fieldValuePairs.put(fieldName, registerQuery
3792: .getField(fieldName)); // put the value also if any
3793: }
3794: boolean filled = regisListener.fillRegistrationInformation(
3795: fieldValuePairs, serverStr);
3796: if (!filled) {
3797: // do not do anything
3798: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION
3799: .equals(reqType)) {
3800: logout();
3801: }
3802: return;
3803: } else {
3804: String userName = (String) fieldValuePairs
3805: .get(RegistrationListener.USERNAME);
3806: String password = (String) fieldValuePairs
3807: .get(RegistrationListener.PASSWORD);
3808: if (userName == null || userName.equals("")
3809: || password == null || password.equals("")) {
3810: regisListener
3811: .registrationFailed(
3812: RegistrationListener.MISSING_DATA,
3813: "Empty username or password is not allowed",
3814: serverStr);
3815: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION
3816: .equals(reqType)) {
3817: logout();
3818: }
3819: return;
3820: }
3821: }
3822:
3823: if (iq.getFrom() != null) {
3824: sendRegistration(iq.getFrom(), fieldValuePairs, iq
3825: .getID());
3826: } else {
3827: sendRegistration(_server, fieldValuePairs, iq.getID());
3828: }
3829: }
3830: }
3831:
3832: private void processRegisSuccessFailure(InfoQuery iq,
3833: XMPPRegistrationListenerWrapper regisListenerWrapper,
3834: String serverStr) throws CollaborationException {
3835:
3836: RegistrationListener regisListener = regisListenerWrapper
3837: .getRegisListener();
3838: XMPPRegistrationListenerWrapper.RequestType reqType = null;
3839: reqType = regisListenerWrapper.getRequestType();
3840:
3841: if (iq.getType() == InfoQuery.RESULT) {
3842: if (XMPPRegistrationListenerWrapper.GATEWAY_REGISTRATION
3843: .equals(reqType)) {
3844: postGatewayRegistration(serverStr);
3845: regisListener.registered(serverStr);
3846: } else if (XMPPRegistrationListenerWrapper.USER_REGISTRATION
3847: .equals(reqType)) {
3848: regisListener.registered(serverStr);
3849: logout();
3850: } else if (XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE
3851: .equals(reqType)) {
3852: regisListener.registrationUpdated(serverStr);
3853: } else if (XMPPRegistrationListenerWrapper.GATEWAY_UNREGISTRATION
3854: .equals(reqType)) {
3855: postGatewayUnregistration(serverStr);
3856: regisListener.unregistered(serverStr);
3857: } else if (XMPPRegistrationListenerWrapper.USER_UNREGISTRATION
3858: .equals(reqType)) {
3859: regisListener.unregistered(serverStr);
3860: }
3861: _regisListeners.remove(iq.getID());
3862:
3863: } else if (iq.getType() == InfoQuery.ERROR) {
3864: XMPPSessionProvider.debug("Error in registration");
3865: PacketError pe = iq.getError();
3866: if (pe != null) {
3867: if (XMPPRegistrationListenerWrapper.USER_PASSWD_CHANGE
3868: .equals(reqType)) {
3869: regisListener.registrationUpdateFailed(pe
3870: .getDefinedCondition(), pe.getText(),
3871: serverStr);
3872: } else if (XMPPRegistrationListenerWrapper.GATEWAY_UNREGISTRATION
3873: .equals(reqType)
3874: || XMPPRegistrationListenerWrapper.USER_UNREGISTRATION
3875: .equals(reqType)) {
3876: regisListener.unregistrationFailed(
3877: getRegistrationErrorCondition(pe
3878: .getDefinedCondition()), pe
3879: .getText(), serverStr);
3880: } else if (XMPPRegistrationListenerWrapper.GATEWAY_REGISTRATION
3881: .equals(reqType)
3882: || XMPPRegistrationListenerWrapper.USER_REGISTRATION
3883: .equals(reqType)) {
3884: regisListener.registrationFailed(
3885: getRegistrationErrorCondition(pe
3886: .getDefinedCondition()), pe
3887: .getText(), serverStr);
3888: }
3889: } else {
3890: XMPPSessionProvider.debug("Packet error is null");
3891: }
3892: _regisListeners.remove(iq.getID());
3893: if (XMPPRegistrationListenerWrapper.USER_REGISTRATION
3894: .equals(reqType)) {
3895: logout();
3896: }
3897: return;
3898: }
3899: }
3900:
3901: public int addWorkerRunnable(Runnable r) {
3902: return _provider.addRunnable(r);
3903: }
3904:
3905: private void fireCollaborationSessionListener(
3906: CollaborationException e) {
3907: addWorkerRunnable(new CollaborationSessionNotifier(e));
3908: }
3909:
3910: private void fireMessageProcessingListener(
3911: org.netbeans.lib.collab.Message m, int status,
3912: CollaborationException e) {
3913: addWorkerRunnable(new MessageProcessingListenerNotifier(m,
3914: status, e));
3915: }
3916:
3917: public void addSessionListener(CollaborationSessionListener listener) {
3918: if (!_sessionListeners.contains(listener))
3919: _sessionListeners.add(listener);
3920: }
3921:
3922: public void removeSessionListener(
3923: CollaborationSessionListener listener) {
3924: _sessionListeners.remove(listener);
3925: }
3926:
3927: public JID getMUCService() {
3928: synchronized (_jabberServiceLock) {
3929: return _mucService;
3930: }
3931: }
3932:
3933: public void setMUCService(JID service) {
3934: synchronized (_jabberServiceLock) {
3935: this ._mucService = service;
3936: }
3937: }
3938:
3939: public JID getPubSubService() {
3940: synchronized (_jabberServiceLock) {
3941: return _pubsubService;
3942: }
3943: }
3944:
3945: public JID getJUDService() {
3946: synchronized (_jabberServiceLock) {
3947: return _judService;
3948: }
3949: }
3950:
3951: public Map getGateways() {
3952: synchronized (_jabberServiceLock) {
3953: return _gateways;
3954: }
3955: }
3956:
3957: private class CollaborationSessionNotifier implements Runnable {
3958: CollaborationException ce;
3959:
3960: CollaborationSessionNotifier(CollaborationException ce) {
3961: this .ce = ce;
3962: }
3963:
3964: public void run() {
3965: synchronized (_sessionListeners) {
3966: for (Iterator itr = _sessionListeners.iterator(); itr
3967: .hasNext();) {
3968: try {
3969: CollaborationSessionListener l = (CollaborationSessionListener) itr
3970: .next();
3971: if (l == null)
3972: continue;
3973: l.onError(ce);
3974: } catch (Exception e) {
3975: XMPPSessionProvider.error(e.toString(), e);
3976: }
3977: }
3978: }
3979: }
3980: }
3981:
3982: private class MessageProcessingListenerNotifier implements Runnable {
3983: private org.netbeans.lib.collab.Message m;
3984: private int status;
3985: private CollaborationException ce;
3986:
3987: MessageProcessingListenerNotifier(
3988: org.netbeans.lib.collab.Message m, int status,
3989: CollaborationException ce) {
3990: this .ce = ce;
3991: this .m = m;
3992: this .status = status;
3993: }
3994:
3995: public void run() {
3996: synchronized (_sessionListeners) {
3997: for (Iterator itr = _sessionListeners.iterator(); itr
3998: .hasNext();) {
3999: try {
4000: CollaborationSessionListener l = (CollaborationSessionListener) itr
4001: .next();
4002: if (l == null
4003: || (!(l instanceof MessageProcessingListener)))
4004: continue;
4005: ((MessageProcessingListener) l)
4006: .onMessageStatus(m, status, ce);
4007: } catch (Exception e) {
4008: XMPPSessionProvider.error(e.toString(), e);
4009: }
4010: }
4011: }
4012: }
4013: }
4014:
4015: protected StreamSourceCreator getStreamSourceCreator() {
4016: return _streamSrcCreator;
4017: }
4018:
4019: public static CollaborationException getCollaborationException(
4020: PacketError error, String errorText) {
4021: if (error == null)
4022: return null;
4023: String errorCond = error.getDefinedCondition();
4024: if (errorText == null)
4025: errorText = error.getText();
4026: if (errorCond != null) {
4027: if (PacketError.FEATURE_NOT_IMPLEMENTED_CONDITION
4028: .equals(errorCond)
4029: || PacketError.SERVICE_UNAVAILABLE_CONDITION
4030: .equals(errorCond)) {
4031: return new ServiceUnavailableException(errorText);
4032: }
4033: if (PacketError.CONFLICT_CONDITION.equals(errorCond)) {
4034: return new ConflictException(errorText);
4035: }
4036: if (PacketError.FORBIDDEN_CONDITION.equals(errorCond)) {
4037: return new AuthorizationException(errorText,
4038: AuthorizationException.INSUFFICIENT_PERMISSIONS);
4039: }
4040: if (PacketError.ITEM_NOT_FOUND_CONDITION.equals(errorCond)) {
4041: return new ItemNotFoundException(errorText);
4042: }
4043: if (PacketError.NOT_ACCEPTABLE_CONDITION.equals(errorCond)) {
4044: return new AuthorizationException(errorText,
4045: AuthorizationException.NOT_ALLOWED);
4046: }
4047: if (PacketError.NOT_ALLOWED_CONDITION.equals(errorCond)) {
4048: return new AuthorizationException(errorText);
4049: }
4050: if (PacketError.NOT_AUTHORIZED_CONDITION.equals(errorCond)) {
4051: return new AuthorizationException(errorText,
4052: AuthorizationException.INVALID_CREDENTIALS);
4053: }
4054: if (PacketError.PAYMENT_REQUIRED_CONDITION
4055: .equals(errorCond)) {
4056: return new AuthorizationException(errorText,
4057: AuthorizationException.PAYMENT_REQUIRED);
4058: }
4059: if (PacketError.RECIPIENT_UNAVAILABLE_CONDITION
4060: .equals(errorCond)) {
4061: return new RecipientUnvailableException(errorText);
4062: }
4063: if (PacketError.SUBSCRIPTION_REQUIRED_CONDITION
4064: .equals(errorCond)) {
4065: return new AuthorizationException(errorText,
4066: AuthorizationException.SUBSCRIPTION_REQUIRED);
4067: }
4068: if (PacketError.REGISTRATION_REQUIRED_CONDITION
4069: .equals(errorCond)) {
4070: return new AuthorizationException(errorText,
4071: AuthorizationException.REGISTRATION_REQUIRED);
4072: }
4073: if (PacketError.REMOTE_SERVER_NOT_FOUND_CONDITION
4074: .equals(errorCond)) {
4075: return new RoutingException(errorText);
4076: }
4077: if (PacketError.REMOTE_SERVER_TIMEOUT_CONDITION
4078: .equals(errorCond)
4079: || PacketError.RESOURCE_CONSTRAINT_CONDITION
4080: .equals(errorCond)) {
4081: return new TimeoutException(errorText);
4082: }
4083: /*if (PacketError.UNDEFINED_CONDITION.equals(errorCond)) {
4084: //use collaboration exception
4085: }
4086: if (PacketError.UNEXPECTED_REQUEST_CONDITION.equals(errorCond)) {
4087: //use collaboration exception
4088: }
4089: if (PacketError.BAD_REQUEST_CONDITION.equals(errorCond)) {
4090: //not needed
4091: }
4092: if (PacketError.INTERNAL_SERVER_ERROR_CONDITION.equals(errorCond)) {
4093: //throw collaboration exception
4094: }
4095: if (PacketError.REDIRECT_CONDITION.equals(errorCond)) {
4096: //handled as part of stream errors
4097: }*/
4098: }
4099: return new CollaborationException(error.getText());
4100: }
4101:
4102: public JID getVoipComponent() {
4103: return _voipComponent;
4104: }
4105:
4106: private boolean isJinglePacket(Packet packet) {
4107: if (_p2pservice != null && _p2pservice.isJinglePacket(packet)) {
4108: return true;
4109: }
4110: return false;
4111: }
4112:
4113: private static final boolean comparatorMethodAvailable;
4114: private static java.lang.reflect.Method sendAndWatch1 = null;
4115: private static java.lang.reflect.Method sendAndWatch2 = null;
4116: static {
4117: boolean available = false;
4118: try {
4119: Class clazz = Class
4120: .forName("org.jabberstudio.jso.util.PacketMonitor");
4121: Class[] params = new Class[] { Stream.class, Packet.class,
4122: Comparator.class };
4123: sendAndWatch1 = clazz.getMethod("sendAndWatch", params);
4124: params = new Class[] { Stream.class, Packet.class,
4125: Long.TYPE, Comparator.class };
4126: sendAndWatch2 = clazz.getMethod("sendAndWatch", params);
4127: if (null != sendAndWatch1 && null != sendAndWatch2) {
4128: available = true;
4129: }
4130: } catch (Exception ex) {
4131: //available = false;
4132: //ex.printStackTrace();
4133: } catch (NoClassDefFoundError ncdfEx) {
4134: //available = false;
4135: //ncdfEx.printStackTrace();
4136: } finally {
4137: comparatorMethodAvailable = available;
4138: }
4139: }
4140:
4141: public Packet sendAndWatch(Packet packet)
4142: throws IllegalArgumentException, StreamException {
4143: String id = packet.getID();
4144: addSendAndWatchID(id);
4145: try {
4146: if (null != id && comparatorMethodAvailable) {
4147: Comparator comparator = new RedispatchComparator(packet);
4148: //return PacketMonitor.sendAndWatch(getConnection() , packet , comparator);
4149: return (Packet) sendAndWatch1.invoke(null,
4150: new Object[] { getConnection(), packet,
4151: comparator });
4152: }
4153: return PacketMonitor.sendAndWatch(getConnection(), packet);
4154: } catch (IllegalAccessException accEx) {
4155: // Can happen ?
4156: accEx.printStackTrace();
4157: throw new RuntimeException(accEx);
4158: } catch (java.lang.reflect.InvocationTargetException itEx) {
4159: //itEx.printStackTrace();
4160: Throwable th = itEx.getTargetException();
4161:
4162: if (th instanceof IllegalArgumentException) {
4163: throw (IllegalArgumentException) th;
4164: }
4165: if (th instanceof StreamException) {
4166: throw (StreamException) th;
4167: }
4168:
4169: throw new RuntimeException(itEx);
4170: } finally {
4171: forceRemoveSendAndWatch(id);
4172: }
4173: }
4174:
4175: public Packet sendAndWatch(Packet packet, long timeout)
4176: throws IllegalArgumentException, StreamException {
4177: String id = packet.getID();
4178: addSendAndWatchID(id);
4179: try {
4180: if (null != id && comparatorMethodAvailable) {
4181: Comparator comparator = new RedispatchComparator(packet);
4182: //return PacketMonitor.sendAndWatch(getConnection() , packet , timeout , comparator);
4183: return (Packet) sendAndWatch2.invoke(null,
4184: new Object[] { getConnection(), packet,
4185: new Long(timeout), comparator });
4186: }
4187: return PacketMonitor.sendAndWatch(getConnection(), packet,
4188: timeout);
4189: } catch (IllegalAccessException accEx) {
4190: // Can happen ?
4191: accEx.printStackTrace();
4192: throw new RuntimeException(accEx);
4193: } catch (java.lang.reflect.InvocationTargetException itEx) {
4194: //itEx.printStackTrace();
4195: Throwable th = itEx.getTargetException();
4196:
4197: if (th instanceof IllegalArgumentException) {
4198: throw (IllegalArgumentException) th;
4199: }
4200: if (th instanceof StreamException) {
4201: throw (StreamException) th;
4202: }
4203:
4204: throw new RuntimeException(itEx);
4205: } finally {
4206: forceRemoveSendAndWatch(id);
4207: }
4208: }
4209:
4210: private class RedispatchComparator implements Comparator {
4211:
4212: private Packet sentPacket;
4213:
4214: public RedispatchComparator(Packet sentPacket) {
4215: this .sentPacket = sentPacket;
4216:
4217: }
4218:
4219: public int compare(Object o1, Object o2) {
4220:
4221: if (null == o1 && null == o2) {
4222: return 0;
4223: }
4224:
4225: if (o1 instanceof Packet && o2 instanceof Packet
4226: // Paranoia
4227: && (o1 == sentPacket || o2 == sentPacket)) {
4228: Packet recievedPacket = (Packet) (o1 == sentPacket ? o2
4229: : o1);
4230:
4231: String id1 = ((Packet) o1).getID();
4232: String id2 = ((Packet) o2).getID();
4233:
4234: JID inFrom = recievedPacket.getFrom();
4235: JID outTo = sentPacket.getTo();
4236:
4237: JID ourJID = null != _client ? _client.getJID() : null;
4238:
4239: if (null != id1
4240: && null != id2
4241: && null != inFrom
4242: && null != outTo
4243: && null != ourJID
4244: && id1.equals(id2)
4245: && inFrom.toBareJID()
4246: .equals(ourJID.toBareJID())
4247: && inFrom.toBareJID().equals(outTo.toBareJID())) {
4248: return isSendAndWatchIDRecievedOnce(id1) ? 0 : 1;
4249: }
4250: }
4251:
4252: // Rest of the validation will be handled by PacketMonitor
4253: return 0;
4254: }
4255: };
4256:
4257: private static long getLongProperty(String key, long def) {
4258: String str = System.getProperty(key);
4259: long retval = def;
4260:
4261: if (null != str) {
4262: try {
4263: retval = Long.parseLong(str.trim());
4264: } catch (NumberFormatException nfEx) {
4265: }
4266: }
4267: return retval;
4268: }
4269:
4270: public Set getFeatures(String jid) {
4271: try {
4272: DiscoInfoQuery diq = sendInfoQuery(new JID(jid), null);
4273: return diq.getFeatures();
4274: } catch (JIDFormatException ex) {
4275: xmpplogger.warn("Could not get features, invalid JID : "
4276: + jid);
4277: } catch (CollaborationException ex) {
4278: xmpplogger.warn("Could not get features for " + jid + " : "
4279: + ex.getMessage());
4280: }
4281: return null;
4282: }
4283:
4284: JingleService _p2pservice;
4285:
4286: public P2PService getP2PService() {
4287: if (_p2pservice == null) {
4288: _p2pservice = new JingleService(this);
4289: }
4290: return _p2pservice;
4291: }
4292: }
|