1 /**
  2  * @fileoverview This file contains all things that make life easier when
  3  * dealing with JIDs
  4  * @author Stefan Strigler
  5  */
  6 
  7 Xmpp4Js.Lang.namespace( "Xmpp4Js" );
  8 
  9 /**
 10  * list of forbidden chars for nodenames
 11  * @private
 12  */
 13 var Jid_FORBIDDEN = ['"',' ','&','\'','/',':','<','>','@']; 
 14 
 15 /**
 16  * Creates a new Jid object
 17  * @class Jid models xmpp jid objects
 18  * @constructor
 19  * @param {Object} jid jid may be either of type String or a JID represented 
 20  * by JSON with fields 'node', 'domain' and 'resource'
 21  * @throws Xmpp4Js.JidInvalidException Thrown if jid is not valid
 22  * @return a new Jid object
 23  */
 24 Xmpp4Js.Jid = function(jid) {
 25   /**
 26    *@private
 27    */
 28   this._node = '';
 29   /**
 30    *@private
 31    */
 32   this._domain = '';
 33   /**
 34    *@private
 35    */
 36   this._resource = '';
 37 
 38   if (jid !== undefined && jid != null) {
 39 	  if (jid instanceof Xmpp4Js.Jid) {
 40 	
 41 	    this.setNode(jid.getNode());
 42 	    this.setDomain(jid.getDomain());
 43 	    this.setResource(jid.getResource());
 44 	    
 45 	  } else {
 46 	    if (jid.indexOf('@') != -1) {
 47 	        this.setNode(jid.substring(0,jid.indexOf('@')));
 48 	        jid = jid.substring(jid.indexOf('@')+1);
 49 	    }
 50 	    if (jid.indexOf('/') != -1) {
 51 	      this.setResource(jid.substring(jid.indexOf('/')+1));
 52 	      jid = jid.substring(0,jid.indexOf('/'));
 53 	    }
 54 	    this.setDomain(jid);
 55 	  }
 56   }
 57 }
 58 
 59 Xmpp4Js.Jid.isValid = function(jid) {
 60     try {
 61         new Xmpp4Js.Jid(jid);
 62         return true;
 63     } catch(e) {
 64         return false;
 65     }
 66 }
 67 
 68 /**
 69  * Gets the node part of the jid
 70  * @return A string representing the node name
 71  * @type String
 72  */
 73 Xmpp4Js.Jid.prototype.getNode = function() { return this._node; };
 74 
 75 /**
 76  * Gets the domain part of the jid
 77  * @return A string representing the domain name
 78  * @type String
 79  */
 80 Xmpp4Js.Jid.prototype.getDomain = function() { return this._domain; };
 81 
 82 /**
 83  * Gets the resource part of the jid
 84  * @return A string representing the resource
 85  * @type String
 86  */
 87 Xmpp4Js.Jid.prototype.getResource = function() { return this._resource; };
 88 
 89 
 90 /**
 91  * Sets the node part of the jid
 92  * @param {String} node Name of the node
 93  * @throws Xmpp4Js.JidInvalidException Thrown if node name contains invalid chars
 94  * @return This object
 95  * @type Jid
 96  */
 97 Xmpp4Js.Jid.prototype.setNode = function(node) {
 98   Xmpp4Js.Jid._checkNodeName(node);
 99   this._node = node || '';
100   return this;
101 };
102 
103 /**
104  * Sets the domain part of the jid
105  * @param {String} domain Name of the domain
106  * @throws Xmpp4Js.JidInvalidException Thrown if domain name contains invalid 
107  * chars or is empty
108  * @return This object
109  * @type Jid
110  */
111 Xmpp4Js.Jid.prototype.setDomain = function(domain) {
112   if (!domain || domain == '')
113     throw new Xmpp4Js.JidInvalidException("domain name missing");
114   // chars forbidden for a node are not allowed in domain names
115   // anyway, so let's check
116   Xmpp4Js.Jid._checkNodeName(domain); 
117   this._domain = domain;
118   return this;
119 };
120 
121 /**
122  * Sets the resource part of the jid
123  * @param {String} resource Name of the resource
124  * @return This object
125  * @type Jid
126  */
127 Xmpp4Js.Jid.prototype.setResource = function(resource) {
128   this._resource = resource || '';
129   return this;
130 };
131 
132 /**
133  * The string representation of the full jid
134  * @return A string representing the jid
135  * @type String
136  */
137 Xmpp4Js.Jid.prototype.toString = function() {
138   var jid = '';
139   if (this.getNode() && this.getNode() != '')
140     jid = this.getNode() + '@';
141   jid += this.getDomain(); // we always have a domain
142   if (this.getResource() && this.getResource() != "")
143     jid += '/' + this.getResource();
144   return jid;
145 };
146 
147 /**
148  * Compare two JIDs for equality
149  * @param jid {Xmpp4Js.Jid or String} The jid to compare to
150  * @param withoutResource {boolean} Remove resource before comparing
151  */
152 Xmpp4Js.Jid.prototype.equals = function( jid, withoutResource ) {
153 	if( !(jid instanceof Xmpp4Js.Jid) ) {
154 		jid = new Xmpp4Js.Jid( jid );
155 	}
156 
157 	var isEqual = false;	
158 	if( withoutResource ) {
159 		isEqual = jid.withoutResource().toString().toLowerCase() == this.withoutResource().toString().toLowerCase();
160 	} else {
161 		isEqual = jid.toString().toLowerCase() == this.toString().toLowerCase();
162 	
163 	}
164 	return isEqual;
165 	
166 }
167 
168 /**
169  * Removes the resource part of the jid
170  * @return This object
171  * @type Jid
172  */
173 Xmpp4Js.Jid.prototype.removeResource = function() {
174   return this.setResource();
175 };
176 
177 
178 /**
179  * Creates a copy of Jid and removes the resource. Unlike removeResource, 
180  * does not modify original object.
181  * @return This object
182  * @type Jid
183  */
184 Xmpp4Js.Jid.prototype.withoutResource = function() {
185 	var tmpJid = new Xmpp4Js.Jid( this );
186   	return tmpJid.removeResource();
187 };
188 
189 /**
190  * Check if node name is valid
191  * @private
192  * @param {String} node A name for a node
193  * @throws Xmpp4Js.JidInvalidException Thrown if name for node is not allowed
194  */
195 Xmpp4Js.Jid._checkNodeName = function(nodeprep) {
196     if (!nodeprep || nodeprep == '')
197       return;
198     for (var i=0; i< Jid_FORBIDDEN.length; i++) {
199       if (nodeprep.indexOf(Jid_FORBIDDEN[i]) != -1) {
200         throw new JidInvalidException("forbidden char in nodename: "+Jid_FORBIDDEN[i]);
201       }
202     }
203 };
204 
205 /**
206  * Creates a new Exception of type JidInvalidException
207  * @class Exception to indicate invalid values for a jid
208  * @constructor
209  * @param {String} message The message associated with this Exception
210  */
211 Xmpp4Js.JidInvalidException = function(message) {
212   /**
213    * The exceptions associated message
214    * @type String
215    */
216   this.message = message;
217   /**
218    * The name of the exception
219    * @type String
220    */
221   this.name = "JidInvalidException";
222 }
223