From f496752b90c2d5c9099b7dbca383bd30820a6ebd Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Fri, 1 Apr 2005 15:42:10 +0000 Subject: Copied IcePack code to IceGrid. --- cpp/src/IceGrid/DescriptorParser.cpp | 821 +++++++++++++++++++++++++++++++++++ 1 file changed, 821 insertions(+) create mode 100644 cpp/src/IceGrid/DescriptorParser.cpp (limited to 'cpp/src/IceGrid/DescriptorParser.cpp') diff --git a/cpp/src/IceGrid/DescriptorParser.cpp b/cpp/src/IceGrid/DescriptorParser.cpp new file mode 100644 index 00000000000..ea175e8f467 --- /dev/null +++ b/cpp/src/IceGrid/DescriptorParser.cpp @@ -0,0 +1,821 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 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. +// +// ********************************************************************** + +#include +#include +#include +#include + +#include +#include + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class DescriptorHandler : public IceXML::Handler +{ +public: + + DescriptorHandler(const string&); + + void setCommunicator(const Ice::CommunicatorPtr&); + void setVariables(const std::map&); + void setTargets(const std::vector&); + + virtual void startElement(const string&, const IceXML::Attributes&, int, int); + virtual void endElement(const string&, int, int); + virtual void characters(const string&, int, int); + virtual void error(const string&, int, int); + + const ApplicationDescriptorPtr& getApplicationDescriptor() const; + const ServerDescriptorPtr& getServerDescriptor() const; + +private: + + std::string getAttributeValue(const IceXML::Attributes&, const std::string&) const; + std::string getAttributeValueWithDefault(const IceXML::Attributes&, const std::string&, const std::string&) const; + bool isCurrentTargetDeployable() const; + std::string substitute(const std::string&) const; + std::string elementValue() const; + std::vector getTargets(const std::string&) const; + void error(const string&) const; + + const std::string& getVariable(const std::string&) const; + bool hasVariable(const std::string&) const; + bool isTargetDeployable(const std::string&) const; + + Ice::CommunicatorPtr _communicator; + string _filename; + std::vector _targets; + std::vector< std::map > _variables; + std::stack _elements; + int _targetCounter; + bool _isCurrentTargetDeployable; + int _line; + int _column; + + ApplicationDescriptorPtr _currentApplication; + ServerDescriptorPtr _currentServer; + ServiceDescriptorPtr _currentService; + ComponentDescriptorPtr _currentComponent; + AdapterDescriptor _currentAdapter; + DbEnvDescriptor _currentDbEnv; + + bool _isTopLevel; + bool _inProperties; + bool _inAdapters; +}; + +} + +DescriptorHandler::DescriptorHandler(const string& filename) : + _filename(filename), + _isCurrentTargetDeployable(true), + _isTopLevel(true), + _inProperties(false), + _inAdapters(false) +{ + _variables.push_back(map()); +} + +void +DescriptorHandler::setCommunicator(const Ice::CommunicatorPtr& communicator) +{ + _communicator = communicator; +} + +void +DescriptorHandler::setVariables(const std::map& variables) +{ + _variables.clear(); + _variables.push_back(variables); +} + +void +DescriptorHandler::setTargets(const vector& targets) +{ + _targets = targets; +} + +void +DescriptorHandler::startElement(const string& name, const IceXML::Attributes& attrs, int line, int column) +{ + _line = line; + _column = column; + + if(name == "icegrid") + { + if(!_isTopLevel) + { + error("element is a top level element"); + } + _isTopLevel = false; + } + else if(_isTopLevel) + { + error("only the element is allowed at the top-level"); + } + else if(name == "target") + { + if(!_isCurrentTargetDeployable) + { + ++_targetCounter; + } + else + { + _isCurrentTargetDeployable = isTargetDeployable(getAttributeValue(attrs, "name")); + _targetCounter = 1; + return; + } + } + else if(!isCurrentTargetDeployable()) + { + // + // We don't bother to parse the elements if the elements are enclosed in a target element + // which won't be deployed. + // + return; + } + else if(name == "include") + { + _variables.push_back(map()); + + string file; + string targets; + + for(IceXML::Attributes::const_iterator p = attrs.begin(); p != attrs.end(); ++p) + { + if(p->first == "descriptor") + { + file = substitute(p->second); + } + else if(p->first == "targets") + { + targets = substitute(p->second); + } + else + { + string v = substitute(p->second); + _variables.back()[p->first] = v; + } + } + + if(file.empty()) + { + error("attribute `descriptor' is mandatory in element "); + } + + if(file[0] != '/') + { + string::size_type end = _filename.find_last_of('/'); + if(end != string::npos) + { + file = _filename.substr(0, end) + "/" + file; + } + } + + string oldFileName = _filename; + vector oldTargets = _targets; + _isTopLevel = true; + _filename = file; + _targets = getTargets(targets); + + IceXML::Parser::parse(file, *this); + + _variables.pop_back(); + _filename = oldFileName; + _targets = oldTargets; + } + else if(name == "application") + { + if(_currentApplication) + { + error("only one element is allowed"); + } + _currentApplication = new ApplicationDescriptor(); + _currentApplication->name = getAttributeValue(attrs, "name"); + _variables.back()["application"] = _currentApplication->name; + } + else if(name == "node") + { + _variables.back()["node"] = getAttributeValue(attrs, "name"); + } + else if(name == "server") + { + if(!hasVariable("node")) + { + error("the element can only be a child of a element"); + } + + string kind = getAttributeValue(attrs, "kind"); + if(kind == "cpp" || kind == "cs") + { + _currentServer = new ServerDescriptor(); + _currentServer->exe = getAttributeValue(attrs, "exe"); + } + else if(kind == "java") + { + JavaServerDescriptorPtr descriptor = new JavaServerDescriptor(); + _currentServer = descriptor; + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java"); + descriptor->className = getAttributeValue(attrs, "classname"); + } + else if(kind == "cpp-icebox") + { + _currentServer = new CppIceBoxDescriptor(); + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "icebox"); + } + else if(kind == "java-icebox") + { + JavaIceBoxDescriptorPtr descriptor = new JavaIceBoxDescriptor(); + _currentServer = descriptor; + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java"); + descriptor->className = getAttributeValueWithDefault(attrs, "classname", "IceBox.Server"); + } + + _currentServer->name = getAttributeValue(attrs, "name"); + _currentServer->node = getVariable("node"); + _currentServer->pwd = getAttributeValueWithDefault(attrs, "pwd", ""); + _currentServer->activation = + getAttributeValueWithDefault(attrs, "activation", "manual") == "on-demand" ? OnDemand : Manual; + + if(_currentApplication) + { + _currentServer->application = _currentApplication->name; + } + + if(kind == "cpp-icebox" || kind == "java-icebox") + { + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(cppIceBox) + { + cppIceBox->endpoints = getAttributeValue(attrs, "endpoints"); + } + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(javaIceBox) + { + javaIceBox->endpoints = getAttributeValue(attrs, "endpoints"); + } + + PropertyDescriptor prop; + prop.name = "IceBox.ServiceManager.Identity"; + prop.value = _currentServer->name + "/ServiceManager"; + _currentServer->properties.push_back(prop); + + AdapterDescriptor adapter; + adapter.name = "IceBox.ServiceManager"; + adapter.endpoints = getAttributeValue(attrs, "endpoints"); + adapter.id = _currentServer->name + "." + adapter.name; + adapter.registerProcess = true; + _currentServer->adapters.push_back(adapter); + } + + _currentComponent = _currentServer; + _variables.back()["server"] = _currentServer->name; + } + else if(name == "service") + { + if(!CppIceBoxDescriptorPtr::dynamicCast(_currentServer) && + !JavaIceBoxDescriptorPtr::dynamicCast(_currentServer)) + { + error("element can only be a child of an IceBox element"); + } + + _currentService = new ServiceDescriptor(); + _currentService->name = getAttributeValue(attrs, "name"); + _currentService->entry = getAttributeValue(attrs, "entry"); + + _currentComponent = _currentService; + _variables.back()["service"] = _currentService->name; + } + else if(name == "variable") + { + _variables.back()[getAttributeValue(attrs, "name")] = getAttributeValueWithDefault(attrs, "value", ""); + } + else if(name == "properties") + { + if(!_currentComponent) + { + error("the element can only be a child of a or element"); + } + + _inProperties = true; + } + else if(name == "property") + { + if(!_inProperties) + { + error("the element can only be a child of a element"); + } + + PropertyDescriptor prop; + prop.name = getAttributeValue(attrs, "name"); + prop.value = getAttributeValueWithDefault(attrs, "value", ""); + _currentComponent->properties.push_back(prop); + } + else if(name == "adapters") + { + if(!_currentComponent) + { + error("the element can only be a child of a or element"); + } + + _inAdapters = true; + } + else if(name == "adapter") + { + if(!_inAdapters) + { + error("the element can only be a child of an element"); + } + + _currentAdapter.name = getAttributeValue(attrs, "name"); + _currentAdapter.id = getAttributeValueWithDefault(attrs, "id", ""); + if(_currentAdapter.id.empty()) + { + string service = getVariable("service"); + const string fqn = getVariable("server") + (service.empty() ? "" : ".") + service; + _currentAdapter.id = fqn + "." + _currentAdapter.name; + } + _currentAdapter.endpoints = getAttributeValue(attrs, "endpoints"); + _currentAdapter.registerProcess = getAttributeValueWithDefault(attrs, "register", "false") == "true"; + } + else if(name == "object") + { + if(_currentAdapter.name.empty()) + { + error("the element can only be a child of an element"); + } + + ObjectDescriptor object; + object.type = getAttributeValueWithDefault(attrs, "type", ""); + object.proxy = _communicator->stringToProxy(getAttributeValue(attrs, "identity") + "@" + _currentAdapter.id); + object.adapterId = _currentAdapter.id; + _currentAdapter.objects.push_back(object); + } + else if(name == "dbenv") + { + if(!_currentComponent) + { + error("the element can only be a child of a or element"); + } + + _currentDbEnv.name = getAttributeValue(attrs, "name"); + + DbEnvDescriptorSeq::iterator p; + for(p = _currentComponent->dbEnvs.begin(); p != _currentComponent->dbEnvs.end(); ++p) + { + // + // We are re-opening the dbenv element to define more properties. + // + if(p->name == _currentDbEnv.name) + { + break; + } + } + + if(p != _currentComponent->dbEnvs.end()) + { + // + // Remove the previously defined dbenv, we'll add it back again when + // the dbenv element end tag is reached. + // + _currentDbEnv = *p; + _currentComponent->dbEnvs.erase(p); + } + + if(_currentDbEnv.dbHome.empty()) + { + _currentDbEnv.dbHome = getAttributeValueWithDefault(attrs, "home", ""); + } + } + else if(name == "dbproperty") + { + if(_currentDbEnv.name.empty()) + { + error("the element can only be a child of a element"); + } + + PropertyDescriptor prop; + prop.name = getAttributeValue(attrs, "name"); + prop.value = getAttributeValueWithDefault(attrs, "value", ""); + _currentDbEnv.properties.push_back(prop); + } + + _elements.push(""); +} + +void +DescriptorHandler::endElement(const string& name, int line, int column) +{ + _line = line; + _column = column; + + if(name == "target") + { + if(!_isCurrentTargetDeployable && --_targetCounter == 0) + { + _isCurrentTargetDeployable = true; + _targetCounter = 0; + } + return; + } + else if(!isCurrentTargetDeployable()) + { + // + // We don't bother to parse the elements if the elements are enclosed in a target element + // which won't be deployed. + // + return; + } + else if(name == "application") + { + _variables.back()["application"] = ""; + } + else if(name == "node") + { + _variables.back()["node"] = ""; + } + else if(name == "server") + { + if(_currentApplication) + { + _currentApplication->servers.push_back(_currentServer); + _currentServer = 0; + } + _currentComponent = 0; + _variables.back()["server"] = ""; + } + else if(name == "service") + { + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(cppIceBox) + { + cppIceBox->services.push_back(_currentService); + } + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(javaIceBox) + { + javaIceBox->services.push_back(_currentService); + } + _currentService = 0; + _currentComponent = _currentServer; + _variables.back()["service"] = ""; + } + else if(name == "comment") + { + if(_currentComponent) + { + _currentComponent->comment = elementValue(); + } + else if(_currentApplication) + { + _currentApplication->comment = elementValue(); + } + } + else if(name == "option") + { + if(!_currentServer) + { + error("element