summaryrefslogtreecommitdiff
path: root/js/src/Ice/Reference.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/Ice/Reference.js')
-rw-r--r--js/src/Ice/Reference.js2345
1 files changed, 2345 insertions, 0 deletions
diff --git a/js/src/Ice/Reference.js b/js/src/Ice/Reference.js
new file mode 100644
index 00000000000..54f0927a49d
--- /dev/null
+++ b/js/src/Ice/Reference.js
@@ -0,0 +1,2345 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+(function(global){
+ require("Ice/Class");
+ require("Ice/ArrayUtil");
+ require("Ice/Debug");
+ require("Ice/HashMap");
+ require("Ice/HashUtil");
+ require("Ice/ExUtil");
+ require("Ice/OpaqueEndpointI");
+ require("Ice/Promise");
+ require("Ice/Protocol");
+ require("Ice/ReferenceMode");
+ require("Ice/StringUtil");
+ require("Ice/BuiltinSequences");
+ require("Ice/EndpointTypes");
+ require("Ice/Identity");
+ require("Ice/Router");
+ require("Ice/Locator");
+ require("Ice/LocalException");
+ require("Ice/Version");
+ require("Ice/PropertyNames");
+
+ var Ice = global.Ice || {};
+
+ var ArrayUtil = Ice.ArrayUtil;
+ var Debug = Ice.Debug;
+ var HashMap = Ice.HashMap;
+ var HashUtil = Ice.HashUtil;
+ var ExUtil = Ice.ExUtil;
+ var OpaqueEndpointI = Ice.OpaqueEndpointI;
+ var Promise = Ice.Promise;
+ var Protocol = Ice.Protocol;
+ var RefMode = Ice.ReferenceMode;
+ var StringUtil = Ice.StringUtil;
+ var StringSeqHelper = Ice.StringSeqHelper;
+ var EndpointSelectionType = Ice.EndpointSelectionType;
+ var Identity = Ice.Identity;
+ var RouterPrx = Ice.RouterPrx;
+ var LocatorPrx = Ice.LocatorPrx;
+ var PropertyNames = Ice.PropertyNames;
+
+ var Class = Ice.Class;
+
+ var suffixes =
+ [
+ "EndpointSelection",
+ "ConnectionCached",
+ "PreferSecure",
+ "EncodingVersion",
+ "LocatorCacheTimeout",
+ "Locator",
+ "Router",
+ "CollocationOptimized"
+ ];
+
+ //
+ // Only for use by Instance
+ //
+ var ReferenceFactory = Class({
+ __init__: function(instance, communicator)
+ {
+ this._instance = instance;
+ this._communicator = communicator;
+ this._defaultRouter = null;
+ this._defaultLocator = null;
+ },
+ create: function(ident, facet, tmpl, endpoints)
+ {
+ if(ident.name.length === 0 && ident.category.length === 0)
+ {
+ return null;
+ }
+
+ return this.createImpl(ident, facet, tmpl.getMode(), tmpl.getSecure(), tmpl.getProtocol(), tmpl.getEncoding(),
+ endpoints, null, null);
+ },
+ createWithAdapterId: function(ident, facet, tmpl, adapterId)
+ {
+ if(ident.name.length === 0 && ident.category.length === 0)
+ {
+ return null;
+ }
+
+ return this.createImpl(ident, facet, tmpl.getMode(), tmpl.getSecure(), tmpl.getProtocol(), tmpl.getEncoding(),
+ null, adapterId, null);
+ },
+ createFixed: function(ident, fixedConnection)
+ {
+ if(ident.name.length === 0 && ident.category.length === 0)
+ {
+ return null;
+ }
+
+ //
+ // Create new reference
+ //
+ var ref = new FixedReference(
+ this._instance,
+ this._communicator,
+ ident,
+ "", // Facet
+ fixedConnection.endpoint().datagram() ? RefMode.ModeDatagram : RefMode.ModeTwoway,
+ fixedConnection.endpoint().secure(),
+ this._instance.defaultsAndOverrides().defaultEncoding,
+ fixedConnection);
+ return ref;
+ },
+ copy: function(r)
+ {
+ var ident = r.getIdentity();
+ if(ident.name.length === 0 && ident.category.length === 0)
+ {
+ return null;
+ }
+ return r.clone();
+ },
+ createFromString: function(s, propertyPrefix)
+ {
+ if(s === undefined || s === null || s.length === 0)
+ {
+ return null;
+ }
+
+ var delim = " \t\n\r";
+
+ var beg;
+ var end = 0;
+
+ beg = StringUtil.findFirstNotOf(s, delim, end);
+ if(beg == -1)
+ {
+ throw new Ice.ProxyParseException("no non-whitespace characters found in `" + s + "'");
+ }
+
+ //
+ // Extract the identity, which may be enclosed in single
+ // or double quotation marks.
+ //
+ var idstr = null;
+ end = StringUtil.checkQuote(s, beg);
+ if(end === -1)
+ {
+ throw new Ice.ProxyParseException("mismatched quotes around identity in `" + s + "'");
+ }
+ else if(end === 0)
+ {
+ end = StringUtil.findFirstOf(s, delim + ":@", beg);
+ if(end === -1)
+ {
+ end = s.length;
+ }
+ idstr = s.substring(beg, end);
+ }
+ else
+ {
+ beg++; // Skip leading quote
+ idstr = s.substring(beg, end);
+ end++; // Skip trailing quote
+ }
+
+ if(beg === end)
+ {
+ throw new Ice.ProxyParseException("no identity in `" + s + "'");
+ }
+
+ //
+ // Parsing the identity may raise IdentityParseException.
+ //
+ var ident = this._instance.stringToIdentity(idstr);
+
+ if(ident.name.length === 0)
+ {
+ //
+ // An identity with an empty name and a non-empty
+ // category is illegal.
+ //
+ if(ident.category.length > 0)
+ {
+ throw new Ice.IllegalIdentityException(ident);
+ }
+ //
+ // Treat a stringified proxy containing two double
+ // quotes ("") the same as an empty string, i.e.,
+ // a null proxy, but only if nothing follows the
+ // quotes.
+ //
+ else if(StringUtil.findFirstNotOf(s, delim, end) != -1)
+ {
+ throw new Ice.ProxyParseException("invalid characters after identity in `" + s + "'");
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ var facet = "";
+ var mode = RefMode.ModeTwoway;
+ var secure = false;
+ var encoding = this._instance.defaultsAndOverrides().defaultEncoding;
+ var protocol = Ice.Protocol_1_0;
+ var adapter = "";
+
+ while(true)
+ {
+ beg = StringUtil.findFirstNotOf(s, delim, end);
+ if(beg === -1)
+ {
+ break;
+ }
+
+ if(s.charAt(beg) == ':' || s.charAt(beg) == '@')
+ {
+ break;
+ }
+
+ end = StringUtil.findFirstOf(s, delim + ":@", beg);
+ if(end == -1)
+ {
+ end = s.length;
+ }
+
+ if(beg == end)
+ {
+ break;
+ }
+
+ var option = s.substring(beg, end);
+ if(option.length != 2 || option.charAt(0) != '-')
+ {
+ throw new Ice.ProxyParseException("expected a proxy option but found `" + option + "' in `" + s + "'");
+ }
+
+ //
+ // Check for the presence of an option argument. The
+ // argument may be enclosed in single or double
+ // quotation marks.
+ //
+ var argument = null;
+ var argumentBeg = StringUtil.findFirstNotOf(s, delim, end);
+ if(argumentBeg != -1)
+ {
+ var ch = s.charAt(argumentBeg);
+ if(ch != "@" && ch != ":" && ch != "-")
+ {
+ beg = argumentBeg;
+ end = StringUtil.checkQuote(s, beg);
+ if(end == -1)
+ {
+ throw new Ice.ProxyParseException("mismatched quotes around value for " + option +
+ " option in `" + s + "'");
+ }
+ else if(end === 0)
+ {
+ end = StringUtil.findFirstOf(s, delim + ":@", beg);
+ if(end === -1)
+ {
+ end = s.length;
+ }
+ argument = s.substring(beg, end);
+ }
+ else
+ {
+ beg++; // Skip leading quote
+ argument = s.substring(beg, end);
+ end++; // Skip trailing quote
+ }
+ }
+ }
+
+ //
+ // If any new options are added here,
+ // IceInternal::Reference::toString() and its derived classes must be updated as well.
+ //
+ switch(option.charAt(1))
+ {
+ case 'f':
+ {
+ if(argument === null)
+ {
+ throw new Ice.ProxyParseException("no argument provided for -f option in `" + s + "'");
+ }
+
+ try
+ {
+ facet = StringUtil.unescapeString(argument, 0, argument.length);
+ }
+ catch(ex)
+ {
+ throw new Ice.ProxyParseException("invalid facet in `" + s + "': " + ex.message);
+ }
+
+ break;
+ }
+
+ case 't':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -t option in `" + s + "'");
+ }
+ mode = RefMode.ModeTwoway;
+ break;
+ }
+
+ case 'o':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -o option in `" + s + "'");
+ }
+ mode = RefMode.ModeOneway;
+ break;
+ }
+
+ case 'O':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -O option in `" + s + "'");
+ }
+ mode = RefMode.ModeBatchOneway;
+ break;
+ }
+
+ case 'd':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -d option in `" + s + "'");
+ }
+ mode = RefMode.ModeDatagram;
+ break;
+ }
+
+ case 'D':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -D option in `" + s + "'");
+ }
+ mode = RefMode.ModeBatchDatagram;
+ break;
+ }
+
+ case 's':
+ {
+ if(argument !== null)
+ {
+ throw new Ice.ProxyParseException("unexpected argument `" + argument +
+ "' provided for -s option in `" + s + "'");
+ }
+ secure = true;
+ break;
+ }
+
+ case 'e':
+ {
+ if(argument === null)
+ {
+ throw new Ice.ProxyParseException("no argument provided for -e option in `" + s + "'");
+ }
+
+ try
+ {
+ encoding = Ice.stringToEncodingVersion(argument);
+ }
+ catch(e) // VersionParseException
+ {
+ throw new Ice.ProxyParseException("invalid encoding version `" + argument + "' in `" + s +
+ "':\n" + e.str);
+ }
+ break;
+ }
+
+ case 'p':
+ {
+ if(argument === null)
+ {
+ throw new Ice.ProxyParseException("no argument provided for -p option in `" + s + "'");
+ }
+
+ try
+ {
+ protocol = Ice.stringToProtocolVersion(argument);
+ }
+ catch(e) // VersionParseException
+ {
+ throw new Ice.ProxyParseException("invalid protocol version `" + argument + "' in `" + s +
+ "':\n" + e.str);
+ }
+ break;
+ }
+
+ default:
+ {
+ throw new Ice.ProxyParseException("unknown option `" + option + "' in `" + s + "'");
+ }
+ }
+ }
+
+ if(beg === -1)
+ {
+ return this.createImpl(ident, facet, mode, secure, protocol, encoding, null, null, propertyPrefix);
+ }
+
+ var endpoints = [];
+
+ if(s.charAt(beg) == ':')
+ {
+ var unknownEndpoints = [];
+ end = beg;
+
+ while(end < s.length && s.charAt(end) == ':')
+ {
+ beg = end + 1;
+
+ end = beg;
+ while(true)
+ {
+ end = s.indexOf(':', end);
+ if(end == -1)
+ {
+ end = s.length;
+ break;
+ }
+ else
+ {
+ var quoted = false;
+ var quote = beg;
+ while(true)
+ {
+ quote = s.indexOf("\"", quote);
+ if(quote == -1 || end < quote)
+ {
+ break;
+ }
+ else
+ {
+ quote = s.indexOf('\"', ++quote);
+ if(quote == -1)
+ {
+ break;
+ }
+ else if(end < quote)
+ {
+ quoted = true;
+ break;
+ }
+ ++quote;
+ }
+ }
+ if(!quoted)
+ {
+ break;
+ }
+ ++end;
+ }
+ }
+
+ var es = s.substring(beg, end);
+ var endp = this._instance.endpointFactoryManager().create(es, false);
+ if(endp !== null)
+ {
+ endpoints.push(endp);
+ }
+ else
+ {
+ unknownEndpoints.push(es);
+ }
+ }
+ if(endpoints.length === 0)
+ {
+ Debug.assert(unknownEndpoints.length > 0);
+ throw new Ice.EndpointParseException("invalid endpoint `" + unknownEndpoints[0] + "' in `" + s + "'");
+ }
+ else if(unknownEndpoints.length !== 0 &&
+ this._instance.initializationData().properties.getPropertyAsIntWithDefault("Ice.Warn.Endpoints", 1) > 0)
+ {
+ var msg = [];
+ msg.push("Proxy contains unknown endpoints:");
+ for(var i = 0; i < unknownEndpoints.length; ++i)
+ {
+ msg.push(" `");
+ msg.push(unknownEndpoints[i]);
+ msg.push("'");
+ }
+ this._instance.initializationData().logger.warning(msg.join(""));
+ }
+
+ return this.createImpl(ident, facet, mode, secure, protocol, encoding, endpoints, null, propertyPrefix);
+ }
+ else if(s.charAt(beg) == '@')
+ {
+ beg = StringUtil.findFirstNotOf(s, delim, beg + 1);
+ if(beg == -1)
+ {
+ throw new Ice.ProxyParseException("missing adapter id in `" + s + "'");
+ }
+
+ var adapterstr = null;
+ end = StringUtil.checkQuote(s, beg);
+ if(end === -1)
+ {
+ throw new Ice.ProxyParseException("mismatched quotes around adapter id in `" + s + "'");
+ }
+ else if(end === 0)
+ {
+ end = StringUtil.findFirstOf(s, delim, beg);
+ if(end === -1)
+ {
+ end = s.length;
+ }
+ adapterstr = s.substring(beg, end);
+ }
+ else
+ {
+ beg++; // Skip leading quote
+ adapterstr = s.substring(beg, end);
+ end++; // Skip trailing quote
+ }
+
+ if(end !== s.length && StringUtil.findFirstNotOf(s, delim, end) !== -1)
+ {
+ throw new Ice.ProxyParseException("invalid trailing characters after `" + s.substring(0, end + 1) +
+ "' in `" + s + "'");
+ }
+
+ try
+ {
+ adapter = StringUtil.unescapeString(adapterstr, 0, adapterstr.length);
+ }
+ catch(ex)
+ {
+ throw new Ice.ProxyParseException("invalid adapter id in `" + s + "': " + ex.message);
+ }
+ if(adapter.length === 0)
+ {
+ throw new Ice.ProxyParseException("empty adapter id in `" + s + "'");
+ }
+ return this.createImpl(ident, facet, mode, secure, protocol, encoding, null, adapter, propertyPrefix);
+ }
+
+ throw new Ice.ProxyParseException("malformed proxy `" + s + "'");
+ },
+ createFromStream: function(ident, s)
+ {
+ //
+ // Don't read the identity here. Operations calling this
+ // constructor read the identity, and pass it as a parameter.
+ //
+
+ if(ident.name.length === 0 && ident.category.length === 0)
+ {
+ return null;
+ }
+
+ //
+ // For compatibility with the old FacetPath.
+ //
+ var facetPath = StringSeqHelper.read(s); // String[]
+ var facet;
+ if(facetPath.length > 0)
+ {
+ if(facetPath.length > 1)
+ {
+ throw new Ice.ProxyUnmarshalException();
+ }
+ facet = facetPath[0];
+ }
+ else
+ {
+ facet = "";
+ }
+
+ var mode = s.readByte();
+ if(mode < 0 || mode > RefMode.ModeLast)
+ {
+ throw new Ice.ProxyUnmarshalException();
+ }
+
+ var secure = s.readBool();
+
+ var protocol = null;
+ var encoding = null;
+ if(!s.getReadEncoding().equals(Ice.Encoding_1_0))
+ {
+ protocol = new Ice.ProtocolVersion();
+ protocol.__read(s);
+ encoding = new Ice.EncodingVersion();
+ encoding.__read(s);
+ }
+ else
+ {
+ protocol = Ice.Protocol_1_0;
+ encoding = Ice.Encoding_1_0;
+ }
+
+ var endpoints = null; // EndpointI[]
+ var adapterId = null;
+
+ var sz = s.readSize();
+ if(sz > 0)
+ {
+ endpoints = [];
+ for(var i = 0; i < sz; i++)
+ {
+ endpoints[i] = this._instance.endpointFactoryManager().read(s);
+ }
+ }
+ else
+ {
+ adapterId = s.readString();
+ }
+
+ return this.createImpl(ident, facet, mode, secure, protocol, encoding, endpoints, adapterId, null);
+ },
+ setDefaultRouter: function(defaultRouter)
+ {
+ if(this._defaultRouter === null ? defaultRouter === null : this._defaultRouter.equals(defaultRouter))
+ {
+ return this;
+ }
+
+ var factory = new ReferenceFactory(this._instance, this._communicator);
+ factory._defaultLocator = this._defaultLocator;
+ factory._defaultRouter = defaultRouter;
+ return factory;
+ },
+ getDefaultRouter: function()
+ {
+ return this._defaultRouter;
+ },
+ setDefaultLocator: function(defaultLocator)
+ {
+ if(this._defaultLocator === null ? defaultLocator === null : this._defaultLocator.equals(defaultLocator))
+ {
+ return this;
+ }
+
+ var factory = new ReferenceFactory(this._instance, this._communicator);
+ factory._defaultRouter = this._defaultRouter;
+ factory._defaultLocator = defaultLocator;
+ return factory;
+ },
+ getDefaultLocator: function()
+ {
+ return this._defaultLocator;
+ },
+ checkForUnknownProperties: function(prefix)
+ {
+ var unknownProps = [], i, length;
+ //
+ // Do not warn about unknown properties for Ice prefixes (Ice, Glacier2, etc.)
+ //
+ for(i = 0; i < PropertyNames.clPropNames.length; ++i)
+ {
+ if(prefix.indexOf(PropertyNames.clPropNames[i] + ".") === 0)
+ {
+ return;
+ }
+ }
+
+ var props = this._instance.initializationData().properties.getPropertiesForPrefix(prefix + ".");
+ for(var e = props.entries; e !== null; e = e.next)
+ {
+ var valid = false;
+ for(i = 0, length = suffixes.length; i < length; ++i)
+ {
+ if(e.key === prefix + "." + suffixes[i])
+ {
+ valid = true;
+ break;
+ }
+ }
+
+ if(!valid)
+ {
+ unknownProps.push(e.key);
+ }
+ }
+
+ if(unknownProps.length > 0)
+ {
+ var message = [];
+ message.push("found unknown properties for proxy '");
+ message.push(prefix);
+ message.push("':");
+ for(i = 0, length = unknownProps.length; i < length; ++i)
+ {
+ message.push("\n ");
+ message.push(unknownProps[i]);
+ }
+ this._instance.initializationData().logger.warning(message.join(""));
+ }
+ },
+ createImpl: function(ident, facet, mode, secure, protocol, encoding, endpoints, adapterId,
+ propertyPrefix)
+ {
+ var defaultsAndOverrides = this._instance.defaultsAndOverrides();
+
+ //
+ // Default local proxy options.
+ //
+ var locatorInfo = null;
+ if(this._defaultLocator !== null)
+ {
+ if(!this._defaultLocator.__reference().getEncoding().equals(encoding))
+ {
+ locatorInfo = this._instance.locatorManager().find(this._defaultLocator.ice_encodingVersion(encoding));
+ }
+ else
+ {
+ locatorInfo = this._instance.locatorManager().find(this._defaultLocator);
+ }
+ }
+ var routerInfo = this._instance.routerManager().find(this._defaultRouter);
+ var cacheConnection = true;
+ var preferSecure = defaultsAndOverrides.defaultPreferSecure;
+ var endpointSelection = defaultsAndOverrides.defaultEndpointSelection;
+ var locatorCacheTimeout = defaultsAndOverrides.defaultLocatorCacheTimeout;
+
+ //
+ // Override the defaults with the proxy properties if a property prefix is defined.
+ //
+ if(propertyPrefix !== null && propertyPrefix.length > 0)
+ {
+ var properties = this._instance.initializationData().properties;
+
+ //
+ // Warn about unknown properties.
+ //
+ if(properties.getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0)
+ {
+ this.checkForUnknownProperties(propertyPrefix);
+ }
+
+ var property;
+
+ property = propertyPrefix + ".Locator";
+ var locator = LocatorPrx.uncheckedCast(this._communicator.propertyToProxy(property));
+ if(locator !== null)
+ {
+ if(!locator.__reference().getEncoding().equals(encoding))
+ {
+ locatorInfo = this._instance.locatorManager().find(locator.ice_encodingVersion(encoding));
+ }
+ else
+ {
+ locatorInfo = this._instance.locatorManager().find(locator);
+ }
+ }
+
+ property = propertyPrefix + ".Router";
+ var router = RouterPrx.uncheckedCast(this._communicator.propertyToProxy(property));
+ if(router !== null)
+ {
+ var match = ".Router";
+ if(propertyPrefix.lastIndexOf(match) == propertyPrefix.length - match.length)
+ {
+ var s = "`" + property + "=" + properties.getProperty(property) +
+ "': cannot set a router on a router; setting ignored";
+ this._instance.initializationData().logger.warning(s);
+ }
+ else
+ {
+ routerInfo = this._instance.routerManager().find(router);
+ }
+ }
+
+ property = propertyPrefix + ".ConnectionCached";
+ cacheConnection = properties.getPropertyAsIntWithDefault(property, cacheConnection ? 1 : 0) > 0;
+
+ property = propertyPrefix + ".PreferSecure";
+ preferSecure = properties.getPropertyAsIntWithDefault(property, preferSecure ? 1 : 0) > 0;
+
+ property = propertyPrefix + ".EndpointSelection";
+ if(properties.getProperty(property).length > 0)
+ {
+ var type = properties.getProperty(property);
+ if(type == "Random")
+ {
+ endpointSelection = EndpointSelectionType.Random;
+ }
+ else if(type == "Ordered")
+ {
+ endpointSelection = EndpointSelectionType.Ordered;
+ }
+ else
+ {
+ throw new Ice.EndpointSelectionTypeParseException("illegal value `" + type +
+ "'; expected `Random' or `Ordered'");
+ }
+ }
+
+ property = propertyPrefix + ".LocatorCacheTimeout";
+ locatorCacheTimeout = properties.getPropertyAsIntWithDefault(property, locatorCacheTimeout);
+ }
+
+ //
+ // Create new reference
+ //
+ return new RoutableReference(this._instance,
+ this._communicator,
+ ident,
+ facet,
+ mode,
+ secure,
+ protocol,
+ encoding,
+ endpoints,
+ adapterId,
+ locatorInfo,
+ routerInfo,
+ cacheConnection,
+ preferSecure,
+ endpointSelection,
+ locatorCacheTimeout);
+ }
+ });
+
+ Ice.ReferenceFactory = ReferenceFactory;
+
+ var Reference = Class({
+ __init__: function(instance, communicator, identity, facet, mode, secure, protocol, encoding)
+ {
+ //
+ // Validate string arguments.
+ //
+ Debug.assert(identity === undefined || identity.name !== null);
+ Debug.assert(identity === undefined || identity.category !== null);
+ Debug.assert(facet === undefined || facet !== null);
+
+ this._instance = instance;
+ this._communicator = communicator;
+ this._mode = mode;
+ this._secure = secure;
+ this._identity = identity;
+ this._context = Reference._emptyContext;
+ this._facet = facet;
+ this._protocol = protocol;
+ this._encoding = encoding;
+ this._hashInitialized = false;
+ this._overrideCompress = false;
+ this._compress = false; // Only used if _overrideCompress == true
+ },
+ getMode: function()
+ {
+ return this._mode;
+ },
+ getSecure: function()
+ {
+ return this._secure;
+ },
+ getProtocol: function()
+ {
+ return this._protocol;
+ },
+ getEncoding: function()
+ {
+ return this._encoding;
+ },
+ getIdentity: function()
+ {
+ return this._identity;
+ },
+ getFacet: function()
+ {
+ return this._facet;
+ },
+ getInstance: function()
+ {
+ return this._instance;
+ },
+ getContext: function()
+ {
+ return this._context; // HashMap
+ },
+ getCommunicator: function()
+ {
+ return this._communicator;
+ },
+ getEndpoints: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ getAdapterId: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return "";
+ },
+ getRouterInfo: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ getLocatorInfo: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ getCacheConnection: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return false;
+ },
+ getPreferSecure: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return false;
+ },
+ getEndpointSelection: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ getLocatorCacheTimeout: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return 0;
+ },
+ getConnectionId: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return "";
+ },
+ //
+ // The change* methods (here and in derived classes) create
+ // a new reference based on the existing one, with the
+ // corresponding value changed.
+ //
+ changeContext: function(newContext)
+ {
+ if(newContext === undefined || newContext === null)
+ {
+ newContext = Reference._emptyContext;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ if(newContext.size === 0)
+ {
+ r._context = Reference._emptyContext;
+ }
+ else
+ {
+ r._context = new HashMap(newContext);
+ }
+ return r;
+ },
+ changeMode: function(newMode)
+ {
+ if(newMode === this._mode)
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._mode = newMode;
+ return r;
+ },
+ changeSecure: function(newSecure)
+ {
+ if(newSecure === this._secure)
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._secure = newSecure;
+ return r;
+ },
+ changeIdentity: function(newIdentity)
+ {
+ if(newIdentity.equals(this._identity))
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._identity = new Identity(newIdentity.name, newIdentity.category);
+ return r;
+ },
+ changeFacet: function(newFacet)
+ {
+ if(newFacet === this._facet)
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._facet = newFacet;
+ return r;
+ },
+ changeEncoding: function(newEncoding)
+ {
+ if(newEncoding.equals(this._encoding))
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._encoding = newEncoding;
+ return r;
+ },
+ changeCompress: function(newCompress)
+ {
+ if(this._overrideCompress && this._compress === newCompress)
+ {
+ return this;
+ }
+ var r = this._instance.referenceFactory().copy(this);
+ r._compress = newCompress;
+ r._overrideCompress = true;
+ return r;
+ },
+ changeAdapterId: function(newAdapterId)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeEndpoints: function(newEndpoints)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeLocator: function(newLocator)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeRouter: function(newRouter)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeCacheConnection: function(newCache)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changePreferSecure: function(newPreferSecure)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeEndpointSelection: function(newType)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeLocatorCacheTimeout: function(newTimeout)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeTimeout: function(newTimeout)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ changeConnectionId: function(connectionId)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ hashCode: function()
+ {
+ if(this._hashInitialized)
+ {
+ return this._hashValue;
+ }
+
+ var h = 5381;
+ h = HashUtil.addNumber(h, this._mode);
+ h = HashUtil.addBoolean(h, this._secure);
+ h = HashUtil.addHashable(h, this._identity);
+ if(this._context !== null && this._context !== undefined)
+ {
+ for(var e = this._context.entries; e !== null; e = e.next)
+ {
+ h = HashUtil.addString(h, e.key);
+ h = HashUtil.addString(h, e.value);
+ }
+ }
+ h = HashUtil.addString(h, this._facet);
+ h = HashUtil.addBoolean(h, this._overrideCompress);
+ if(this._overrideCompress)
+ {
+ h = HashUtil.addBoolean(h, this._compress);
+ }
+ h = HashUtil.addHashable(h, this._protocol);
+ h = HashUtil.addHashable(h, this._encoding);
+
+ this._hashValue = h;
+ this._hashInitialized = true;
+
+ return this._hashValue;
+ },
+ //
+ // Utility methods
+ //
+ isIndirect: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return false;
+ },
+ isWellKnown: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return false;
+ },
+ //
+ // Marshal the reference.
+ //
+ streamWrite: function(s)
+ {
+ //
+ // Don't write the identity here. Operations calling streamWrite
+ // write the identity.
+ //
+
+ //
+ // For compatibility with the old FacetPath.
+ //
+ if(this._facet.length === 0)
+ {
+ s.writeSize(0); // Empty string sequence
+ }
+ else
+ {
+ s.writeSize(1); // String sequence with one element
+ s.writeString(this._facet);
+ }
+
+ s.writeByte(this._mode);
+
+ s.writeBool(this._secure);
+
+ if(!s.getWriteEncoding().equals(Ice.Encoding_1_0))
+ {
+ this._protocol.__write(s);
+ this._encoding.__write(s);
+ }
+
+ // Derived class writes the remainder of the reference.
+ },
+ //
+ // Convert the reference to its string form.
+ //
+ toString: function()
+ {
+ //
+ // WARNING: Certain features, such as proxy validation in Glacier2,
+ // depend on the format of proxy strings. Changes to toString() and
+ // methods called to generate parts of the reference string could break
+ // these features. Please review for all features that depend on the
+ // format of proxyToString() before changing this and related code.
+ //
+ var s = [];
+
+ //
+ // If the encoded identity string contains characters which
+ // the reference parser uses as separators, then we enclose
+ // the identity string in quotes.
+ //
+ var id = this._instance.identityToString(this._identity);
+ if(id.search(/[ :@]/) != -1)
+ {
+ s.push('"');
+ s.push(id);
+ s.push('"');
+ }
+ else
+ {
+ s.push(id);
+ }
+
+ if(this._facet.length > 0)
+ {
+ //
+ // If the encoded facet string contains characters which
+ // the reference parser uses as separators, then we enclose
+ // the facet string in quotes.
+ //
+ s.push(" -f ");
+ var fs = StringUtil.escapeString(this._facet, "");
+ if(fs.search(/[ :@]/) != -1)
+ {
+ s.push('"');
+ s.push(fs);
+ s.push('"');
+ }
+ else
+ {
+ s.push(fs);
+ }
+ }
+
+ switch(this._mode)
+ {
+ case RefMode.ModeTwoway:
+ {
+ s.push(" -t");
+ break;
+ }
+
+ case RefMode.ModeOneway:
+ {
+ s.push(" -o");
+ break;
+ }
+
+ case RefMode.ModeBatchOneway:
+ {
+ s.push(" -O");
+ break;
+ }
+
+ case RefMode.ModeDatagram:
+ {
+ s.push(" -d");
+ break;
+ }
+
+ case RefMode.ModeBatchDatagram:
+ {
+ s.push(" -D");
+ break;
+ }
+ }
+
+ if(this._secure)
+ {
+ s.push(" -s");
+ }
+
+ if(!this._protocol.equals(Ice.Protocol_1_0))
+ {
+ //
+ // We only print the protocol if it's not 1.0. It's fine as
+ // long as we don't add Ice.Default.ProtocolVersion, a
+ // stringified proxy will convert back to the same proxy with
+ // stringToProxy.
+ //
+ s.push(" -p ");
+ s.push(Ice.protocolVersionToString(this._protocol));
+ }
+
+ //
+ // Always print the encoding version to ensure a stringified proxy
+ // will convert back to a proxy with the same encoding with
+ // stringToProxy (and won't use Ice.Default.EncodingVersion).
+ //
+ s.push(" -e ");
+ s.push(Ice.encodingVersionToString(this._encoding));
+
+ return s.join("");
+
+ // Derived class writes the remainder of the string.
+ },
+ //
+ // Convert the reference to its property form.
+ //
+ toProperty: function(prefix)
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ getConnection: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ },
+ equals: function(r)
+ {
+ //
+ // Note: if(this === r) and type test are performed by each non-abstract derived class.
+ //
+
+ if(this._mode !== r._mode)
+ {
+ return false;
+ }
+
+ if(this._secure !== r._secure)
+ {
+ return false;
+ }
+
+ if(!this._identity.equals(r._identity))
+ {
+ return false;
+ }
+
+ if(!this._context.equals(r._context))
+ {
+ return false;
+ }
+
+ if(this._facet !== r._facet)
+ {
+ return false;
+ }
+
+ if(this._overrideCompress !== r._overrideCompress)
+ {
+ return false;
+ }
+ if(this._overrideCompress && this._compress !== r._compress)
+ {
+ return false;
+ }
+
+ if(!this._protocol.equals(r._protocol))
+ {
+ return false;
+ }
+
+ if(!this._encoding.equals(r._encoding))
+ {
+ return false;
+ }
+
+ return true;
+ },
+ clone: function()
+ {
+ // Abstract
+ Debug.assert(false);
+ return null;
+ },
+ copyMembers: function(r)
+ {
+ //
+ // Copy the members that are not passed to the constructor.
+ //
+ r._context = this._context;
+ r._overrideCompress = this._overrideCompress;
+ r._compress = this._compress;
+ }
+ });
+
+ Reference._emptyContext = new HashMap();
+ Reference._emptyEndpoints = [];
+
+ Ice.Reference = Reference;
+
+ var FixedReference = Class(Reference, {
+ __init__: function(instance, communicator, identity, facet, mode, secure, encoding, connection)
+ {
+ Reference.call(this, instance, communicator, identity, facet, mode, secure, Ice.Protocol_1_0, encoding);
+ this._fixedConnection = connection;
+ },
+ getEndpoints: function()
+ {
+ return Reference._emptyEndpoints;
+ },
+ getAdapterId: function()
+ {
+ return "";
+ },
+ getRouterInfo: function()
+ {
+ return null;
+ },
+ getLocatorInfo: function()
+ {
+ return null;
+ },
+ getCacheConnection: function()
+ {
+ return false;
+ },
+ getPreferSecure: function()
+ {
+ return false;
+ },
+ getEndpointSelection: function()
+ {
+ return EndpointSelectionType.Random;
+ },
+ getLocatorCacheTimeout: function()
+ {
+ return 0;
+ },
+ getConnectionId: function()
+ {
+ return "";
+ },
+ changeAdapterId: function(newAdapterId)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeEndpoints: function(newEndpoints)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeLocator: function(newLocator)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeRouter: function(newRouter)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeCacheConnection: function(newCache)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changePreferSecure: function(prefSec)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeEndpointSelection: function(newType)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeLocatorCacheTimeout: function(newTimeout)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeTimeout: function(newTimeout)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ changeConnectionId: function(connectionId)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ isIndirect: function()
+ {
+ return false;
+ },
+ isWellKnown: function()
+ {
+ return false;
+ },
+ streamWrite: function(s)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ toString: function()
+ {
+ throw new Ice.FixedProxyException();
+ },
+ toProperty: function(prefix)
+ {
+ throw new Ice.FixedProxyException();
+ },
+ clone: function()
+ {
+ var r = new FixedReference(this.getInstance(), this.getCommunicator(), this.getIdentity(), this.getFacet(),
+ this.getMode(), this.getSecure(), this.getEncoding(), this._fixedConnection);
+ this.copyMembers(r);
+ return r;
+ },
+ getConnectionInternal: function(compress)
+ {
+ switch(this.getMode())
+ {
+ case RefMode.ModeTwoway:
+ case RefMode.ModeOneway:
+ case RefMode.ModeBatchOneway:
+ {
+ if(this._fixedConnection.endpoint().datagram())
+ {
+ throw new Ice.NoEndpointException("");
+ }
+ break;
+ }
+
+ case RefMode.ModeDatagram:
+ case RefMode.ModeBatchDatagram:
+ {
+ if(!this._fixedConnection.endpoint().datagram())
+ {
+ throw new Ice.NoEndpointException("");
+ }
+ break;
+ }
+ }
+
+ //
+ // If a secure connection is requested or secure overrides is set,
+ // check if the connection is secure.
+ //
+ var secure;
+ var defaultsAndOverrides = this.getInstance().defaultsAndOverrides();
+ if(defaultsAndOverrides.overrideSecure)
+ {
+ secure = defaultsAndOverrides.overrideSecureValue;
+ }
+ else
+ {
+ secure = this.getSecure();
+ }
+ if(secure && !this._fixedConnection.endpoint().secure())
+ {
+ throw new Ice.NoEndpointException("");
+ }
+
+ this._fixedConnection.throwException(); // Throw in case our connection is already destroyed.
+
+ if(defaultsAndOverrides.overrideCompress)
+ {
+ compress.value = defaultsAndOverrides.overrideCompressValue;
+ }
+ else if(this._overrideCompress)
+ {
+ compress.value = this._compress;
+ }
+ else
+ {
+ compress.value = this._fixedConnection.endpoint().compress();
+ }
+ return this._fixedConnection;
+ },
+ getConnection: function()
+ {
+ var promise = new Promise(); // success callback receives (connection, compress)
+ try
+ {
+ var compress = { 'value': false };
+ var connection = this.getConnectionInternal(compress);
+ promise.succeed(connection, compress.value);
+ }
+ catch(ex)
+ {
+ promise.fail(ex);
+ }
+ return promise;
+ },
+ equals: function(rhs)
+ {
+ if(this === rhs)
+ {
+ return true;
+ }
+ if(!(rhs instanceof FixedReference))
+ {
+ return false;
+ }
+ if(!Reference.prototype.equals.call(this, rhs))
+ {
+ return false;
+ }
+ return this._fixedConnection.equals(rhs._fixedConnection);
+ }
+ });
+
+ Ice.FixedReference = FixedReference;
+
+ var RoutableReference = Class(Reference, {
+ __init__: function(instance, communicator, identity, facet, mode, secure, protocol, encoding, endpoints,
+ adapterId, locatorInfo, routerInfo, cacheConnection, preferSecure, endpointSelection,
+ locatorCacheTimeout)
+ {
+ Reference.call(this, instance, communicator, identity, facet, mode, secure, protocol, encoding);
+ this._endpoints = endpoints;
+ this._adapterId = adapterId;
+ this._locatorInfo = locatorInfo;
+ this._routerInfo = routerInfo;
+ this._cacheConnection = cacheConnection;
+ this._preferSecure = preferSecure;
+ this._endpointSelection = endpointSelection;
+ this._locatorCacheTimeout = locatorCacheTimeout;
+ this._overrideTimeout = false;
+ this._timeout = -1;
+
+ if(this._endpoints === null)
+ {
+ this._endpoints = Reference._emptyEndpoints;
+ }
+ if(this._adapterId === null)
+ {
+ this._adapterId = "";
+ }
+ this._connectionId = "";
+ Debug.assert(this._adapterId.length === 0 || this._endpoints.length === 0);
+ },
+ getEndpoints: function()
+ {
+ return this._endpoints;
+ },
+ getAdapterId: function()
+ {
+ return this._adapterId;
+ },
+ getRouterInfo: function()
+ {
+ return this._routerInfo;
+ },
+ getLocatorInfo: function()
+ {
+ return this._locatorInfo;
+ },
+ getCacheConnection: function()
+ {
+ return this._cacheConnection;
+ },
+ getPreferSecure: function()
+ {
+ return this._preferSecure;
+ },
+ getEndpointSelection: function()
+ {
+ return this._endpointSelection;
+ },
+ getLocatorCacheTimeout: function()
+ {
+ return this._locatorCacheTimeout;
+ },
+ getConnectionId: function()
+ {
+ return this._connectionId;
+ },
+ changeEncoding: function(newEncoding)
+ {
+ var r = Reference.prototype.changeEncoding.call(this, newEncoding);
+ if(r !== this)
+ {
+ var locInfo = r._locatorInfo;
+ if(locInfo !== null && !locInfo.getLocator().ice_getEncodingVersion().equals(newEncoding))
+ {
+ r._locatorInfo = this.getInstance().locatorManager().find(
+ locInfo.getLocator().ice_encodingVersion(newEncoding));
+ }
+ }
+ return r;
+ },
+ changeCompress: function(newCompress)
+ {
+ var r = Reference.prototype.changeCompress.call(this, newCompress);
+ if(r !== this && this._endpoints.length > 0) // Also override the compress flag on the endpoints if it was updated.
+ {
+ var newEndpoints = [];
+ for(var i = 0; i < this._endpoints.length; i++)
+ {
+ newEndpoints[i] = this._endpoints[i].changeCompress(newCompress);
+ }
+ r._endpoints = newEndpoints;
+ }
+ return r;
+ },
+ changeAdapterId: function(newAdapterId)
+ {
+ if(this._adapterId === newAdapterId)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._adapterId = newAdapterId;
+ r._endpoints = Reference._emptyEndpoints;
+ return r;
+ },
+ changeEndpoints: function(newEndpoints)
+ {
+ if(ArrayUtil.equals(newEndpoints, this._endpoints, function(e1, e2) { return e1.equals(e2); }))
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._endpoints = newEndpoints;
+ r._adapterId = "";
+ r.applyOverrides(r._endpoints);
+ return r;
+ },
+ changeLocator: function(newLocator)
+ {
+ var newLocatorInfo = this.getInstance().locatorManager().find(newLocator);
+ if(newLocatorInfo !== null && this._locatorInfo !== null && newLocatorInfo.equals(this._locatorInfo))
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._locatorInfo = newLocatorInfo;
+ return r;
+ },
+ changeRouter: function(newRouter)
+ {
+ var newRouterInfo = this.getInstance().routerManager().find(newRouter);
+ if(newRouterInfo !== null && this._routerInfo !== null && newRouterInfo.equals(this._routerInfo))
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._routerInfo = newRouterInfo;
+ return r;
+ },
+ changeCacheConnection: function(newCache)
+ {
+ if(newCache === this._cacheConnection)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._cacheConnection = newCache;
+ return r;
+ },
+ changePreferSecure: function(newPreferSecure)
+ {
+ if(newPreferSecure === this._preferSecure)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._preferSecure = newPreferSecure;
+ return r;
+ },
+ changeEndpointSelection: function(newType)
+ {
+ if(newType === this._endpointSelection)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._endpointSelection = newType;
+ return r;
+ },
+ changeLocatorCacheTimeout: function(newTimeout)
+ {
+ if(this._locatorCacheTimeout === newTimeout)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._locatorCacheTimeout = newTimeout;
+ return r;
+ },
+ changeTimeout: function(newTimeout)
+ {
+ if(this._overrideTimeout && this._timeout === newTimeout)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._timeout = newTimeout;
+ r._overrideTimeout = true;
+ if(this._endpoints.length > 0)
+ {
+ var newEndpoints = [];
+ for(var i = 0; i < this._endpoints.length; i++)
+ {
+ newEndpoints[i] = this._endpoints[i].changeTimeout(newTimeout);
+ }
+ r._endpoints = newEndpoints;
+ }
+ return r;
+ },
+ changeConnectionId: function(id)
+ {
+ if(this._connectionId === id)
+ {
+ return this;
+ }
+ var r = this.getInstance().referenceFactory().copy(this);
+ r._connectionId = id;
+ if(this._endpoints.length > 0)
+ {
+ var newEndpoints = [];
+ for(var i = 0; i < this._endpoints.length; i++)
+ {
+ newEndpoints[i] = this._endpoints[i].changeConnectionId(id);
+ }
+ r._endpoints = newEndpoints;
+ }
+ return r;
+ },
+ isIndirect: function()
+ {
+ return this._endpoints.length === 0;
+ },
+ isWellKnown: function()
+ {
+ return this._endpoints.length === 0 && this._adapterId.length === 0;
+ },
+ streamWrite: function(s)
+ {
+ Reference.prototype.streamWrite.call(this, s);
+
+ s.writeSize(this._endpoints.length);
+ if(this._endpoints.length > 0)
+ {
+ Debug.assert(this._adapterId.length === 0);
+ for(var i = 0; i < this._endpoints.length; ++i)
+ {
+ this._endpoints[i].streamWrite(s);
+ }
+ }
+ else
+ {
+ s.writeString(this._adapterId); // Adapter id.
+ }
+ },
+ toString: function()
+ {
+ //
+ // WARNING: Certain features, such as proxy validation in Glacier2,
+ // depend on the format of proxy strings. Changes to toString() and
+ // methods called to generate parts of the reference string could break
+ // these features. Please review for all features that depend on the
+ // format of proxyToString() before changing this and related code.
+ //
+ var s = [];
+ s.push(Reference.prototype.toString.call(this));
+ if(this._endpoints.length > 0)
+ {
+ for(var i = 0; i < this._endpoints.length; ++i)
+ {
+ var endp = this._endpoints[i].toString();
+ if(endp !== null && endp.length > 0)
+ {
+ s.push(':');
+ s.push(endp);
+ }
+ }
+ }
+ else if(this._adapterId.length > 0)
+ {
+ s.push(" @ ");
+
+ //
+ // If the encoded adapter id string contains characters which
+ // the reference parser uses as separators, then we enclose
+ // the adapter id string in quotes.
+ //
+ var a = StringUtil.escapeString(this._adapterId, null);
+ if(a.search(/[ :@]/) != -1)
+ {
+ s.push('"');
+ s.push(a);
+ s.push('"');
+ }
+ else
+ {
+ s.push(a);
+ }
+ }
+ return s.join("");
+ },
+ toProperty: function(prefix)
+ {
+ var properties = new HashMap(), e;
+
+ properties.set(prefix, this.toString());
+ properties.set(prefix + ".CollocationOptimized", "0");
+ properties.set(prefix + ".ConnectionCached", this._cacheConnection ? "1" : "0");
+ properties.set(prefix + ".PreferSecure", this._preferSecure ? "1" : "0");
+ properties.set(prefix + ".EndpointSelection",
+ this._endpointSelection === EndpointSelectionType.Random ? "Random" : "Ordered");
+
+ properties.set(prefix + ".LocatorCacheTimeout", "" + this._locatorCacheTimeout);
+
+ if(this._routerInfo !== null)
+ {
+ var h = this._routerInfo.getRouter();
+ var routerProperties = h.__reference().toProperty(prefix + ".Router");
+ for(e = routerProperties.entries; e !== null; e = e.next)
+ {
+ properties.set(e.key, e.value);
+ }
+ }
+
+ if(this._locatorInfo !== null)
+ {
+ var p = this._locatorInfo.getLocator();
+ var locatorProperties = p.__reference().toProperty(prefix + ".Locator");
+ for(e = locatorProperties.entries; e !== null; e = e.next)
+ {
+ properties.set(e.key, e.value);
+ }
+ }
+
+ return properties;
+ },
+ hashCode: function()
+ {
+ if(!this._hashInitialized)
+ {
+ Reference.prototype.hashCode.call(this); // Initializes _hashValue.
+ this._hashValue = HashUtil.addString(this._hashValue, this._adapterId);
+ }
+ return this._hashValue;
+ },
+ equals: function(rhs)
+ {
+ if(this === rhs)
+ {
+ return true;
+ }
+ if(!(rhs instanceof RoutableReference))
+ {
+ return false;
+ }
+
+ if(!Reference.prototype.equals.call(this, rhs))
+ {
+ return false;
+ }
+
+ if(this._locatorInfo === null ? rhs._locatorInfo !== null : !this._locatorInfo.equals(rhs._locatorInfo))
+ {
+ return false;
+ }
+ if(this._routerInfo === null ? rhs._routerInfo !== null : !this._routerInfo.equals(rhs._routerInfo))
+ {
+ return false;
+ }
+ if(this._cacheConnection !== rhs._cacheConnection)
+ {
+ return false;
+ }
+ if(this._preferSecure !== rhs._preferSecure)
+ {
+ return false;
+ }
+ if(this._endpointSelection !== rhs._endpointSelection)
+ {
+ return false;
+ }
+ if(this._locatorCacheTimeout !== rhs._locatorCacheTimeout)
+ {
+ return false;
+ }
+ if(this._connectionId !== rhs._connectionId)
+ {
+ return false;
+ }
+ if(this._overrideTimeout !== rhs._overrideTimeout)
+ {
+ return false;
+ }
+ if(this._overrideTimeout && this._timeout !== rhs._timeout)
+ {
+ return false;
+ }
+ if(!ArrayUtil.equals(this._endpoints, rhs._endpoints, function(e1, e2) { return e1.equals(e2); }))
+ {
+ return false;
+ }
+ if(this._adapterId !== rhs._adapterId)
+ {
+ return false;
+ }
+ return true;
+ },
+ getConnection: function()
+ {
+ var promise = new Promise(); // success callback receives (connection, compress)
+
+ if(this._routerInfo !== null)
+ {
+ //
+ // If we route, we send everything to the router's client
+ // proxy endpoints.
+ //
+ var self = this;
+ this._routerInfo.getClientEndpoints().then(
+ function(endpts)
+ {
+ if(endpts.length > 0)
+ {
+ self.applyOverrides(endpts);
+ self.createConnection(endpts).then(
+ function(connection, compress)
+ {
+ promise.succeed(connection, compress);
+ },
+ function(ex)
+ {
+ promise.fail(ex);
+ });
+ }
+ else
+ {
+ self.getConnectionNoRouterInfo(promise);
+ }
+ }).exception(
+ function(ex)
+ {
+ promise.fail(ex);
+ });
+ }
+ else
+ {
+ this.getConnectionNoRouterInfo(promise);
+ }
+
+ return promise;
+ },
+ getConnectionNoRouterInfo: function(promise)
+ {
+ if(this._endpoints.length > 0)
+ {
+ this.createConnection(this._endpoints).then(
+ function(connection, compress)
+ {
+ promise.succeed(connection, compress);
+ }).exception(
+ function(ex)
+ {
+ promise.fail(ex);
+ });
+ return;
+ }
+
+ var self = this;
+ if(this._locatorInfo !== null)
+ {
+ this._locatorInfo.getEndpoints(this, null, this._locatorCacheTimeout).then(
+ function(endpoints, cached)
+ {
+ if(endpoints.length === 0)
+ {
+ promise.fail(new Ice.NoEndpointException(self.toString()));
+ return;
+ }
+
+ self.applyOverrides(endpoints);
+ self.createConnection(endpoints).then(
+ function(connection, compress)
+ {
+ promise.succeed(connection, compress);
+ },
+ function(ex)
+ {
+ if(ex instanceof Ice.NoEndpointException)
+ {
+ //
+ // No need to retry if there's no endpoints.
+ //
+ promise.fail(ex);
+ }
+ else
+ {
+ Debug.assert(self._locatorInfo !== null);
+ self.getLocatorInfo().clearCache(self);
+ if(cached)
+ {
+ var traceLevels = self.getInstance().traceLevels();
+ if(traceLevels.retry >= 2)
+ {
+ var s = "connection to cached endpoints failed\n" +
+ "removing endpoints from cache and trying one more time\n" +
+ ExUtil.toString(ex);
+ self.getInstance().initializationData().logger.trace(
+ traceLevels.retryCat, s);
+ }
+ self.getConnectionNoRouterInfo(promise); // Retry.
+ return;
+ }
+ promise.fail(ex);
+ }
+ });
+ }).exception(
+ function(ex)
+ {
+ promise.fail(ex);
+ });
+ }
+ else
+ {
+ promise.fail(new Ice.NoEndpointException(this.toString()));
+ }
+ },
+ clone: function()
+ {
+ var r = new RoutableReference(this.getInstance(), this.getCommunicator(), this.getIdentity(), this.getFacet(),
+ this.getMode(), this.getSecure(), this.getProtocol(), this.getEncoding(),
+ this._endpoints, this._adapterId, this._locatorInfo, this._routerInfo,
+ this._cacheConnection, this._preferSecure, this._endpointSelection,
+ this._locatorCacheTimeout);
+ this.copyMembers(r);
+ return r;
+ },
+ copyMembers: function(rhs)
+ {
+ //
+ // Copy the members that are not passed to the constructor.
+ //
+ Reference.prototype.copyMembers.call(this, rhs);
+ rhs._overrideTimeout = this._overrideTimeout;
+ rhs._timeout = this._timeout;
+ rhs._connectionId = this._connectionId;
+ },
+ applyOverrides: function(endpts)
+ {
+ //
+ // Apply the endpoint overrides to each endpoint.
+ //
+ for(var i = 0; i < endpts.length; ++i)
+ {
+ endpts[i] = endpts[i].changeConnectionId(this._connectionId);
+ if(this._overrideCompress)
+ {
+ endpts[i] = endpts[i].changeCompress(this._compress);
+ }
+ if(this._overrideTimeout)
+ {
+ endpts[i] = endpts[i].changeTimeout(this._timeout);
+ }
+ }
+ },
+ filterEndpoints: function(allEndpoints)
+ {
+ var endpoints = [];
+
+ //
+ // Filter out opaque endpoints.
+ //
+ for(var i = 0; i < allEndpoints.length; ++i)
+ {
+ if(!(allEndpoints[i] instanceof OpaqueEndpointI))
+ {
+ endpoints.push(allEndpoints[i]);
+ }
+ }
+
+ //
+ // Filter out endpoints according to the mode of the reference.
+ //
+ switch(this.getMode())
+ {
+ case RefMode.ModeTwoway:
+ case RefMode.ModeOneway:
+ case RefMode.ModeBatchOneway:
+ {
+ //
+ // Filter out datagram endpoints.
+ //
+ endpoints = ArrayUtil.filter(endpoints, function(e, index, arr) { return !e.datagram(); });
+ break;
+ }
+
+ case RefMode.ModeDatagram:
+ case RefMode.ModeBatchDatagram:
+ {
+ //
+ // Filter out non-datagram endpoints.
+ //
+ endpoints = ArrayUtil.filter(endpoints, function(e, index, arr) { return e.datagram(); });
+ break;
+ }
+ }
+
+ //
+ // Sort the endpoints according to the endpoint selection type.
+ //
+ switch(this.getEndpointSelection())
+ {
+ case EndpointSelectionType.Random:
+ {
+ //
+ // Shuffle the endpoints.
+ //
+ ArrayUtil.shuffle(endpoints);
+ break;
+ }
+ case EndpointSelectionType.Ordered:
+ {
+ // Nothing to do.
+ break;
+ }
+ default:
+ {
+ Debug.assert(false);
+ break;
+ }
+ }
+
+ //
+ // If a secure connection is requested or secure overrides is
+ // set, remove all non-secure endpoints. Otherwise if preferSecure is set
+ // make secure endpoints prefered. By default make non-secure
+ // endpoints preferred over secure endpoints.
+ //
+ var overrides = this.getInstance().defaultsAndOverrides();
+ if(overrides.overrideSecure ? overrides.overrideSecureValue : this.getSecure())
+ {
+ endpoints = ArrayUtil.filter(endpoints, function(e, index, arr) { return e.secure(); });
+ }
+ else
+ {
+ var preferSecure = this.getPreferSecure();
+ var compare = function(e1, e2)
+ {
+ var ls = e1.secure();
+ var rs = e2.secure();
+ if((ls && rs) || (!ls && !rs))
+ {
+ return 0;
+ }
+ else if(!ls && rs)
+ {
+ return preferSecure ? 1 : -1;
+ }
+ else
+ {
+ return preferSecure ? -1 : 1;
+ }
+ };
+ endpoints.sort(compare);
+ }
+ return endpoints;
+ },
+ createConnection: function(allEndpoints)
+ {
+ var endpoints = this.filterEndpoints(allEndpoints);
+ if(endpoints.length === 0)
+ {
+ return new Promise().fail(new Ice.NoEndpointException(this.toString()));
+ }
+
+ //
+ // Finally, create the connection.
+ //
+ var promise = new Promise();
+ var factory = this.getInstance().outgoingConnectionFactory();
+ var cb;
+ if(this.getCacheConnection() || endpoints.length == 1)
+ {
+ //
+ // Get an existing connection or create one if there's no
+ // existing connection to one of the given endpoints.
+ //
+ cb = new CreateConnectionCallback(this, null, promise);
+ factory.create(endpoints, false, this.getEndpointSelection()).then(
+ function(connection, compress)
+ {
+ cb.setConnection(connection, compress);
+ }).exception(
+ function(ex)
+ {
+ cb.setException(ex);
+ });
+ }
+ else
+ {
+ //
+ // Go through the list of endpoints and try to create the
+ // connection until it succeeds. This is different from just
+ // calling create() with the given endpoints since this might
+ // create a new connection even if there's an existing
+ // connection for one of the endpoints.
+ //
+ var v = [ endpoints[0] ];
+ cb = new CreateConnectionCallback(this, endpoints, promise);
+ factory.create(v, true, this.getEndpointSelection()).then(
+ function(connection, compress)
+ {
+ cb.setConnection(connection, compress);
+ }).exception(
+ function(ex)
+ {
+ cb.setException(ex);
+ });
+ }
+
+ return promise;
+ }
+ });
+
+ Ice.RoutableReference = RoutableReference;
+ global.Ice = Ice;
+
+ var CreateConnectionCallback = Class({
+ __init__: function(r, endpoints, promise)
+ {
+ this.ref = r;
+ this.endpoints = endpoints;
+ this.promise = promise;
+ this.i = 0;
+ this.exception = null;
+ },
+ setConnection: function(connection, compress)
+ {
+ //
+ // If we have a router, set the object adapter for this router
+ // (if any) to the new connection, so that callbacks from the
+ // router can be received over this new connection.
+ //
+ if(this.ref.getRouterInfo() !== null && this.ref.getRouterInfo().getAdapter() !== null)
+ {
+ connection.setAdapter(this.ref.getRouterInfo().getAdapter());
+ }
+ this.promise.succeed(connection, compress);
+ },
+ setException: function(ex)
+ {
+ if(this.exception === null)
+ {
+ this.exception = ex;
+ }
+
+ if(this.endpoints === null || ++this.i === this.endpoints.length)
+ {
+ this.promise.fail(this.exception);
+ return;
+ }
+
+ var more = this.i != this.endpoints.length - 1;
+ var arr = [ this.endpoints[this.i] ];
+ var self = this;
+ this.ref.getInstance().outgoingConnectionFactory().create(arr, more, this.ref.getEndpointSelection()).then(
+ function(connection, compress)
+ {
+ self.setConnection(connection, compress);
+ }).exception(
+ function(ex)
+ {
+ self.setException(ex);
+ });
+ }
+ });
+}(typeof (global) === "undefined" ? window : global));