1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <Ice/Communicator.h>
6 #include <Ice/ReferenceFactory.h>
7 #include <Ice/ProxyFactory.h>
8 #include <Ice/LocalException.h>
9 #include <Ice/Instance.h>
10 #include <Ice/EndpointI.h>
11 #include <Ice/ConnectionI.h>
12 #include <Ice/EndpointFactoryManager.h>
13 #include <Ice/RouterInfo.h>
14 #include <Ice/Router.h>
15 #include <Ice/LocatorInfo.h>
16 #include <Ice/Locator.h>
17 #include <Ice/LoggerUtil.h>
18 #include <Ice/InputStream.h>
19 #include <Ice/Properties.h>
20 #include <Ice/DefaultsAndOverrides.h>
21 #include <Ice/PropertyNames.h>
22 #include <Ice/StringUtil.h>
23
24 using namespace std;
25 using namespace Ice;
26 using namespace IceInternal;
27
upCast(::IceInternal::ReferenceFactory * p)28 IceUtil::Shared* IceInternal::upCast(::IceInternal::ReferenceFactory* p) { return p; }
29
30 ReferencePtr
copy(const Reference * r) const31 IceInternal::ReferenceFactory::copy(const Reference* r) const
32 {
33 const Ice::Identity& ident = r->getIdentity();
34 if(ident.name.empty() && ident.category.empty())
35 {
36 return 0;
37 }
38
39 return r->clone();
40 }
41
42 ReferencePtr
create(const Identity & ident,const string & facet,const ReferencePtr & tmpl,const vector<EndpointIPtr> & endpoints)43 IceInternal::ReferenceFactory::create(const Identity& ident,
44 const string& facet,
45 const ReferencePtr& tmpl,
46 const vector<EndpointIPtr>& endpoints)
47 {
48 if(ident.name.empty() && ident.category.empty())
49 {
50 return 0;
51 }
52
53 return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), tmpl->getProtocol(), tmpl->getEncoding(),
54 endpoints, "", "");
55 }
56
57 ReferencePtr
create(const Identity & ident,const string & facet,const ReferencePtr & tmpl,const string & adapterId)58 IceInternal::ReferenceFactory::create(const Identity& ident,
59 const string& facet,
60 const ReferencePtr& tmpl,
61 const string& adapterId)
62 {
63 if(ident.name.empty() && ident.category.empty())
64 {
65 return 0;
66 }
67
68 return create(ident, facet, tmpl->getMode(), tmpl->getSecure(), tmpl->getProtocol(), tmpl->getEncoding(),
69 vector<EndpointIPtr>(), adapterId, "");
70 }
71
72 ReferencePtr
create(const Identity & ident,const Ice::ConnectionIPtr & connection)73 IceInternal::ReferenceFactory::create(const Identity& ident, const Ice::ConnectionIPtr& connection)
74 {
75 if(ident.name.empty() && ident.category.empty())
76 {
77 return 0;
78 }
79
80 //
81 // Create new reference
82 //
83 return new FixedReference(_instance,
84 _communicator,
85 ident,
86 "", // Facet
87 connection->endpoint()->datagram() ? Reference::ModeDatagram : Reference::ModeTwoway,
88 connection->endpoint()->secure(),
89 Ice::Protocol_1_0,
90 _instance->defaultsAndOverrides()->defaultEncoding,
91 connection,
92 -1,
93 Ice::Context(),
94 IceUtil::Optional<bool>());
95 }
96
97 ReferencePtr
create(const string & str,const string & propertyPrefix)98 IceInternal::ReferenceFactory::create(const string& str, const string& propertyPrefix)
99 {
100 if(str.empty())
101 {
102 return 0;
103 }
104
105 const string delim = " \t\r\n";
106
107 string s(str);
108 string::size_type beg;
109 string::size_type end = 0;
110
111 beg = s.find_first_not_of(delim, end);
112 if(beg == string::npos)
113 {
114 throw ProxyParseException(__FILE__, __LINE__, "no non-whitespace characters found in `" + s + "'");
115 }
116
117 //
118 // Extract the identity, which may be enclosed in single
119 // or double quotation marks.
120 //
121 string idstr;
122 end = IceUtilInternal::checkQuote(s, beg);
123 if(end == string::npos)
124 {
125 throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around identity in `" + s + "'");
126 }
127 else if(end == 0)
128 {
129 end = s.find_first_of(delim + ":@", beg);
130 if(end == string::npos)
131 {
132 end = s.size();
133 }
134 idstr = s.substr(beg, end - beg);
135 }
136 else
137 {
138 beg++; // Skip leading quote
139 idstr = s.substr(beg, end - beg);
140 end++; // Skip trailing quote
141 }
142
143 if(beg == end)
144 {
145 throw ProxyParseException(__FILE__, __LINE__, "no identity in `" + s + "'");
146 }
147
148 //
149 // Parsing the identity may raise IdentityParseException.
150 //
151 Identity ident = Ice::stringToIdentity(idstr);
152
153 if(ident.name.empty())
154 {
155 //
156 // An identity with an empty name and a non-empty
157 // category is illegal.
158 //
159 if(!ident.category.empty())
160 {
161 throw IllegalIdentityException(__FILE__, __LINE__, ident);
162 }
163 //
164 // Treat a stringified proxy containing two double
165 // quotes ("") the same as an empty string, i.e.,
166 // a null proxy, but only if nothing follows the
167 // quotes.
168 //
169 else if(s.find_first_not_of(delim, end) != string::npos)
170 {
171 throw ProxyParseException(__FILE__, __LINE__, "invalid characters after identity in `" + s + "'");
172 }
173 else
174 {
175 return 0;
176 }
177 }
178
179 string facet;
180 Reference::Mode mode = Reference::ModeTwoway;
181 bool secure = false;
182 Ice::EncodingVersion encoding = _instance->defaultsAndOverrides()->defaultEncoding;
183 Ice::ProtocolVersion protocol = Protocol_1_0;
184 string adapter;
185
186 while(true)
187 {
188 beg = s.find_first_not_of(delim, end);
189 if(beg == string::npos)
190 {
191 break;
192 }
193
194 if(s[beg] == ':' || s[beg] == '@')
195 {
196 break;
197 }
198
199 end = s.find_first_of(delim + ":@", beg);
200 if(end == string::npos)
201 {
202 end = s.length();
203 }
204
205 if(beg == end)
206 {
207 break;
208 }
209
210 string option = s.substr(beg, end - beg);
211 if(option.length() != 2 || option[0] != '-')
212 {
213 throw ProxyParseException(__FILE__, __LINE__, "expected a proxy option but found `" + option + "' in `" +
214 s + "'");
215 }
216
217 //
218 // Check for the presence of an option argument. The
219 // argument may be enclosed in single or double
220 // quotation marks.
221 //
222 string argument;
223 string::size_type argumentBeg = s.find_first_not_of(delim, end);
224 if(argumentBeg != string::npos)
225 {
226 if(s[argumentBeg] != '@' && s[argumentBeg] != ':' && s[argumentBeg] != '-')
227 {
228 beg = argumentBeg;
229 end = IceUtilInternal::checkQuote(s, beg);
230 if(end == string::npos)
231 {
232 throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around value for " + option +
233 " option in `" + s + "'");
234 }
235 else if(end == 0)
236 {
237 end = s.find_first_of(delim + ":@", beg);
238 if(end == string::npos)
239 {
240 end = s.size();
241 }
242 argument = s.substr(beg, end - beg);
243 }
244 else
245 {
246 beg++; // Skip leading quote
247 argument = s.substr(beg, end - beg);
248 end++; // Skip trailing quote
249 }
250 }
251 }
252
253 //
254 // If any new options are added here,
255 // IceInternal::Reference::toString() and its derived classes must be updated as well.
256 //
257 switch(option[1])
258 {
259 case 'f':
260 {
261 if(argument.empty())
262 {
263 throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -f option in `" + s + "'");
264 }
265
266 try
267 {
268 facet = unescapeString(argument, 0, argument.size(), "");
269 }
270 catch(const IceUtil::IllegalArgumentException& ex)
271 {
272 throw ProxyParseException(__FILE__, __LINE__, "invalid facet in `" + s + "': " + ex.reason());
273 }
274
275 break;
276 }
277
278 case 't':
279 {
280 if(!argument.empty())
281 {
282 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
283 "' provided for -t option in `" + s + "'");
284 }
285 mode = Reference::ModeTwoway;
286 break;
287 }
288
289 case 'o':
290 {
291 if(!argument.empty())
292 {
293 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
294 "' provided for -o option in `" + s + "'");
295 }
296 mode = Reference::ModeOneway;
297 break;
298 }
299
300 case 'O':
301 {
302 if(!argument.empty())
303 {
304 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
305 "' provided for -O option in `" + s + "'");
306 }
307 mode = Reference::ModeBatchOneway;
308 break;
309 }
310
311 case 'd':
312 {
313 if(!argument.empty())
314 {
315 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
316 "' provided for -d option in `" + s + "'");
317 }
318 mode = Reference::ModeDatagram;
319 break;
320 }
321
322 case 'D':
323 {
324 if(!argument.empty())
325 {
326 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
327 "' provided for -D option in `" + s + "'");
328 }
329 mode = Reference::ModeBatchDatagram;
330 break;
331 }
332
333 case 's':
334 {
335 if(!argument.empty())
336 {
337 throw ProxyParseException(__FILE__, __LINE__, "unexpected argument `" + argument +
338 "' provided for -s option in `" + s + "'");
339 }
340 secure = true;
341 break;
342 }
343
344 case 'e':
345 {
346 if(argument.empty())
347 {
348 throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -e option in `" + s + "'");
349 }
350
351 try
352 {
353 encoding = Ice::stringToEncodingVersion(argument);
354 }
355 catch(const Ice::VersionParseException& ex)
356 {
357 throw ProxyParseException(__FILE__, __LINE__, "invalid encoding version `" + argument + "' in `" +
358 s + "':\n" + ex.str);
359 }
360 break;
361 }
362
363 case 'p':
364 {
365 if(argument.empty())
366 {
367 throw ProxyParseException(__FILE__, __LINE__, "no argument provided for -p option in `" + s + "'");
368 }
369
370 try
371 {
372 protocol = Ice::stringToProtocolVersion(argument);
373 }
374 catch(const Ice::VersionParseException& ex)
375 {
376 throw ProxyParseException(__FILE__, __LINE__, "invalid protocol version `" + argument + "' in `" +
377 s + "':\n" + ex.str);
378 }
379 break;
380 }
381
382 default:
383 {
384 throw ProxyParseException(__FILE__, __LINE__, "unknown option `" + option + "' in `" + s + "'");
385 }
386 }
387 }
388
389 if(beg == string::npos)
390 {
391 return create(ident, facet, mode, secure, protocol, encoding, vector<EndpointIPtr>(), "", propertyPrefix);
392 }
393
394 vector<EndpointIPtr> endpoints;
395 switch(s[beg])
396 {
397 case ':':
398 {
399 vector<string> unknownEndpoints;
400 end = beg;
401
402 while(end < s.length() && s[end] == ':')
403 {
404 beg = end + 1;
405
406 end = beg;
407 while(true)
408 {
409 end = s.find(':', end);
410 if(end == string::npos)
411 {
412 end = s.length();
413 break;
414 }
415 else
416 {
417 bool quoted = false;
418 string::size_type quote = beg;
419 while(true)
420 {
421 quote = s.find('\"', quote);
422 if(quote == string::npos || end < quote)
423 {
424 break;
425 }
426 else
427 {
428 quote = s.find('\"', ++quote);
429 if(quote == string::npos)
430 {
431 break;
432 }
433 else if(end < quote)
434 {
435 quoted = true;
436 break;
437 }
438 ++quote;
439 }
440 }
441 if(!quoted)
442 {
443 break;
444 }
445 ++end;
446 }
447 }
448
449 string es = s.substr(beg, end - beg);
450 EndpointIPtr endp = _instance->endpointFactoryManager()->create(es, false);
451 if(endp != ICE_NULLPTR)
452 {
453 endpoints.push_back(endp);
454 }
455 else
456 {
457 unknownEndpoints.push_back(es);
458 }
459 }
460 if(endpoints.size() == 0)
461 {
462 assert(!unknownEndpoints.empty());
463 throw EndpointParseException(__FILE__, __LINE__, "invalid endpoint `" + unknownEndpoints.front() +
464 "' in `" + s + "'");
465 }
466 else if(unknownEndpoints.size() != 0 &&
467 _instance->initializationData().properties->
468 getPropertyAsIntWithDefault("Ice.Warn.Endpoints", 1) > 0)
469 {
470 Warning out(_instance->initializationData().logger);
471 out << "Proxy contains unknown endpoints:";
472 for(unsigned int idx = 0; idx < unknownEndpoints.size(); ++idx)
473 {
474 out << " `" << unknownEndpoints[idx] << "'";
475 }
476 }
477
478 return create(ident, facet, mode, secure, protocol, encoding, endpoints, "", propertyPrefix);
479 break;
480 }
481 case '@':
482 {
483 beg = s.find_first_not_of(delim, beg + 1);
484 if(beg == string::npos)
485 {
486 throw ProxyParseException(__FILE__, __LINE__, "missing adapter id in `" + s + "'");
487 }
488
489 string adapterstr;
490 end = IceUtilInternal::checkQuote(s, beg);
491 if(end == string::npos)
492 {
493 throw ProxyParseException(__FILE__, __LINE__, "mismatched quotes around adapter id in `" + s + "'");
494 }
495 else if(end == 0)
496 {
497 end = s.find_first_of(delim, beg);
498 if(end == string::npos)
499 {
500 end = s.size();
501 }
502 adapterstr = s.substr(beg, end - beg);
503 }
504 else
505 {
506 beg++; // Skip leading quote
507 adapterstr = s.substr(beg, end - beg);
508 end++; // Skip trailing quote.
509 }
510
511 // Check for trailing whitespace.
512 if(end != string::npos && s.find_first_not_of(delim, end) != string::npos)
513 {
514 throw ProxyParseException(__FILE__, __LINE__, "invalid trailing characters after `" +
515 s.substr(0, end + 1) + "' in `" + s + "'");
516 }
517
518 try
519 {
520 adapter = unescapeString(adapterstr, 0, adapterstr.size(), "");
521 }
522 catch(const IceUtil::IllegalArgumentException& ex)
523 {
524 throw ProxyParseException(__FILE__, __LINE__, "invalid adapter id in `" + s + "': " + ex.reason());
525 }
526 if(adapter.size() == 0)
527 {
528 throw ProxyParseException(__FILE__, __LINE__, "empty adapter id in `" + s + "'");
529 }
530
531 return create(ident, facet, mode, secure, protocol, encoding, endpoints, adapter, propertyPrefix);
532 break;
533 }
534 default:
535 {
536 throw ProxyParseException(__FILE__, __LINE__, "malformed proxy `" + s + "'");
537 }
538 }
539 }
540
541 ReferencePtr
create(const Identity & ident,InputStream * s)542 IceInternal::ReferenceFactory::create(const Identity& ident, InputStream* s)
543 {
544 //
545 // Don't read the identity here. Operations calling this
546 // constructor read the identity, and pass it as a parameter.
547 //
548
549 if(ident.name.empty() && ident.category.empty())
550 {
551 return 0;
552 }
553
554 //
555 // For compatibility with the old FacetPath.
556 //
557 vector<string> facetPath;
558 s->read(facetPath);
559 string facet;
560 if(!facetPath.empty())
561 {
562 if(facetPath.size() > 1)
563 {
564 throw ProxyUnmarshalException(__FILE__, __LINE__);
565 }
566 facet.swap(facetPath[0]);
567 }
568
569 Byte modeAsByte;
570 s->read(modeAsByte);
571 Reference::Mode mode = static_cast<Reference::Mode>(modeAsByte);
572 if(mode < 0 || mode > Reference::ModeLast)
573 {
574 throw ProxyUnmarshalException(__FILE__, __LINE__);
575 }
576
577 bool secure;
578 s->read(secure);
579
580 Ice::ProtocolVersion protocol;
581 Ice::EncodingVersion encoding;
582 if(s->getEncoding() != Ice::Encoding_1_0)
583 {
584 s->read(protocol);
585 s->read(encoding);
586 }
587 else
588 {
589 protocol = Ice::Protocol_1_0;
590 encoding = Ice::Encoding_1_0;
591 }
592
593 vector<EndpointIPtr> endpoints;
594 string adapterId;
595
596 Ice::Int sz = s->readSize();
597
598 if(sz > 0)
599 {
600 endpoints.reserve(sz);
601 while(sz--)
602 {
603 EndpointIPtr endpoint = _instance->endpointFactoryManager()->read(s);
604 endpoints.push_back(endpoint);
605 }
606 }
607 else
608 {
609 s->read(adapterId);
610 }
611
612 return create(ident, facet, mode, secure, protocol, encoding, endpoints, adapterId, "");
613 }
614
615 ReferenceFactoryPtr
setDefaultRouter(const RouterPrxPtr & defaultRouter)616 IceInternal::ReferenceFactory::setDefaultRouter(const RouterPrxPtr& defaultRouter)
617 {
618 if(defaultRouter == _defaultRouter)
619 {
620 return this;
621 }
622
623 ReferenceFactoryPtr factory = new ReferenceFactory(_instance, _communicator);
624 factory->_defaultLocator = _defaultLocator;
625 factory->_defaultRouter = defaultRouter;
626 return factory;
627 }
628
629 RouterPrxPtr
getDefaultRouter() const630 IceInternal::ReferenceFactory::getDefaultRouter() const
631 {
632 return _defaultRouter;
633 }
634
635 ReferenceFactoryPtr
setDefaultLocator(const LocatorPrxPtr & defaultLocator)636 IceInternal::ReferenceFactory::setDefaultLocator(const LocatorPrxPtr& defaultLocator)
637 {
638 if(defaultLocator == _defaultLocator)
639 {
640 return this;
641 }
642
643 ReferenceFactoryPtr factory = new ReferenceFactory(_instance, _communicator);
644 factory->_defaultRouter = _defaultRouter;
645 factory->_defaultLocator = defaultLocator;
646 return factory;
647 }
648
649 LocatorPrxPtr
getDefaultLocator() const650 IceInternal::ReferenceFactory::getDefaultLocator() const
651 {
652 return _defaultLocator;
653 }
654
ReferenceFactory(const InstancePtr & instance,const CommunicatorPtr & communicator)655 IceInternal::ReferenceFactory::ReferenceFactory(const InstancePtr& instance, const CommunicatorPtr& communicator) :
656 _instance(instance),
657 _communicator(communicator)
658 {
659 }
660
661 void
checkForUnknownProperties(const string & prefix)662 IceInternal::ReferenceFactory::checkForUnknownProperties(const string& prefix)
663 {
664 static const string suffixes[] =
665 {
666 "EndpointSelection",
667 "ConnectionCached",
668 "PreferSecure",
669 "LocatorCacheTimeout",
670 "InvocationTimeout",
671 "Locator",
672 "Router",
673 "CollocationOptimized",
674 "Context.*"
675 };
676
677 //
678 // Do not warn about unknown properties list if Ice prefix, ie Ice, Glacier2, etc
679 //
680 for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i)
681 {
682 if(prefix.find(*i) == 0)
683 {
684 return;
685 }
686 }
687
688 StringSeq unknownProps;
689 PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix + ".");
690 for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p)
691 {
692 bool valid = false;
693 for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i)
694 {
695 string prop = prefix + "." + suffixes[i];
696 if(IceUtilInternal::match(p->first, prop))
697 {
698 valid = true;
699 break;
700 }
701 }
702
703 if(!valid)
704 {
705 unknownProps.push_back(p->first);
706 }
707 }
708
709 if(unknownProps.size())
710 {
711 Warning out(_instance->initializationData().logger);
712 out << "found unknown properties for proxy '" << prefix << "':";
713 for(unsigned int i = 0; i < unknownProps.size(); ++i)
714 {
715 out << "\n " << unknownProps[i];
716 }
717 }
718 }
719
720 RoutableReferencePtr
create(const Identity & ident,const string & facet,Reference::Mode mode,bool secure,const Ice::ProtocolVersion & protocol,const Ice::EncodingVersion & encoding,const vector<EndpointIPtr> & endpoints,const string & adapterId,const string & propertyPrefix)721 IceInternal::ReferenceFactory::create(const Identity& ident,
722 const string& facet,
723 Reference::Mode mode,
724 bool secure,
725 const Ice::ProtocolVersion& protocol,
726 const Ice::EncodingVersion& encoding,
727 const vector<EndpointIPtr>& endpoints,
728 const string& adapterId,
729 const string& propertyPrefix)
730 {
731 DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides();
732
733 //
734 // Default local proxy options.
735 //
736 LocatorInfoPtr locatorInfo;
737 if(_defaultLocator)
738 {
739 if(_defaultLocator->ice_getEncodingVersion() != encoding)
740 {
741 locatorInfo = _instance->locatorManager()->get(_defaultLocator->ice_encodingVersion(encoding));
742 }
743 else
744 {
745 locatorInfo = _instance->locatorManager()->get(_defaultLocator);
746 }
747 }
748 RouterInfoPtr routerInfo = _instance->routerManager()->get(_defaultRouter);
749 bool collocationOptimized = defaultsAndOverrides->defaultCollocationOptimization;
750 bool cacheConnection = true;
751 bool preferSecure = defaultsAndOverrides->defaultPreferSecure;
752 Ice::EndpointSelectionType endpointSelection = defaultsAndOverrides->defaultEndpointSelection;
753 int locatorCacheTimeout = defaultsAndOverrides->defaultLocatorCacheTimeout;
754 int invocationTimeout = defaultsAndOverrides->defaultInvocationTimeout;
755 Ice::Context ctx;
756
757 //
758 // Override the defaults with the proxy properties if a property prefix is defined.
759 //
760 if(!propertyPrefix.empty())
761 {
762 PropertiesPtr properties = _instance->initializationData().properties;
763 if(properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0)
764 {
765 checkForUnknownProperties(propertyPrefix);
766 }
767
768 string property;
769
770 property = propertyPrefix + ".Locator";
771 LocatorPrxPtr locator = ICE_UNCHECKED_CAST(LocatorPrx, _communicator->propertyToProxy(property));
772 if(locator)
773 {
774 if(locator->ice_getEncodingVersion() != encoding)
775 {
776 locatorInfo = _instance->locatorManager()->get(locator->ice_encodingVersion(encoding));
777 }
778 else
779 {
780 locatorInfo = _instance->locatorManager()->get(locator);
781 }
782 }
783
784 property = propertyPrefix + ".Router";
785 RouterPrxPtr router = ICE_UNCHECKED_CAST(RouterPrx, _communicator->propertyToProxy(property));
786 if(router)
787 {
788 if(propertyPrefix.size() > 7 && propertyPrefix.substr(propertyPrefix.size() - 7, 7) == ".Router")
789 {
790 Warning out(_instance->initializationData().logger);
791 out << "`" << property << "=" << properties->getProperty(property)
792 << "': cannot set a router on a router; setting ignored";
793 }
794 else
795 {
796 routerInfo = _instance->routerManager()->get(router);
797 }
798 }
799
800 property = propertyPrefix + ".CollocationOptimized";
801 collocationOptimized = properties->getPropertyAsIntWithDefault(property, collocationOptimized) > 0;
802
803 property = propertyPrefix + ".ConnectionCached";
804 cacheConnection = properties->getPropertyAsIntWithDefault(property, cacheConnection) > 0;
805
806 property = propertyPrefix + ".PreferSecure";
807 preferSecure = properties->getPropertyAsIntWithDefault(property, preferSecure) > 0;
808
809 property = propertyPrefix + ".EndpointSelection";
810 if(!properties->getProperty(property).empty())
811 {
812 string type = properties->getProperty(property);
813 if(type == "Random")
814 {
815 endpointSelection = ICE_ENUM(EndpointSelectionType, Random);
816 }
817 else if(type == "Ordered")
818 {
819 endpointSelection = ICE_ENUM(EndpointSelectionType, Ordered);
820 }
821 else
822 {
823 throw EndpointSelectionTypeParseException(__FILE__, __LINE__, "illegal value `" + type +
824 "'; expected `Random' or `Ordered'");
825 }
826 }
827
828 property = propertyPrefix + ".LocatorCacheTimeout";
829 string value = properties->getProperty(property);
830 if(!value.empty())
831 {
832 locatorCacheTimeout = properties->getPropertyAsIntWithDefault(property, locatorCacheTimeout);
833 if(locatorCacheTimeout < -1)
834 {
835 locatorCacheTimeout = -1;
836
837 Warning out(_instance->initializationData().logger);
838 out << "invalid value for " << property << "`" << properties->getProperty(property) << "'"
839 << ": defaulting to -1";
840 }
841 }
842
843 property = propertyPrefix + ".InvocationTimeout";
844 value = properties->getProperty(property);
845 if(!value.empty())
846 {
847 invocationTimeout = properties->getPropertyAsIntWithDefault(property, invocationTimeout);
848 if(invocationTimeout < 1 && invocationTimeout != -1)
849 {
850 invocationTimeout = -1;
851
852 Warning out(_instance->initializationData().logger);
853 out << "invalid value for " << property << "`" << properties->getProperty(property) << "'"
854 << ": defaulting to -1";
855 }
856 }
857
858 property = propertyPrefix + ".Context.";
859 PropertyDict contexts = properties->getPropertiesForPrefix(property);
860 for(PropertyDict::const_iterator p = contexts.begin(); p != contexts.end(); ++p)
861 {
862 ctx.insert(make_pair(p->first.substr(property.length()), p->second));
863 }
864 }
865
866 //
867 // Create new reference
868 //
869 return new RoutableReference(_instance,
870 _communicator,
871 ident,
872 facet,
873 mode,
874 secure,
875 protocol,
876 encoding,
877 endpoints,
878 adapterId,
879 locatorInfo,
880 routerInfo,
881 collocationOptimized,
882 cacheConnection,
883 preferSecure,
884 endpointSelection,
885 locatorCacheTimeout,
886 invocationTimeout,
887 ctx);
888 }
889