// -*- indent-tabs-mode: nil -*- #ifndef __ARC_JOBDESCRIPTIONPARSERPLUGIN_H__ #define __ARC_JOBDESCRIPTIONPARSERPLUGIN_H__ /** \file * \brief Plugin, loader and argument classes for job description parser specialisation. */ #include #include #include #include #include #include namespace Arc { class JobDescription; class Logger; /** * \ingroup accplugins * \headerfile JobDescriptionParserPlugin.h arc/compute/JobDescriptionParserPlugin.h */ /** * \since Added in 5.1.0 **/ class JobDescriptionParsingError { public: JobDescriptionParsingError() {} JobDescriptionParsingError(const std::string& message, const std::pair& line_pos = std::make_pair(0, 0), const std::string& failing_code = "") : message(message), failing_code(failing_code), line_pos(line_pos) {} ~JobDescriptionParsingError() {} std::string message; std::string failing_code; std::pair line_pos; }; class JobDescriptionParserPluginResult { public: typedef enum { Success, Failure, /**< Parsing failed **/ WrongLanguage } Result; JobDescriptionParserPluginResult(void):v_(Success) { }; JobDescriptionParserPluginResult(bool v):v_(v?Success:Failure) { }; JobDescriptionParserPluginResult(Result v):v_(v) { }; operator bool(void) { return (v_ == Success); }; bool operator!(void) { return (v_ != Success); }; bool operator==(bool v) { return ((v_ == Success) == v); }; bool operator==(Result v) { return (v_ == v); }; /** * \since Added in 5.1.0 **/ bool HasErrors() const { return !errors_.empty(); }; /** * \since Added in 5.1.0 **/ const std::list& GetErrors() const { return errors_; }; /** * \since Added in 5.1.0 **/ void AddError(const JobDescriptionParsingError& error) { errors_.push_back(error); }; /** * \since Added in 5.1.0 **/ void AddError(const IString& msg, const std::pair& location = std::make_pair(0, 0), const std::string& failing_code = "") { errors_.push_back(JobDescriptionParsingError(msg.str(), location, failing_code)); } /** * \since Added in 5.1.0 **/ void SetSuccess() { v_ = Success; }; /** * \since Added in 5.1.0 **/ void SetFailure() { v_ = Failure; }; /** * \since Added in 5.1.0 **/ void SetWrongLanguage() {v_ = WrongLanguage; }; private: Result v_; std::list errors_; }; /// Abstract plugin class for different parsers /** * The JobDescriptionParserPlugin class is abstract which provide an interface * for job description parsers. A job description parser should inherit this * class and overwrite the JobDescriptionParserPlugin::Parse and * JobDescriptionParserPlugin::UnParse methods. The inheriating class should * add the job description languages that it supports to the * 'supportedLanguages' member, formatted according to the GLUE2 * JobDescription_t type (GFD-R-P.147). The created job description parser * will then be available to the JobDescription::Parse, * JobDescription::ParseFromFile and JobDescription::Assemble methods, adding * the ability to parse and assemble job descriptions in the specified * languages. * * Using the methods in JobDescription class for parsing job descriptions is * recommended, however it is also possible to use parser plugins directly, * which can be done by loading them using the * JobDescriptionParserPluginLoader class. * * Since this class inheriates from the Plugin class, inheriating classes * should be compiled as a loadable module. See xxx for information on * creating loadable modules for ARC. * * \ingroup accplugins * \headerfile JobDescriptionParserPlugin.h arc/compute/JobDescriptionParserPlugin.h */ class JobDescriptionParserPlugin : public Plugin { public: virtual ~JobDescriptionParserPlugin(); /// Parse string into JobDescription objects /** * Parses the string argument \p source into JobDescription objects. If the * \p language argument is specified the method will only parse the string * if it supports that language - a JobDescriptionParserPluginResult object * with status \ref JobDescriptionParserPluginResult::WrongLanguage "WrongLanguage" * is returned if language is not supported. Similar for the \p dialect * argument, if specified, string is only parsed if that dialect is known * by parser. * If the \p language argument is not specified an attempt at parsing * \p source using any of the supported languages is tried. * If parsing is successful the generated JobDescription objects is appended * to the \p jobdescs argument. If parsing is unsuccessful the \p jobdescs * argument is untouched, and details of the failure is returned. * * Inheriating classes must extend this method. The extended method should * parse the \p source argument string into a JobDescription object, possibly * into multiple objects. Some languages can contain multiple alternative * views, in such cases alternatives should be added using the * JobDescription::AddAlternative method. Only if parsing is successful * should the generated JobDescription objects be added to the \p jobdescs * argument. Note: The only allowed modification of the \p jobdescs list is * adding elements. If the \p language argument is specified parsing should * only be initiated if the specified language is among the supported * ones, if that is not the case \ref JobDescriptionParserPluginResult::WrongLanguage "WrongLanguage" * should be returned. * If the \p language argument * For some languages different dialects exist (e.g. user- and GM- side xRSL), * and if the \p dialect argument is specified the * parsing must strictly conform to that dialect. If the dialect is unknown * \ref JobDescriptionParserPluginResult::WrongLanguage "WrongLanguage" * should be returned. * * \param source should contain a representation of job description as a * string. * \param jobdescs a reference to a list of JobDescription object which * parsed job descriptions should be appended to. * \param language if specified parse in specified language (if not supported * \ref JobDescriptionParserPluginResult::WrongLanguage "WrongLanguage" is * returned). * \param dialect if specified parsing conforms strictly to specified * dialect. * \return A JobDescriptionParserPluginResult is returned indicating outcome * of parsing. * \see JobDescriptionParserPlugin::Assemble * \see JobDescriptionParserPluginResult **/ virtual JobDescriptionParserPluginResult Parse(const std::string& source, std::list& jobdescs, const std::string& language = "", const std::string& dialect = "") const = 0; /// Assemble job description into string /** * \since Added in 5.1.0 **/ virtual JobDescriptionParserPluginResult Assemble(const JobDescription& job, std::string& output, const std::string& language, const std::string& dialect = "") const = 0; /// [DEPRECATED] Assemble job description into string /** * \deprecated Deprecated as of 5.1.0, use the * JobDescriptionParserPlugin::Assemble method instead - expected to be * removed in 6.0.0. **/ virtual JobDescriptionParserPluginResult UnParse(const JobDescription& job, std::string& output, const std::string& language, const std::string& dialect = "") const { return Assemble(job, output, language, dialect); }; /// Get supported job description languages /** * \return A list of job description languages supported by this parser is * returned. **/ const std::list& GetSupportedLanguages() const { return supportedLanguages; } /// Check if language is supported /** * \param language a string formatted according to the GLUE2 * JobDescription_t type (GFD-R-P.147), e.g. nordugrid:xrsl. * \return \c true is returned if specified language is supported. **/ bool IsLanguageSupported(const std::string& language) const { return std::find(supportedLanguages.begin(), supportedLanguages.end(), language) != supportedLanguages.end(); } /// [DEPRECATED] Get parsing error /** * \deprecated Deprecated as of 5.1.0 - expected to be removed in 6.0.0. **/ const std::string& GetError(void) { return error; }; protected: JobDescriptionParserPlugin(PluginArgument* parg); /// [DEPRECATED] Get reference to sourceLanguage member /** * \deprecated Deprecated as of 5.1.0 - expected to be removed in 6.0.0. **/ std::string& SourceLanguage(JobDescription& j) const; /// List of supported job description languages /** * Inheriating classes should add languages supported to this list in * the constructor. **/ std::list supportedLanguages; /// [DEPRECATED] Parsing error /** * \deprecated Deprecated as of 5.1.0 - expected to be removed in 6.0.0. **/ mutable std::string error; static Logger logger; }; /** Class responsible for loading JobDescriptionParserPlugin plugins * The JobDescriptionParserPlugin objects returned by a * JobDescriptionParserPluginLoader must not be used after the * JobDescriptionParserPluginLoader goes out of scope. * * \ingroup accplugins * \headerfile JobDescriptionParserPlugin.h arc/compute/JobDescriptionParserPlugin.h */ class JobDescriptionParserPluginLoader : public Loader { public: /** Constructor * Creates a new JobDescriptionParserPluginLoader. */ JobDescriptionParserPluginLoader(); /** Destructor * Calling the destructor destroys all JobDescriptionParserPlugin object * loaded by the JobDescriptionParserPluginLoader instance. */ ~JobDescriptionParserPluginLoader(); /** Load a new JobDescriptionParserPlugin * \param name The name of the JobDescriptionParserPlugin to load. * \return A pointer to the new JobDescriptionParserPlugin (NULL on error). */ JobDescriptionParserPlugin* load(const std::string& name); /** Retrieve the list of loaded JobDescriptionParserPlugin objects. * \return A reference to the list of JobDescriptionParserPlugin objects. */ const std::list& GetJobDescriptionParserPlugins() const { return jdps; } class iterator { private: iterator(JobDescriptionParserPluginLoader& jdpl); iterator& operator=(const iterator& it); public: ~iterator() {} //iterator& operator=(const iterator& it) { current = it.current; jdpl = it.jdpl; return *this; } JobDescriptionParserPlugin& operator*() { return **current; } const JobDescriptionParserPlugin& operator*() const { return **current; } JobDescriptionParserPlugin* operator->() { return *current; } const JobDescriptionParserPlugin* operator->() const { return *current; } iterator& operator++(); operator bool() { return !jdpl->jdpDescs.empty() || current != jdpl->jdps.end(); } friend class JobDescriptionParserPluginLoader; private: void LoadNext(); std::list::iterator current; JobDescriptionParserPluginLoader* jdpl; }; iterator GetIterator() { return iterator(*this); } private: std::list jdps; std::list jdpDescs; void scan(); bool scaningDone; }; } // namespace Arc #endif // __ARC_JOBDESCRIPTIONPARSERPLUGIN_H__