1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <Ice/Ice.h>
6 #include <IceXML/Parser.h>
7 #include <IcePatch2Lib/Util.h>
8 #include <IceGrid/Admin.h>
9 #include <IceGrid/DescriptorParser.h>
10 #include <IceGrid/DescriptorBuilder.h>
11 #include <IceGrid/Util.h>
12 
13 #include <stack>
14 #include <fstream>
15 
16 using namespace std;
17 using namespace Ice;
18 using namespace IceGrid;
19 
20 namespace IceGrid
21 {
22 
23 class DescriptorHandler : public IceXML::Handler
24 {
25 public:
26 
27     DescriptorHandler(const string&, const Ice::CommunicatorPtr&);
28 
29     void setAdmin(const IceGrid::AdminPrx&);
30     void setVariables(const map<string, string>&, const vector<string>&);
31 
32     virtual void startElement(const string&, const IceXML::Attributes&, int, int);
33     virtual void endElement(const string&, int, int);
34     virtual void characters(const string&, int, int);
35     virtual void error(const string&, int, int);
36 
37     const ApplicationDescriptor& getApplicationDescriptor() const;
38 
39 private:
40 
41     bool isCurrentTargetDeployable() const;
42     string elementValue();
43     vector<string> getTargets(const string&) const;
44     void error(const string&) const;
45     bool isTargetDeployable(const string&) const;
46 
47     const Ice::CommunicatorPtr _communicator;
48     IceGrid::AdminPrx _admin;
49     string _filename;
50     map<string, string> _overrides;
51     vector<string> _targets;
52     string _data;
53     string _previousElementName;
54     int _targetCounter;
55     bool _isCurrentTargetDeployable;
56     int _line;
57     int _column;
58 
59     IceInternal::UniquePtr<ApplicationDescriptorBuilder> _currentApplication;
60     IceInternal::UniquePtr<NodeDescriptorBuilder> _currentNode;
61     IceInternal::UniquePtr<TemplateDescriptorBuilder> _currentTemplate;
62     IceInternal::UniquePtr<ServerInstanceDescriptorBuilder> _currentServerInstance;
63     IceInternal::UniquePtr<ServiceInstanceDescriptorBuilder> _currentServiceInstance;
64     IceInternal::UniquePtr<ServerDescriptorBuilder> _currentServer;
65     IceInternal::UniquePtr<ServiceDescriptorBuilder> _currentService;
66     CommunicatorDescriptorBuilder* _currentCommunicator;
67     IceInternal::UniquePtr<PropertySetDescriptorBuilder> _currentPropertySet;
68 
69     bool _isTopLevel;
70     bool _inAdapter;
71     bool _inReplicaGroup;
72     bool _inDbEnv;
73     bool _inDistrib;
74 };
75 
76 }
77 
DescriptorHandler(const string & filename,const Ice::CommunicatorPtr & communicator)78 DescriptorHandler::DescriptorHandler(const string& filename, const Ice::CommunicatorPtr& communicator) :
79     _communicator(communicator),
80     _filename(filename),
81     _isCurrentTargetDeployable(true),
82     _currentCommunicator(0),
83     _isTopLevel(true),
84     _inAdapter(false),
85     _inReplicaGroup(false),
86     _inDbEnv(false)
87 {
88 }
89 
90 void
setAdmin(const AdminPrx & admin)91 DescriptorHandler::setAdmin(const AdminPrx& admin)
92 {
93     _admin = admin;
94 }
95 
96 void
setVariables(const map<string,string> & variables,const vector<string> & targets)97 DescriptorHandler::setVariables(const map<string, string>& variables, const vector<string>& targets)
98 {
99     _overrides = variables;
100     _targets = targets;
101 }
102 
103 void
startElement(const string & name,const IceXML::Attributes & attrs,int line,int column)104 DescriptorHandler::startElement(const string& name, const IceXML::Attributes& attrs, int line, int column)
105 {
106     _line = line;
107     _column = column;
108     XmlAttributesHelper attributes(attrs, _communicator->getLogger(), _filename, line);
109 
110     try
111     {
112         if(name == "icegrid")
113         {
114             if(!_isTopLevel)
115             {
116                 error("element <icegrid> is a top level element");
117             }
118             _isTopLevel = false;
119         }
120         else if(_isTopLevel)
121         {
122             error("only the <icegrid> element is allowed at the top-level");
123         }
124         else if(name == "target")
125         {
126             if(!_isCurrentTargetDeployable)
127             {
128                 ++_targetCounter;
129             }
130             else
131             {
132                 _isCurrentTargetDeployable = isTargetDeployable(attributes("name"));
133                 _targetCounter = 1;
134                 return;
135             }
136         }
137         else if(!isCurrentTargetDeployable())
138         {
139             //
140             // We don't bother to parse the elements if the elements are enclosed in a target element
141             // which won't be deployed.
142             //
143             attributes.asMap();
144             return;
145         }
146         else if(name == "include")
147         {
148             string targets = attributes("targets", "");
149             string file = attributes("file");
150             if(file[0] != '/')
151             {
152                 string::size_type end = _filename.find_last_of('/');
153                 if(end != string::npos)
154                 {
155                     file = _filename.substr(0, end) + "/" + file;
156                 }
157             }
158 
159             string oldFileName = _filename;
160             vector<string> oldTargets = _targets;
161             _isTopLevel = true;
162             _filename = file;
163             _targets = getTargets(targets);
164 
165             IceXML::Parser::parse(file, *this);
166 
167             _filename = oldFileName;
168             _targets = oldTargets;
169         }
170         else if(name == "application")
171         {
172             if(_currentApplication.get())
173             {
174                 error("only one <application> element is allowed");
175             }
176 
177             bool importTemplates = attributes.asBool("import-default-templates", false);
178 
179             //
180             // TODO: is ignoring importTemplates the desired behavior when _admin == 0?
181             //
182             if(importTemplates && _admin != 0)
183             {
184                 try
185                 {
186                     ApplicationDescriptor application = _admin->getDefaultApplicationDescriptor();
187                     _currentApplication.reset(new ApplicationDescriptorBuilder(_communicator, application,
188                                                                                attributes, _overrides));
189                 }
190                 catch(const DeploymentException& ex)
191                 {
192                     throw runtime_error(ex.reason);
193                 }
194             }
195             else
196             {
197                 _currentApplication.reset(new ApplicationDescriptorBuilder(_communicator, attributes, _overrides));
198             }
199         }
200         else if(name == "node")
201         {
202             if(!_currentApplication.get() || _currentNode.get())
203             {
204                 error("the <node> element can only be a child of an <application> element");
205             }
206             _currentNode.reset(_currentApplication->createNode(attributes));
207         }
208         else if(name == "server-instance")
209         {
210             if(!_currentNode.get() || _currentServer.get() || _currentServerInstance.get())
211             {
212                 error("the <server-instance> element can only be a child of a <node> element");
213             }
214             _currentServerInstance.reset(_currentNode->createServerInstance(attributes));
215         }
216         else if(name == "server")
217         {
218             if((!_currentNode.get() && !_currentTemplate.get()) || _currentServer.get() || _currentServerInstance.get())
219             {
220                 error("the <server> element can only be a child of a <node> or <server-template> element");
221             }
222             if(_currentNode.get())
223             {
224                 _currentServer.reset(_currentNode->createServer(attributes));
225             }
226             else
227             {
228                 _currentServer.reset(_currentTemplate->createServer(attributes));
229             }
230             _currentCommunicator = _currentServer.get();
231         }
232         else if(name == "icebox")
233         {
234             if((!_currentNode.get() && !_currentTemplate.get()) || _currentServer.get() || _currentServerInstance.get())
235             {
236                 error("the <icebox> element can only be a child of a <node> or <server-template> element");
237             }
238             if(_currentNode.get())
239             {
240                 _currentServer.reset(_currentNode->createIceBox(attributes));
241             }
242             else
243             {
244                 _currentServer.reset(_currentTemplate->createIceBox(attributes));
245             }
246             _currentCommunicator = _currentServer.get();
247         }
248         else if(name == "server-template")
249         {
250             if(!_currentApplication.get() || _currentTemplate.get() || _currentNode.get())
251             {
252                 error("the <server-template> element can only be a child of an <application> element");
253             }
254             _currentTemplate.reset(_currentApplication->createServerTemplate(attributes));
255         }
256         else if(name == "service-instance")
257         {
258             if(!_currentServer.get() || _currentServiceInstance.get())
259             {
260                 error("the <service-instance> element can only be a child of an <icebox> element");
261             }
262             _currentServiceInstance.reset(_currentServer->createServiceInstance(attributes));
263         }
264         else if(name == "service")
265         {
266             if((!_currentServer.get() && !_currentTemplate.get()) || _currentService.get() ||
267                _currentServiceInstance.get())
268             {
269                 error("the <service> element can only be a child of an <icebox> or <service-template> element");
270             }
271 
272             if(_currentServer.get())
273             {
274                 _currentService.reset(_currentServer->createService(attributes));
275             }
276             else
277             {
278                 _currentService.reset(_currentTemplate->createService(attributes));
279             }
280             _currentCommunicator = _currentService.get();
281         }
282         else if(name == "service-template")
283         {
284             if(!_currentApplication.get() || _currentNode.get() || _currentTemplate.get())
285             {
286                 error("the <service-template> element can only be a child of an <application> element");
287             }
288 
289             _currentTemplate.reset(_currentApplication->createServiceTemplate(attributes));
290         }
291         else if(name == "replica-group")
292         {
293             if(!_currentApplication.get())
294             {
295                 error("the <replica-group> element can only be a child of an <application> element");
296             }
297             _currentApplication->addReplicaGroup(attributes);
298             _inReplicaGroup = true;
299         }
300         else if(name == "load-balancing")
301         {
302             if(!_inReplicaGroup)
303             {
304                 error("the <load-balancing> element can only be a child of a <replica-group> element");
305             }
306             _currentApplication->setLoadBalancing(attributes);
307         }
308         else if(name == "variable")
309         {
310             if(_currentNode.get())
311             {
312                 _currentNode->addVariable(attributes);
313             }
314             else if(_currentApplication.get())
315             {
316                 _currentApplication->addVariable(attributes);
317             }
318             else
319             {
320                 error("the <variable> element can only be a child of an <application> or <node> element");
321             }
322         }
323         else if(name == "parameter")
324         {
325             if(!_currentTemplate.get())
326             {
327                 error("the <parameter> element can only be a child of a <template> element");
328             }
329             _currentTemplate->addParameter(attributes);
330         }
331         else if(name == "properties")
332         {
333             if(_currentPropertySet.get())
334             {
335                 _currentPropertySet->addPropertySet(attributes);
336             }
337             else if(_currentServiceInstance.get())
338             {
339                 _currentPropertySet.reset(_currentServiceInstance->createPropertySet());
340             }
341             else if(_currentServerInstance.get())
342             {
343                 _currentPropertySet.reset(_currentServerInstance->createPropertySet(attributes));
344             }
345             else if(_currentCommunicator)
346             {
347                 _currentPropertySet.reset(_currentCommunicator->createPropertySet());
348             }
349             else if(_currentNode.get())
350             {
351                 _currentPropertySet.reset(_currentNode->createPropertySet(attributes));
352             }
353             else if(_currentApplication.get() && !_currentTemplate.get())
354             {
355                 _currentPropertySet.reset(_currentApplication->createPropertySet(attributes));
356             }
357             else
358             {
359                 error("the <properties> element is not allowed here");
360             }
361         }
362         else if(name == "property")
363         {
364             if(_currentPropertySet.get())
365             {
366                 _currentPropertySet->addProperty(attributes);
367             }
368             else if(_currentCommunicator)
369             {
370                 _currentCommunicator->addProperty(attributes);
371             }
372             else
373             {
374                 error("the <property> element can only be a child of a <properties>, <icebox>, <server> or <service> "
375                       "element");
376             }
377         }
378         else if(name == "adapter")
379         {
380             if(!_currentCommunicator)
381             {
382                 error("the <adapter> element can only be a child of a <server> or <service> element");
383             }
384             _currentCommunicator->addAdapter(attributes);
385             _inAdapter = true;
386         }
387         else if(name == "object")
388         {
389             if(!_inAdapter && !_inReplicaGroup)
390             {
391                 error("the <object> element can only be a child of an <adapter> or <replica-group> element");
392             }
393             if(_inReplicaGroup)
394             {
395                 _currentApplication->addObject(attributes);
396             }
397             else
398             {
399                 _currentCommunicator->addObject(attributes);
400             }
401         }
402         else if(name == "allocatable")
403         {
404             if(!_inAdapter)
405             {
406                 error("the <allocatable> element can only be a child of an <adapter> element");
407             }
408             _currentCommunicator->addAllocatable(attributes);
409         }
410         else if(name == "distrib")
411         {
412             if(!_currentApplication.get() ||
413                ((_currentNode.get() || _currentTemplate.get()) && !_currentServer.get()) ||
414                _currentServer.get() != _currentCommunicator)
415             {
416                 error("the <distrib> element can only be a child of an <application>, <server> or <icebox> element");
417             }
418             if(!_currentServer.get())
419             {
420                 _currentApplication->addDistribution(attributes);
421             }
422             else
423             {
424                 _currentServer->addDistribution(attributes);
425             }
426             _inDistrib = true;
427         }
428         else if(name == "dbenv")
429         {
430             if(!_currentCommunicator)
431             {
432                 error("the <dbenv> element can only be a child of a <server> or <service> element");
433             }
434             _currentCommunicator->addDbEnv(attributes);
435             _inDbEnv = true;
436         }
437         else if(name == "log")
438         {
439             if(!_currentCommunicator)
440             {
441                 error("the <log> element can only be a child of a <server> or <service> element");
442             }
443             _currentCommunicator->addLog(attributes);
444         }
445         else if(name == "dbproperty")
446         {
447             if(!_inDbEnv)
448             {
449                 error("the <dbproperty> element can only be a child of a <dbenv> element");
450             }
451             _currentCommunicator->addDbEnvProperty(attributes);
452         }
453         else if(name == "description" || name == "option" || name == "env" || name == "directory")
454         {
455             //
456             // Nothing to do.
457             //
458         }
459         else
460         {
461             error("unknown element `" + name + "'");
462         }
463 
464         attributes.checkUnknownAttributes();
465     }
466     catch(const exception& ex)
467     {
468         error(ex.what());
469     }
470 
471     //
472     // Check if the previous element value has been consumed and if not make
473     // sure it's "empty".
474     //
475     string value = elementValue();
476     if(!value.empty() && value.find_first_not_of(" \t\r\n") != string::npos)
477     {
478         error("invalid element value for element `" + _previousElementName + "'");
479     }
480     _previousElementName = name;
481 }
482 
483 void
endElement(const string & name,int line,int column)484 DescriptorHandler::endElement(const string& name, int line, int column)
485 {
486     _line = line;
487     _column = column;
488 
489     try
490     {
491         if(name == "target")
492         {
493             if(!_isCurrentTargetDeployable && --_targetCounter == 0)
494             {
495                 _isCurrentTargetDeployable = true;
496                 _targetCounter = 0;
497             }
498             return;
499         }
500         else if(!isCurrentTargetDeployable())
501         {
502             //
503             // We don't bother to parse the elements if the elements are enclosed in a target element
504             // which won't be deployed.
505             //
506             return;
507         }
508         else if(name == "node")
509         {
510             _currentApplication->addNode(_currentNode->getName(), _currentNode->getDescriptor());
511             _currentNode.reset(0);
512         }
513         else if(name == "server" || name == "icebox")
514         {
515             assert(_currentServer.get());
516             if(_currentTemplate.get())
517             {
518                 _currentTemplate->setDescriptor(_currentServer->getDescriptor());
519             }
520             else
521             {
522                 assert(_currentNode.get());
523                 _currentNode->addServer(_currentServer->getDescriptor());
524             }
525             _currentServer->finish();
526             _currentServer.reset(0);
527             _currentCommunicator = 0;
528         }
529         else if(name == "server-template")
530         {
531             assert(_currentApplication.get());
532             _currentApplication->addServerTemplate(_currentTemplate->getId(), _currentTemplate->getDescriptor());
533             _currentTemplate.reset(0);
534         }
535         else if(name == "service")
536         {
537             assert(_currentService.get());
538             if(_currentServer.get())
539             {
540                 _currentServer->addService(_currentService->getDescriptor());
541             }
542             else
543             {
544                 _currentTemplate->setDescriptor(_currentService->getDescriptor());
545             }
546             _currentService->finish();
547             _currentService.reset(0);
548             _currentCommunicator = _currentServer.get();
549         }
550         else if(name == "service-template")
551         {
552             assert(_currentTemplate.get());
553             _currentApplication->addServiceTemplate(_currentTemplate->getId(), _currentTemplate->getDescriptor());
554             _currentTemplate.reset(0);
555         }
556         else if(name == "server-instance")
557         {
558             assert(_currentNode.get() && _currentServerInstance.get());
559             _currentNode->addServerInstance(_currentServerInstance->getDescriptor());
560             _currentServerInstance.reset(0);
561         }
562         else if(name == "service-instance")
563         {
564             assert(_currentServer.get() && _currentServiceInstance.get());
565             _currentServer->addServiceInstance(_currentServiceInstance->getDescriptor());
566             _currentServiceInstance.reset(0);
567         }
568         else if(name == "properties")
569         {
570             assert(_currentPropertySet.get());
571             if(_currentPropertySet->finish())
572             {
573                 if(_currentServiceInstance.get())
574                 {
575                     _currentServiceInstance->addPropertySet(_currentPropertySet->getDescriptor());
576                 }
577                 else if(_currentServerInstance.get())
578                 {
579                     _currentServerInstance->addPropertySet(_currentPropertySet->getService(),
580                                                            _currentPropertySet->getDescriptor());
581                 }
582                 else if(_currentCommunicator)
583                 {
584                     _currentCommunicator->addPropertySet(_currentPropertySet->getDescriptor());
585                 }
586                 else if(_currentNode.get())
587                 {
588                     _currentNode->addPropertySet(_currentPropertySet->getId(),
589                                                  _currentPropertySet->getDescriptor());
590                 }
591                 else if(_currentApplication.get())
592                 {
593                     _currentApplication->addPropertySet(_currentPropertySet->getId(),
594                                                         _currentPropertySet->getDescriptor());
595                 }
596                 else
597                 {
598                     assert(false);
599                 }
600                 _currentPropertySet.reset(0);
601             }
602         }
603         else if(name == "description")
604         {
605             if(_inAdapter)
606             {
607                 _currentCommunicator->setAdapterDescription(elementValue());
608             }
609             else if(_inReplicaGroup)
610             {
611                 _currentApplication->setReplicaGroupDescription(elementValue());
612             }
613             else if(_inDbEnv)
614             {
615                 assert(_currentCommunicator);
616                 _currentCommunicator->setDbEnvDescription(elementValue());
617             }
618             else if(_currentCommunicator)
619             {
620                 _currentCommunicator->setDescription(elementValue());
621             }
622             else if(_currentNode.get())
623             {
624                 _currentNode->setDescription(elementValue());
625             }
626             else if(_currentApplication.get())
627             {
628                 _currentApplication->setDescription(elementValue());
629             }
630             else
631             {
632                 error("element <description> is not allowed here");
633             }
634         }
635         else if(name == "option")
636         {
637             if(!_currentServer.get())
638             {
639                 error("element <option> can only be the child of a <server> element");
640             }
641             _currentServer->addOption(elementValue());
642         }
643         else if(name == "env")
644         {
645             if(!_currentServer.get())
646             {
647                 error("element <env> can only be the child of a <server> element");
648             }
649             _currentServer->addEnv(elementValue());
650         }
651         else if(name == "directory")
652         {
653             if(!_inDistrib)
654             {
655                 error("the <directory> element can only be a child of a <distrib> element");
656             }
657             if(!_currentServer.get())
658             {
659                 _currentApplication->addDistributionDirectory(elementValue());
660             }
661             else
662             {
663                 _currentServer->addDistributionDirectory(elementValue());
664             }
665         }
666         else if(name == "adapter")
667         {
668             _inAdapter = false;
669         }
670         else if(name == "replica-group")
671         {
672             _currentApplication->finishReplicaGroup();
673             _inReplicaGroup = false;
674         }
675         else if(name == "dbenv")
676         {
677             _inDbEnv = false;
678         }
679         else if(name == "distrib")
680         {
681             _inDistrib = false;
682         }
683     }
684     catch(const exception& ex)
685     {
686         error(ex.what());
687     }
688 
689     //
690     // Check if the element value has been consumed and if not make
691     // sure it's "empty".
692     //
693     string value = elementValue();
694     if(!value.empty() && value.find_first_not_of(" \t\r\n") != string::npos)
695     {
696         error("invalid element value for element `" + name + "'");
697     }
698 }
699 
700 void
characters(const string & chars,int,int)701 DescriptorHandler::characters(const string& chars, int, int)
702 {
703     if(isCurrentTargetDeployable())
704     {
705         _data += chars;
706     }
707 }
708 
709 void
error(const string & msg,int line,int column)710 DescriptorHandler::error(const string& msg, int line, int column)
711 {
712     ostringstream os;
713     os << "error in <" << _filename << "> descriptor, line " << line << ", column " << column << ":\n" << msg;
714     throw IceXML::ParserException(__FILE__, __LINE__, os.str());
715 }
716 
717 const ApplicationDescriptor&
getApplicationDescriptor() const718 DescriptorHandler::getApplicationDescriptor() const
719 {
720     if(!_currentApplication.get())
721     {
722         error("no application descriptor defined in this file");
723     }
724     return _currentApplication->getDescriptor();
725 }
726 
727 bool
isCurrentTargetDeployable() const728 DescriptorHandler::isCurrentTargetDeployable() const
729 {
730     return _isCurrentTargetDeployable;
731 }
732 
733 vector<string>
getTargets(const string & targets) const734 DescriptorHandler::getTargets(const string& targets) const
735 {
736     vector<string> result;
737 
738     if(!targets.empty())
739     {
740         const string delim = " \t\n\r";
741 
742         string::size_type beg = 0;
743         string::size_type end = 0;
744         do
745         {
746             end = targets.find_first_of(delim, end);
747             if(end == string::npos)
748             {
749                 end = targets.size();
750             }
751 
752             result.push_back(targets.substr(beg, end - beg));
753             beg = ++end;
754         }
755         while(end < targets.size());
756     }
757 
758     copy(_targets.begin(), _targets.end(), back_inserter(result));
759 
760     return result;
761 }
762 
763 void
error(const string & msg) const764 DescriptorHandler::error(const string& msg) const
765 {
766     ostringstream os;
767     os << "error in <" << _filename << "> descriptor, line " << _line << ", column " << _column << ":\n" << msg;
768     throw IceXML::ParserException(__FILE__, __LINE__, os.str());
769 }
770 
771 string
elementValue()772 DescriptorHandler::elementValue()
773 {
774     string tmp;
775     tmp = _data;
776     _data = "";
777     return tmp;
778 }
779 
780 bool
isTargetDeployable(const string & target) const781 DescriptorHandler::isTargetDeployable(const string& target) const
782 {
783     string application = _currentApplication.get() ? _currentApplication->getDescriptor().name : string("");
784     string node = _currentNode.get() ? _currentNode->getName() : string("");
785     string server = _currentServer.get() ? _currentServer->getDescriptor()->id : string("");
786     string service = _currentService.get() ? _currentService->getDescriptor()->name : string("");
787 
788     //
789     // Compute the current fully qualified name of the communicator.
790     //
791     string fqn;
792     if(!application.empty())
793     {
794         fqn += (fqn.empty() ? "" : ".") + application;
795     }
796     if(!node.empty())
797     {
798         fqn += (fqn.empty() ? "" : ".") + node;
799     }
800     if(!server.empty())
801     {
802         fqn += (fqn.empty() ? "" : ".") + server;
803     }
804     if(!service.empty())
805     {
806         fqn += (fqn.empty() ? "" : ".") + service;
807     }
808 
809     //
810     // Go through the list of supplied targets and see if we can match one with the current communicator + target.
811     //
812     for(vector<string>::const_iterator p = _targets.begin(); p != _targets.end(); ++p)
813     {
814         if((*p) == target)
815         {
816             //
817             // A supplied target without any communicator prefix is matching the target.
818             //
819             return true;
820         }
821         else
822         {
823             string communicatorTarget;
824             string::size_type end = 0;
825             while(end != string::npos)
826             {
827                 //
828                 // Add the first communicator name from the communicator fully qualified name to the
829                 // target and see if matches.
830                 //
831                 end = fqn.find('.', end);
832                 if(end == string::npos)
833                 {
834                     communicatorTarget = fqn + "." + target;
835                 }
836                 else
837                 {
838                     communicatorTarget = fqn.substr(0, end) + "." + target;
839                     ++end;
840                 }
841 
842                 if((*p) == communicatorTarget)
843                 {
844                     return true;
845                 }
846             }
847         }
848     }
849 
850     return false;
851 }
852 
853 ApplicationDescriptor
parseDescriptor(const string & descriptor,const Ice::StringSeq & targets,const map<string,string> & variables,const Ice::CommunicatorPtr & communicator,const IceGrid::AdminPrx & admin)854 DescriptorParser::parseDescriptor(const string& descriptor,
855                                   const Ice::StringSeq& targets,
856                                   const map<string, string>& variables,
857                                   const Ice::CommunicatorPtr& communicator,
858                                   const IceGrid::AdminPrx& admin)
859 {
860     string filename = IcePatch2Internal::simplify(descriptor);
861     DescriptorHandler handler(filename, communicator);
862     handler.setAdmin(admin);
863     handler.setVariables(variables, targets);
864     IceXML::Parser::parse(filename, handler);
865     return handler.getApplicationDescriptor();
866 }
867 
868 ApplicationDescriptor
parseDescriptor(const string & descriptor,const Ice::CommunicatorPtr & communicator)869 DescriptorParser::parseDescriptor(const string& descriptor, const Ice::CommunicatorPtr& communicator)
870 {
871     string filename = IcePatch2Internal::simplify(descriptor);
872     DescriptorHandler handler(filename, communicator);
873     IceXML::Parser::parse(filename, handler);
874     return handler.getApplicationDescriptor();
875 }
876