ICE 3.4.2
[php5-ice-freebsdport.git] / java / src / IceInternal / RoutableReference.java
blobc90a57f082a8f3e2195c484a4de45937218103b8
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 package IceInternal;
12 public class RoutableReference extends Reference
14 public final EndpointI[]
15 getEndpoints()
17 return _endpoints;
20 public final String
21 getAdapterId()
23 return _adapterId;
26 public final LocatorInfo
27 getLocatorInfo()
29 return _locatorInfo;
32 public final RouterInfo
33 getRouterInfo()
35 return _routerInfo;
38 public final boolean
39 getCollocationOptimized()
41 return _collocationOptimized;
44 public final boolean
45 getCacheConnection()
47 return _cacheConnection;
50 public final boolean
51 getPreferSecure()
53 return _preferSecure;
56 public final Ice.EndpointSelectionType
57 getEndpointSelection()
59 return _endpointSelection;
62 public final int
63 getLocatorCacheTimeout()
65 return _locatorCacheTimeout;
68 public final String
69 getConnectionId()
71 return _connectionId;
74 public Reference
75 changeCompress(boolean newCompress)
77 RoutableReference r = (RoutableReference)super.changeCompress(newCompress);
78 if(r != this && _endpoints.length > 0) // Also override the compress flag on the endpoints if it was updated.
80 EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
81 for(int i = 0; i < _endpoints.length; i++)
83 newEndpoints[i] = _endpoints[i].compress(newCompress);
85 r._endpoints = newEndpoints;
87 return r;
90 public Reference
91 changeEndpoints(EndpointI[] newEndpoints)
93 if(java.util.Arrays.equals(newEndpoints, _endpoints))
95 return this;
97 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
98 r._endpoints = newEndpoints;
99 r._adapterId = "";
100 r.applyOverrides(r._endpoints);
101 return r;
104 public Reference
105 changeAdapterId(String newAdapterId)
107 if(_adapterId.equals(newAdapterId))
109 return this;
111 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
112 r._adapterId = newAdapterId;
113 r._endpoints = _emptyEndpoints;
114 return r;
117 public Reference
118 changeLocator(Ice.LocatorPrx newLocator)
120 LocatorInfo newLocatorInfo = getInstance().locatorManager().get(newLocator);
121 if(newLocatorInfo != null && _locatorInfo != null && newLocatorInfo.equals(_locatorInfo))
123 return this;
125 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
126 r._locatorInfo = newLocatorInfo;
127 return r;
130 public Reference
131 changeRouter(Ice.RouterPrx newRouter)
133 RouterInfo newRouterInfo = getInstance().routerManager().get(newRouter);
134 if(newRouterInfo != null && _routerInfo != null && newRouterInfo.equals(_routerInfo))
136 return this;
138 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
139 r._routerInfo = newRouterInfo;
140 return r;
143 public Reference
144 changeCollocationOptimized(boolean newCollocationOptimized)
146 if(newCollocationOptimized == _collocationOptimized)
148 return this;
150 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
151 r._collocationOptimized = newCollocationOptimized;
152 return r;
155 public final Reference
156 changeCacheConnection(boolean newCache)
158 if(newCache == _cacheConnection)
160 return this;
162 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
163 r._cacheConnection = newCache;
164 return r;
167 public Reference
168 changePreferSecure(boolean newPreferSecure)
170 if(newPreferSecure == _preferSecure)
172 return this;
174 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
175 r._preferSecure = newPreferSecure;
176 return r;
179 public final Reference
180 changeEndpointSelection(Ice.EndpointSelectionType newType)
182 if(newType == _endpointSelection)
184 return this;
186 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
187 r._endpointSelection = newType;
188 return r;
191 public Reference
192 changeLocatorCacheTimeout(int newTimeout)
194 if(_locatorCacheTimeout == newTimeout)
196 return this;
198 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
199 r._locatorCacheTimeout = newTimeout;
200 return r;
203 public Reference
204 changeTimeout(int newTimeout)
206 if(_overrideTimeout && _timeout == newTimeout)
208 return this;
210 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
211 r._timeout = newTimeout;
212 r._overrideTimeout = true;
213 if(_endpoints.length > 0)
215 EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
216 for(int i = 0; i < _endpoints.length; i++)
218 newEndpoints[i] = _endpoints[i].timeout(newTimeout);
220 r._endpoints = newEndpoints;
222 return r;
225 public Reference
226 changeConnectionId(String id)
228 if(_connectionId.equals(id))
230 return this;
232 RoutableReference r = (RoutableReference)getInstance().referenceFactory().copy(this);
233 r._connectionId = id;
234 if(_endpoints.length > 0)
236 EndpointI[] newEndpoints = new EndpointI[_endpoints.length];
237 for(int i = 0; i < _endpoints.length; i++)
239 newEndpoints[i] = _endpoints[i].connectionId(id);
241 r._endpoints = newEndpoints;
243 return r;
246 public boolean
247 isIndirect()
249 return _endpoints.length == 0;
252 public boolean
253 isWellKnown()
255 return _endpoints.length == 0 && _adapterId.length() == 0;
258 public void
259 streamWrite(BasicStream s)
260 throws Ice.MarshalException
262 super.streamWrite(s);
264 s.writeSize(_endpoints.length);
265 if(_endpoints.length > 0)
267 assert(_adapterId.length() == 0);
268 for(EndpointI endpoint : _endpoints)
270 endpoint.streamWrite(s);
273 else
275 s.writeString(_adapterId); // Adapter id.
279 public String
280 toString()
283 // WARNING: Certain features, such as proxy validation in Glacier2,
284 // depend on the format of proxy strings. Changes to toString() and
285 // methods called to generate parts of the reference string could break
286 // these features. Please review for all features that depend on the
287 // format of proxyToString() before changing this and related code.
289 StringBuilder s = new StringBuilder(128);
290 s.append(super.toString());
291 if(_endpoints.length > 0)
293 for(EndpointI endpoint : _endpoints)
295 String endp = endpoint.toString();
296 if(endp != null && endp.length() > 0)
298 s.append(':');
299 s.append(endp);
303 else if(_adapterId.length() > 0)
305 s.append(" @ ");
308 // If the encoded adapter id string contains characters which
309 // the reference parser uses as separators, then we enclose
310 // the adapter id string in quotes.
312 String a = IceUtilInternal.StringUtil.escapeString(_adapterId, null);
313 if(IceUtilInternal.StringUtil.findFirstOf(a, " :@") != -1)
315 s.append('"');
316 s.append(a);
317 s.append('"');
319 else
321 s.append(a);
324 return s.toString();
327 public java.util.Map<String, String> toProperty(String prefix)
329 java.util.Map<String, String> properties = new java.util.HashMap<String, String>();
331 properties.put(prefix, toString());
332 properties.put(prefix + ".CollocationOptimized", _collocationOptimized ? "1" : "0");
333 properties.put(prefix + ".ConnectionCached", _cacheConnection ? "1" : "0");
334 properties.put(prefix + ".PreferSecure", _preferSecure ? "1" : "0");
335 properties.put(prefix + ".EndpointSelection",
336 _endpointSelection == Ice.EndpointSelectionType.Random ? "Random" : "Ordered");
338 StringBuffer s = new StringBuffer();
339 s.append(_locatorCacheTimeout);
340 properties.put(prefix + ".LocatorCacheTimeout", s.toString());
342 if(_routerInfo != null)
344 Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_routerInfo.getRouter();
345 java.util.Map<String, String> routerProperties = h.__reference().toProperty(prefix + ".Router");
346 for(java.util.Map.Entry<String, String> p : routerProperties.entrySet())
348 properties.put(p.getKey(), p.getValue());
352 if(_locatorInfo != null)
354 Ice.ObjectPrxHelperBase h = (Ice.ObjectPrxHelperBase)_locatorInfo.getLocator();
355 java.util.Map<String, String> locatorProperties = h.__reference().toProperty(prefix + ".Locator");
356 for(java.util.Map.Entry<String, String> p : locatorProperties.entrySet())
358 properties.put(p.getKey(), p.getValue());
362 return properties;
365 public synchronized int
366 hashCode()
368 if(!_hashInitialized)
370 super.hashCode(); // Initializes _hashValue.
372 // Add hash of adapter ID to base hash.
373 _hashValue = 5 * _hashValue + _adapterId.hashCode();
375 return _hashValue;
378 public boolean
379 equals(java.lang.Object obj)
381 if(this == obj)
383 return true;
385 if(!(obj instanceof RoutableReference))
387 return false;
390 if(!super.equals(obj))
392 return false;
394 RoutableReference rhs = (RoutableReference)obj; // Guaranteed to succeed.
395 if(_locatorInfo == null ? rhs._locatorInfo != null : !_locatorInfo.equals(rhs._locatorInfo))
397 return false;
399 if(_routerInfo == null ? rhs._routerInfo != null : !_routerInfo.equals(rhs._routerInfo))
401 return false;
403 if(_collocationOptimized != rhs._collocationOptimized)
405 return false;
407 if(_cacheConnection != rhs._cacheConnection)
409 return false;
411 if(_preferSecure != rhs._preferSecure)
413 return false;
415 if(_endpointSelection != rhs._endpointSelection)
417 return false;
419 if(_locatorCacheTimeout != rhs._locatorCacheTimeout)
421 return false;
423 if(!_connectionId.equals(rhs._connectionId))
425 return false;
427 if(_overrideTimeout != rhs._overrideTimeout)
429 return false;
431 if(_overrideTimeout && _timeout != rhs._timeout)
433 return false;
435 if(!java.util.Arrays.equals(_endpoints, rhs._endpoints))
437 return false;
439 if(!_adapterId.equals(rhs._adapterId))
441 return false;
443 return true;
446 public Ice.ConnectionI
447 getConnection(Ice.BooleanHolder comp)
449 if(_routerInfo != null)
452 // If we route, we send everything to the router's client
453 // proxy endpoints.
455 EndpointI[] endpts = _routerInfo.getClientEndpoints();
456 if(endpts.length > 0)
458 applyOverrides(endpts);
459 return createConnection(endpts, comp);
463 if(_endpoints.length > 0)
465 return createConnection(_endpoints, comp);
468 while(true)
470 Ice.BooleanHolder cached = new Ice.BooleanHolder(false);
471 EndpointI[] endpts = null;
472 if(_locatorInfo != null)
474 endpts = _locatorInfo.getEndpoints(this, _locatorCacheTimeout, cached);
475 applyOverrides(endpts);
478 if(endpts == null || endpts.length == 0)
480 throw new Ice.NoEndpointException(toString());
485 return createConnection(endpts, comp);
487 catch(Ice.NoEndpointException ex)
489 throw ex; // No need to retry if there's no endpoints.
491 catch(Ice.LocalException ex)
493 assert(_locatorInfo != null);
494 _locatorInfo.clearCache(this);
495 if(cached.value)
497 TraceLevels traceLevels = getInstance().traceLevels();
498 if(traceLevels.retry >= 2)
500 String s = "connection to cached endpoints failed\n" +
501 "removing endpoints from cache and trying one more time\n" + ex;
502 getInstance().initializationData().logger.trace(traceLevels.retryCat, s);
504 continue; // Try again if the endpoints were cached.
506 throw ex;
511 public void
512 getConnection(final GetConnectionCallback callback)
514 if(_routerInfo != null)
517 // If we route, we send everything to the router's client
518 // proxy endpoints.
520 _routerInfo.getClientEndpoints(new RouterInfo.GetClientEndpointsCallback()
522 public void
523 setEndpoints(EndpointI[] endpts)
525 if(endpts.length > 0)
527 applyOverrides(endpts);
528 createConnection(endpts, callback);
530 else
532 getConnectionNoRouterInfo(callback);
536 public void
537 setException(Ice.LocalException ex)
539 callback.setException(ex);
543 else
545 getConnectionNoRouterInfo(callback);
549 public void
550 getConnectionNoRouterInfo(final GetConnectionCallback callback)
552 if(_endpoints.length > 0)
554 createConnection(_endpoints, callback);
555 return;
558 final RoutableReference self = this;
559 if(_locatorInfo != null)
561 _locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorInfo.GetEndpointsCallback()
563 public void
564 setEndpoints(EndpointI[] endpoints, final boolean cached)
566 if(endpoints.length == 0)
568 callback.setException(new Ice.NoEndpointException(self.toString()));
569 return;
572 applyOverrides(endpoints);
573 createConnection(endpoints, new GetConnectionCallback()
575 public void
576 setConnection(Ice.ConnectionI connection, boolean compress)
578 callback.setConnection(connection, compress);
581 public void
582 setException(Ice.LocalException exc)
586 throw exc;
588 catch(Ice.NoEndpointException ex)
590 callback.setException(ex); // No need to retry if there's no endpoints.
592 catch(Ice.LocalException ex)
594 assert(_locatorInfo != null);
595 _locatorInfo.clearCache(self);
596 if(cached)
598 TraceLevels traceLvls = getInstance().traceLevels();
599 if(traceLvls.retry >= 2)
601 String s = "connection to cached endpoints failed\n" +
602 "removing endpoints from cache and trying one more time\n" + ex;
603 getInstance().initializationData().logger.trace(traceLvls.retryCat, s);
605 getConnectionNoRouterInfo(callback); // Retry.
606 return;
608 callback.setException(ex);
614 public void
615 setException(Ice.LocalException ex)
617 callback.setException(ex);
621 else
623 callback.setException(new Ice.NoEndpointException(toString()));
627 protected
628 RoutableReference(Instance instance,
629 Ice.Communicator communicator,
630 Ice.Identity identity,
631 String facet,
632 int mode,
633 boolean secure,
634 EndpointI[] endpoints,
635 String adapterId,
636 LocatorInfo locatorInfo,
637 RouterInfo routerInfo,
638 boolean collocationOptimized,
639 boolean cacheConnection,
640 boolean prefereSecure,
641 Ice.EndpointSelectionType endpointSelection,
642 int locatorCacheTimeout)
644 super(instance, communicator, identity, facet, mode, secure);
645 _endpoints = endpoints;
646 _adapterId = adapterId;
647 _locatorInfo = locatorInfo;
648 _routerInfo = routerInfo;
649 _collocationOptimized = collocationOptimized;
650 _cacheConnection = cacheConnection;
651 _preferSecure = prefereSecure;
652 _endpointSelection = endpointSelection;
653 _locatorCacheTimeout = locatorCacheTimeout;
654 _overrideTimeout = false;
655 _timeout = -1;
657 if(_endpoints == null)
659 _endpoints = _emptyEndpoints;
661 if(_adapterId == null)
663 _adapterId = "";
665 assert(_adapterId.length() == 0 || _endpoints.length == 0);
668 protected void
669 applyOverrides(EndpointI[] endpts)
672 // Apply the endpoint overrides to each endpoint.
674 for(int i = 0; i < endpts.length; ++i)
676 endpts[i] = endpts[i].connectionId(_connectionId);
677 if(_overrideCompress)
679 endpts[i] = endpts[i].compress(_compress);
681 if(_overrideTimeout)
683 endpts[i] = endpts[i].timeout(_timeout);
688 private EndpointI[]
689 filterEndpoints(EndpointI[] allEndpoints)
691 java.util.List<EndpointI> endpoints = new java.util.ArrayList<EndpointI>();
694 // Filter out opaque endpoints.
696 for(EndpointI endpoint : allEndpoints)
698 if(!(endpoint instanceof IceInternal.OpaqueEndpointI))
700 endpoints.add(endpoint);
705 // Filter out endpoints according to the mode of the reference.
707 switch(getMode())
709 case Reference.ModeTwoway:
710 case Reference.ModeOneway:
711 case Reference.ModeBatchOneway:
714 // Filter out datagram endpoints.
716 java.util.Iterator<EndpointI> i = endpoints.iterator();
717 while(i.hasNext())
719 EndpointI endpoint = i.next();
720 if(endpoint.datagram())
722 i.remove();
725 break;
728 case Reference.ModeDatagram:
729 case Reference.ModeBatchDatagram:
732 // Filter out non-datagram endpoints.
734 java.util.Iterator<EndpointI> i = endpoints.iterator();
735 while(i.hasNext())
737 EndpointI endpoint = i.next();
738 if(!endpoint.datagram())
740 i.remove();
743 break;
748 // Sort the endpoints according to the endpoint selection type.
750 switch(getEndpointSelection())
752 case Random:
754 java.util.Collections.shuffle(endpoints);
755 break;
757 case Ordered:
759 // Nothing to do.
760 break;
762 default:
764 assert(false);
765 break;
770 // If a secure connection is requested or secure overrides is
771 // set, remove all non-secure endpoints. Otherwise if preferSecure is set
772 // make secure endpoints prefered. By default make non-secure
773 // endpoints preferred over secure endpoints.
775 DefaultsAndOverrides overrides = getInstance().defaultsAndOverrides();
776 if(overrides.overrideSecure ? overrides.overrideSecureValue : getSecure())
778 java.util.Iterator<EndpointI> i = endpoints.iterator();
779 while(i.hasNext())
781 EndpointI endpoint = i.next();
782 if(!endpoint.secure())
784 i.remove();
788 else if(getPreferSecure())
790 java.util.Collections.sort(endpoints, _preferSecureEndpointComparator);
792 else
794 java.util.Collections.sort(endpoints, _preferNonSecureEndpointComparator);
797 return (EndpointI[])endpoints.toArray(new EndpointI[endpoints.size()]);
800 protected Ice.ConnectionI
801 createConnection(EndpointI[] allEndpoints, Ice.BooleanHolder compress)
803 EndpointI[] endpoints = filterEndpoints(allEndpoints);
804 if(endpoints.length == 0)
806 throw new Ice.NoEndpointException(toString());
810 // Finally, create the connection.
812 OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory();
813 Ice.ConnectionI connection = null;
814 if(getCacheConnection() || endpoints.length == 1)
817 // Get an existing connection or create one if there's no
818 // existing connection to one of the given endpoints.
820 connection = factory.create(endpoints, false, getEndpointSelection(), compress);
822 else
825 // Go through the list of endpoints and try to create the
826 // connection until it succeeds. This is different from just
827 // calling create() with the given endpoints since this might
828 // create a new connection even if there's an existing
829 // connection for one of the endpoints.
832 Ice.LocalException exception = null;
833 EndpointI[] endpoint = new EndpointI[1];
834 for(int i = 0; i < endpoints.length; ++i)
838 endpoint[0] = endpoints[i];
839 final boolean more = i != endpoints.length - 1;
840 connection = factory.create(endpoint, more, getEndpointSelection(), compress);
841 break;
843 catch(Ice.LocalException ex)
845 exception = ex;
849 if(connection == null)
851 assert(exception != null);
852 throw exception;
856 assert(connection != null);
859 // If we have a router, set the object adapter for this router
860 // (if any) to the new connection, so that callbacks from the
861 // router can be received over this new connection.
863 if(_routerInfo != null && _routerInfo.getAdapter() != null)
865 connection.setAdapter(_routerInfo.getAdapter());
868 return connection;
871 protected void
872 createConnection(EndpointI[] allEndpoints, final GetConnectionCallback callback)
874 final EndpointI[] endpoints = filterEndpoints(allEndpoints);
875 if(endpoints.length == 0)
877 callback.setException(new Ice.NoEndpointException(toString()));
878 return;
882 // Finally, create the connection.
884 final OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory();
885 if(getCacheConnection() || endpoints.length == 1)
888 // Get an existing connection or create one if there's no
889 // existing connection to one of the given endpoints.
891 factory.create(endpoints, false, getEndpointSelection(),
892 new OutgoingConnectionFactory.CreateConnectionCallback()
894 public void
895 setConnection(Ice.ConnectionI connection, boolean compress)
898 // If we have a router, set the object adapter for this router
899 // (if any) to the new connection, so that callbacks from the
900 // router can be received over this new connection.
902 if(_routerInfo != null && _routerInfo.getAdapter() != null)
904 connection.setAdapter(_routerInfo.getAdapter());
906 callback.setConnection(connection, compress);
909 public void
910 setException(Ice.LocalException ex)
912 callback.setException(ex);
916 else
919 // Go through the list of endpoints and try to create the
920 // connection until it succeeds. This is different from just
921 // calling create() with the given endpoints since this might
922 // create a new connection even if there's an existing
923 // connection for one of the endpoints.
926 factory.create(new EndpointI[]{ endpoints[0] }, true, getEndpointSelection(),
927 new OutgoingConnectionFactory.CreateConnectionCallback()
929 public void
930 setConnection(Ice.ConnectionI connection, boolean compress)
933 // If we have a router, set the object adapter for this router
934 // (if any) to the new connection, so that callbacks from the
935 // router can be received over this new connection.
937 if(_routerInfo != null && _routerInfo.getAdapter() != null)
939 connection.setAdapter(_routerInfo.getAdapter());
941 callback.setConnection(connection, compress);
944 public void
945 setException(final Ice.LocalException ex)
947 if(_exception == null)
949 _exception = ex;
952 if(++_i == endpoints.length)
954 callback.setException(_exception);
955 return;
958 final boolean more = _i != endpoints.length - 1;
959 final EndpointI[] endpoint = new EndpointI[]{ endpoints[_i] };
960 factory.create(endpoint, more, getEndpointSelection(), this);
963 private int _i = 0;
964 private Ice.LocalException _exception = null;
969 static class EndpointComparator implements java.util.Comparator<EndpointI>
971 EndpointComparator(boolean preferSecure)
973 _preferSecure = preferSecure;
976 public int
977 compare(EndpointI le, EndpointI re)
979 boolean ls = le.secure();
980 boolean rs = re.secure();
981 if((ls && rs) || (!ls && !rs))
983 return 0;
985 else if(!ls && rs)
987 if(_preferSecure)
989 return 1;
991 else
993 return -1;
996 else
998 if(_preferSecure)
1000 return -1;
1002 else
1004 return 1;
1009 private boolean _preferSecure;
1012 private static EndpointComparator _preferNonSecureEndpointComparator = new EndpointComparator(false);
1013 private static EndpointComparator _preferSecureEndpointComparator = new EndpointComparator(true);
1014 private static EndpointI[] _emptyEndpoints = new EndpointI[0];
1016 private EndpointI[] _endpoints;
1017 private String _adapterId;
1018 private LocatorInfo _locatorInfo; // Null if no router is used.
1019 private RouterInfo _routerInfo; // Null if no router is used.
1020 private boolean _collocationOptimized;
1021 private boolean _cacheConnection;
1022 private boolean _preferSecure;
1023 private Ice.EndpointSelectionType _endpointSelection;
1024 private int _locatorCacheTimeout;
1026 private boolean _overrideTimeout;
1027 private int _timeout; // Only used if _overrideTimeout == true
1028 private String _connectionId = "";