diff options
author | Joe George <joe@zeroc.com> | 2015-03-03 17:30:50 -0500 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2015-05-12 11:41:55 -0400 |
commit | d35bb9f5c19e34aee31f83d445695a8186ef675e (patch) | |
tree | d5324eaf44f5f9776495537c51653f50a66a7237 /java/src/IceInternal/ReferenceFactory.java | |
download | ice-d35bb9f5c19e34aee31f83d445695a8186ef675e.tar.bz2 ice-d35bb9f5c19e34aee31f83d445695a8186ef675e.tar.xz ice-d35bb9f5c19e34aee31f83d445695a8186ef675e.zip |
Ice 3.4.2 Source Distributionv3.4.2
Diffstat (limited to 'java/src/IceInternal/ReferenceFactory.java')
-rw-r--r-- | java/src/IceInternal/ReferenceFactory.java | 830 |
1 files changed, 830 insertions, 0 deletions
diff --git a/java/src/IceInternal/ReferenceFactory.java b/java/src/IceInternal/ReferenceFactory.java new file mode 100644 index 00000000000..6388ebe5f45 --- /dev/null +++ b/java/src/IceInternal/ReferenceFactory.java @@ -0,0 +1,830 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 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. +// +// ********************************************************************** + +package IceInternal; + +public final class ReferenceFactory +{ + public Reference + create(Ice.Identity ident, String facet, Reference tmpl, EndpointI[] endpoints) + { + if(ident.name.length() == 0 && ident.category.length() == 0) + { + return null; + } + + return create(ident, facet, tmpl.getMode(), tmpl.getSecure(), endpoints, null, null); + } + + public Reference + create(Ice.Identity ident, String facet, Reference tmpl, String adapterId) + { + if(ident.name.length() == 0 && ident.category.length() == 0) + { + return null; + } + + return create(ident, facet, tmpl.getMode(), tmpl.getSecure(), null, adapterId, null); + } + + public Reference + create(Ice.Identity ident, Ice.ConnectionI fixedConnection) + { + if(ident.name.length() == 0 && ident.category.length() == 0) + { + return null; + } + + // + // Create new reference + // + FixedReference ref = new FixedReference( + _instance, + _communicator, + ident, + "", // Facet + fixedConnection.endpoint().datagram() ? Reference.ModeDatagram : Reference.ModeTwoway, + fixedConnection.endpoint().secure(), + fixedConnection); + return updateCache(ref); + } + + public Reference + copy(Reference r) + { + Ice.Identity ident = r.getIdentity(); + if(ident.name.length() == 0 && ident.category.length() == 0) + { + return null; + } + return (Reference)r.clone(); + } + + public Reference + create(String s, String propertyPrefix) + { + if(s == null || s.length() == 0) + { + return null; + } + + final String delim = " \t\n\r"; + + int beg; + int end = 0; + + beg = IceUtilInternal.StringUtil.findFirstNotOf(s, delim, end); + if(beg == -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "no non-whitespace characters found in `" + s + "'"; + throw e; + } + + // + // Extract the identity, which may be enclosed in single + // or double quotation marks. + // + String idstr = null; + end = IceUtilInternal.StringUtil.checkQuote(s, beg); + if(end == -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "mismatched quotes around identity in `" + s + "'"; + throw e; + } + else if(end == 0) + { + end = IceUtilInternal.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) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "no identity in `" + s + "'"; + throw e; + } + + // + // Parsing the identity may raise IdentityParseException. + // + Ice.Identity ident = _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) + { + Ice.IllegalIdentityException e = new Ice.IllegalIdentityException(); + e.id = ident; + throw e; + } + // + // 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(IceUtilInternal.StringUtil.findFirstNotOf(s, delim, end) != -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "invalid characters after identity in `" + s + "'"; + throw e; + } + else + { + return null; + } + } + + String facet = ""; + int mode = Reference.ModeTwoway; + boolean secure = false; + String adapter = ""; + + while(true) + { + beg = IceUtilInternal.StringUtil.findFirstNotOf(s, delim, end); + if(beg == -1) + { + break; + } + + if(s.charAt(beg) == ':' || s.charAt(beg) == '@') + { + break; + } + + end = IceUtilInternal.StringUtil.findFirstOf(s, delim + ":@", beg); + if(end == -1) + { + end = s.length(); + } + + if(beg == end) + { + break; + } + + String option = s.substring(beg, end); + if(option.length() != 2 || option.charAt(0) != '-') + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "expected a proxy option but found `" + option + "' in `" + s + "'"; + throw e; + } + + // + // Check for the presence of an option argument. The + // argument may be enclosed in single or double + // quotation marks. + // + String argument = null; + int argumentBeg = IceUtilInternal.StringUtil.findFirstNotOf(s, delim, end); + if(argumentBeg != -1) + { + final char ch = s.charAt(argumentBeg); + if(ch != '@' && ch != ':' && ch != '-') + { + beg = argumentBeg; + end = IceUtilInternal.StringUtil.checkQuote(s, beg); + if(end == -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "mismatched quotes around value for " + option + " option in `" + s + "'"; + throw e; + } + else if(end == 0) + { + end = IceUtilInternal.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) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "no argument provided for -f option in `" + s + "'"; + throw e; + } + + try + { + facet = IceUtilInternal.StringUtil.unescapeString(argument, 0, argument.length()); + } + catch(IllegalArgumentException ex) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "invalid facet in `" + s + "': " + ex.getMessage(); + throw e; + } + + break; + } + + case 't': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -t option in `" + s + "'"; + throw e; + } + mode = Reference.ModeTwoway; + break; + } + + case 'o': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -o option in `" + s + "'"; + throw e; + } + mode = Reference.ModeOneway; + break; + } + + case 'O': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -O option in `" + s + "'"; + throw e; + } + mode = Reference.ModeBatchOneway; + break; + } + + case 'd': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -d option in `" + s + "'"; + throw e; + } + mode = Reference.ModeDatagram; + break; + } + + case 'D': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -D option in `" + s + "'"; + throw e; + } + mode = Reference.ModeBatchDatagram; + break; + } + + case 's': + { + if(argument != null) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unexpected argument `" + argument + "' provided for -s option in `" + s + "'"; + throw e; + } + secure = true; + break; + } + + default: + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "unknown option `" + option + "' in `" + s + "'"; + throw e; + } + } + } + + if(beg == -1) + { + return create(ident, facet, mode, secure, null, null, propertyPrefix); + } + + java.util.ArrayList<EndpointI> endpoints = new java.util.ArrayList<EndpointI>(); + + if(s.charAt(beg) == ':') + { + java.util.ArrayList<String> unknownEndpoints = new java.util.ArrayList<String>(); + 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 + { + boolean quoted = false; + int 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; + } + } + + String es = s.substring(beg, end); + EndpointI endp = _instance.endpointFactoryManager().create(es, false); + if(endp != null) + { + endpoints.add(endp); + } + else + { + unknownEndpoints.add(es); + } + } + if(endpoints.size() == 0) + { + assert(!unknownEndpoints.isEmpty()); + Ice.EndpointParseException e = new Ice.EndpointParseException(); + e.str = "invalid endpoint `" + unknownEndpoints.get(0) + "' in `" + s + "'"; + throw e; + } + else if(unknownEndpoints.size() != 0 && + _instance.initializationData().properties.getPropertyAsIntWithDefault("Ice.Warn.Endpoints", 1) > 0) + { + StringBuffer msg = new StringBuffer("Proxy contains unknown endpoints:"); + for(String e : unknownEndpoints) + { + msg.append(" `"); + msg.append(e); + msg.append("'"); + } + _instance.initializationData().logger.warning(msg.toString()); + } + + EndpointI[] endp = new EndpointI[endpoints.size()]; + endpoints.toArray(endp); + return create(ident, facet, mode, secure, endp, null, propertyPrefix); + } + else if(s.charAt(beg) == '@') + { + beg = IceUtilInternal.StringUtil.findFirstNotOf(s, delim, beg + 1); + if(beg == -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "missing adapter id in `" + s + "'"; + throw e; + } + + String adapterstr = null; + end = IceUtilInternal.StringUtil.checkQuote(s, beg); + if(end == -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "mismatched quotes around adapter id in `" + s + "'"; + throw e; + } + else if(end == 0) + { + end = IceUtilInternal.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() && IceUtilInternal.StringUtil.findFirstNotOf(s, delim, end) != -1) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "invalid trailing characters after `" + s.substring(0, end + 1) + "' in `" + s + "'"; + throw e; + } + + try + { + adapter = IceUtilInternal.StringUtil.unescapeString(adapterstr, 0, adapterstr.length()); + } + catch(IllegalArgumentException ex) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "invalid adapter id in `" + s + "': " + ex.getMessage(); + throw e; + } + if(adapter.length() == 0) + { + Ice.ProxyParseException e = new Ice.ProxyParseException(); + e.str = "empty adapter id in `" + s + "'"; + throw e; + } + return create(ident, facet, mode, secure, null, adapter, propertyPrefix); + } + + Ice.ProxyParseException ex = new Ice.ProxyParseException(); + ex.str = "malformed proxy `" + s + "'"; + throw ex; + } + + public Reference + create(Ice.Identity ident, BasicStream 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. + // + String[] facetPath = s.readStringSeq(); + String facet; + if(facetPath.length > 0) + { + if(facetPath.length > 1) + { + throw new Ice.ProxyUnmarshalException(); + } + facet = facetPath[0]; + } + else + { + facet = ""; + } + + int mode = (int)s.readByte(); + if(mode < 0 || mode > Reference.ModeLast) + { + throw new Ice.ProxyUnmarshalException(); + } + + boolean secure = s.readBool(); + + EndpointI[] endpoints = null; + String adapterId = null; + + int sz = s.readSize(); + if(sz > 0) + { + endpoints = new EndpointI[sz]; + for(int i = 0; i < sz; i++) + { + endpoints[i] = _instance.endpointFactoryManager().read(s); + } + } + else + { + adapterId = s.readString(); + } + + return create(ident, facet, mode, secure, endpoints, adapterId, null); + } + + public ReferenceFactory + setDefaultRouter(Ice.RouterPrx defaultRouter) + { + if(_defaultRouter == null ? defaultRouter == null : _defaultRouter.equals(defaultRouter)) + { + return this; + } + + ReferenceFactory factory = new ReferenceFactory(_instance, _communicator); + factory._defaultLocator = _defaultLocator; + factory._defaultRouter = defaultRouter; + return factory; + } + + public Ice.RouterPrx + getDefaultRouter() + { + return _defaultRouter; + } + + public ReferenceFactory + setDefaultLocator(Ice.LocatorPrx defaultLocator) + { + if(_defaultLocator == null ? defaultLocator == null : _defaultLocator.equals(defaultLocator)) + { + return this; + } + + ReferenceFactory factory = new ReferenceFactory(_instance, _communicator); + factory._defaultRouter = _defaultRouter; + factory._defaultLocator = defaultLocator; + return factory; + } + + public Ice.LocatorPrx + getDefaultLocator() + { + return _defaultLocator; + } + + // + // Only for use by Instance + // + ReferenceFactory(Instance instance, Ice.Communicator communicator) + { + _instance = instance; + _communicator = communicator; + } + + synchronized void + destroy() + { + _references.clear(); + } + + synchronized private Reference + updateCache(Reference ref) + { + // + // If we already have an equivalent reference, use such equivalent + // reference. Otherwise add the new reference to the reference + // set. + // + // Java implementation note: A WeakHashMap is used to hold References, + // allowing References to be garbage collected automatically. A + // Reference serves as both key and value in the map. The + // WeakHashMap class internally creates a weak reference for the + // key, and we use a weak reference for the value as well. + // + java.lang.ref.WeakReference<Reference> w = _references.get(ref); + if(w != null) + { + Reference r = w.get(); + if(r != null) + { + ref = r; + } + else + { + _references.put(ref, new java.lang.ref.WeakReference<Reference>(ref)); + } + } + else + { + _references.put(ref, new java.lang.ref.WeakReference<Reference>(ref)); + } + + return ref; + } + + static private String[] _suffixes = + { + "EndpointSelection", + "ConnectionCached", + "PreferSecure", + "LocatorCacheTimeout", + "Locator", + "Router", + "CollocationOptimized" + }; + + private void + checkForUnknownProperties(String prefix) + { + // + // Do not warn about unknown properties if Ice prefix, ie Ice, Glacier2, etc + // + for(int i = 0; IceInternal.PropertyNames.clPropNames[i] != null; ++i) + { + if(prefix.startsWith(IceInternal.PropertyNames.clPropNames[i] + ".")) + { + return; + } + } + + java.util.ArrayList<String> unknownProps = new java.util.ArrayList<String>(); + java.util.Map<String, String> props = + _instance.initializationData().properties.getPropertiesForPrefix(prefix + "."); + for(java.util.Map.Entry<String, String> p : props.entrySet()) + { + String prop = p.getKey(); + + boolean valid = false; + for(String suffix : _suffixes) + { + if(prop.equals(prefix + "." + suffix)) + { + valid = true; + break; + } + } + + if(!valid) + { + unknownProps.add(prop); + } + } + + if(unknownProps.size() != 0) + { + StringBuffer message = new StringBuffer("found unknown properties for proxy '"); + message.append(prefix); + message.append("':"); + for(String s : unknownProps) + { + message.append("\n "); + message.append(s); + } + _instance.initializationData().logger.warning(message.toString()); + } + } + + private Reference + create(Ice.Identity ident, String facet, int mode, boolean secure, EndpointI[] endpoints, String adapterId, + String propertyPrefix) + { + DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + + // + // Default local proxy options. + // + LocatorInfo locatorInfo = _instance.locatorManager().get(_defaultLocator); + RouterInfo routerInfo = _instance.routerManager().get(_defaultRouter); + boolean collocationOptimized = defaultsAndOverrides.defaultCollocationOptimization; + boolean cacheConnection = true; + boolean preferSecure = defaultsAndOverrides.defaultPreferSecure; + Ice.EndpointSelectionType endpointSelection = defaultsAndOverrides.defaultEndpointSelection; + int locatorCacheTimeout = defaultsAndOverrides.defaultLocatorCacheTimeout; + + // + // Override the defaults with the proxy properties if a property prefix is defined. + // + if(propertyPrefix != null && propertyPrefix.length() > 0) + { + Ice.Properties properties = _instance.initializationData().properties; + + // + // Warn about unknown properties. + // + if(properties.getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) + { + checkForUnknownProperties(propertyPrefix); + } + + String property; + + property = propertyPrefix + ".Locator"; + Ice.LocatorPrx locator = Ice.LocatorPrxHelper.uncheckedCast(_communicator.propertyToProxy(property)); + if(locator != null) + { + locatorInfo = _instance.locatorManager().get(locator); + } + + property = propertyPrefix + ".Router"; + Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(_communicator.propertyToProxy(property)); + if(router != null) + { + if(propertyPrefix.endsWith(".Router")) + { + String s = "`" + property + "=" + properties.getProperty(property) + + "': cannot set a router on a router; setting ignored"; + _instance.initializationData().logger.warning(s); + } + else + { + routerInfo = _instance.routerManager().get(router); + } + } + + property = propertyPrefix + ".CollocationOptimized"; + collocationOptimized = properties.getPropertyAsIntWithDefault(property, collocationOptimized ? 1 : 0) > 0; + + 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) + { + String type = properties.getProperty(property); + if(type.equals("Random")) + { + endpointSelection = Ice.EndpointSelectionType.Random; + } + else if(type.equals("Ordered")) + { + endpointSelection = Ice.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 updateCache(new RoutableReference(_instance, + _communicator, + ident, + facet, + mode, + secure, + endpoints, + adapterId, + locatorInfo, + routerInfo, + collocationOptimized, + cacheConnection, + preferSecure, + endpointSelection, + locatorCacheTimeout)); + } + + final private Instance _instance; + final private Ice.Communicator _communicator; + private Ice.RouterPrx _defaultRouter; + private Ice.LocatorPrx _defaultLocator; + private java.util.WeakHashMap<Reference, java.lang.ref.WeakReference<Reference> > _references = + new java.util.WeakHashMap<Reference, java.lang.ref.WeakReference<Reference> >(); +} |