diff options
Diffstat (limited to 'qpid/cpp/managementgen')
18 files changed, 3502 insertions, 0 deletions
diff --git a/qpid/cpp/managementgen/CMakeLists.txt b/qpid/cpp/managementgen/CMakeLists.txt new file mode 100644 index 0000000000..2511b745a3 --- /dev/null +++ b/qpid/cpp/managementgen/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +project(qpidc-qmfgen) +cmake_minimum_required(VERSION 2.4.0 FATAL_ERROR) + +install(PROGRAMS qmf-gen DESTINATION managementgen + COMPONENT ${QPID_COMPONENT_QMF}) +install(DIRECTORY qmfgen DESTINATION managementgen + COMPONENT ${QPID_COMPONENT_QMF} + PATTERN ".svn" EXCLUDE PATTERN "*.pyc" EXCLUDE) diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am new file mode 100644 index 0000000000..8769200719 --- /dev/null +++ b/qpid/cpp/managementgen/Makefile.am @@ -0,0 +1,39 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +qmfpythondir = $(pythondir) +dist_bin_SCRIPTS = \ + qmf-gen +pkgpyexec_qmfgendir = $(pyexecdir)/qmfgen +pkgpyexec_qmfgen_PYTHON = \ + qmfgen/__init__.py \ + qmfgen/generate.py \ + qmfgen/schema.py \ + qmfgen/templates/Args.h \ + qmfgen/templates/Class.cpp \ + qmfgen/templates/Class.h \ + qmfgen/templates/Event.cpp \ + qmfgen/templates/Event.h \ + qmfgen/templates/Makefile.mk \ + qmfgen/templates/Package.cpp \ + qmfgen/templates/Package.h \ + qmfgen/templates/V2Package.cpp \ + qmfgen/templates/V2Package.h \ + qmfgen/management-types.xml + +EXTRA_DIST = $(nobase_qmfpython_DATA) CMakeLists.txt diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen new file mode 100755 index 0000000000..6e8f864256 --- /dev/null +++ b/qpid/cpp/managementgen/qmf-gen @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys +import os +from qmfgen.schema import SchemaPackage, SchemaClass +from qmfgen.generate import Generator +from optparse import OptionParser + +dataPath = os.path.dirname(Generator.getModulePath()) +defaultTypeFile = dataPath + "/management-types.xml" +defaultTemplateDir = dataPath + "/templates" + +# Set command line options +usage = "usage: %prog [options] schema-document..." +parser = OptionParser(usage=usage) +parser.add_option("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", + help="Output directory") +parser.add_option("-c", "--cmakelists", dest="cmakelists", metavar="FILE", + help="CMakeLists fragment") +parser.add_option("-m", "--makefile", dest="makefile", metavar="FILE", + help="Makefile fragment") +parser.add_option("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, + help="Override type descriptor file") +parser.add_option("-d", "--templatedir", dest="templatedir", metavar="DIR", default=defaultTemplateDir, + help="Override template directory") +parser.add_option("-p", "--gen-prefix", dest="genprefix", default="", + help="Prefix for generated files in make dependencies") +parser.add_option("-q", "--qpid-broker", dest="qpidbroker", default=False, action="store_true", + help="Generate makefile for Qpid broker") +parser.add_option("-b", "--broker-plugin", dest="brokerplugin", default=False, action="store_true", + help="Generate code for use in a qpid broker plugin") +parser.add_option("-2", "--v2-style", dest="v2_style", default=False, action="store_true", + help="Generate code for use with the QMFv2 Agent API") + +(opts, args) = parser.parse_args() + +typefile = opts.typefile +templatedir = opts.templatedir +outdir = opts.outputdir +v2_style = opts.v2_style +gen = Generator(outdir, templatedir) + +if len(args) == 0: + print "no input files" + parser.exit() + +vargs = {} +if opts.brokerplugin: + vargs["agentHeaderDir"] = "management" + vargs["genQmfV1"] = True +else: + vargs["agentHeaderDir"] = "agent" + vargs["genQmfV1"] = None + +for schemafile in args: + package = SchemaPackage(typefile, schemafile, opts) + + gen.setPackage(package.packageName) + + if v2_style: + gen.makeV2PackageFile("V2Package.h", package, vars=vargs) + gen.makeV2PackageFile("V2Package.cpp", package, vars=vargs) + else: + gen.makeClassFiles ("Class.h", package, vars=vargs) + gen.makeClassFiles ("Class.cpp", package, vars=vargs) + gen.makeMethodFiles ("Args.h", package, vars=vargs) + gen.makeEventFiles ("Event.h", package, vars=vargs) + gen.makeEventFiles ("Event.cpp", package, vars=vargs) + gen.makePackageFile ("Package.h", package, vars=vargs) + gen.makePackageFile ("Package.cpp", package, vars=vargs) + +if opts.makefile != None: + args = {} + args["qpidbroker"] = opts.qpidbroker + args["genprefix"] = opts.genprefix + gen.makeSingleFile("Makefile.mk", opts.makefile, force=True, vars=args) + +if opts.cmakelists != None: + args = {} + args["qpidbroker"] = opts.qpidbroker + args["genprefix"] = opts.genprefix + gen.makeSingleFile("CMakeLists.cmake", opts.cmakelists, force=True, vars=args) diff --git a/qpid/cpp/managementgen/qmfgen/__init__.py b/qpid/cpp/managementgen/qmfgen/__init__.py new file mode 100644 index 0000000000..63a3f41f28 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/__init__.py @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py new file mode 100755 index 0000000000..4e688e3bc7 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -0,0 +1,494 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from xml.dom.minidom import parse, parseString, Node +from cStringIO import StringIO +from stat import * +from errno import * +import os +import os.path +import filecmp +import re + +class Template: + """ + Expandable File Template - This class is instantiated each time a + template is to be expanded. It is instantiated with the "filename" + which is the full path to the template file and the "handler" which + is an object that is responsible for storing variables (setVariable), + checking conditions (testCondition), and expanding tags (substHandler). + """ + def __init__ (self, filename, handler): + self.filename = filename + self.handler = handler + self.handler.initExpansion () + self.writing = 0 # 0 => write output lines; >0 => recursive depth of conditional regions + + def expandLine (self, line, stream, object): + cursor = 0 + while 1: + sub = line.find ("/*MGEN:", cursor) + if sub == -1: + if self.writing == 0: + stream.write (line[cursor:len (line)]) + return + + subend = line.find("*/", sub) + if self.writing == 0: + stream.write (line[cursor:sub]) + cursor = subend + 2 + + tag = line[sub:subend] + + if tag[7:10] == "IF(": + if self.writing == 0: + close = tag.find(")") + if close == -1: + raise ValueError ("Missing ')' on condition") + cond = tag[10:close] + dotPos = cond.find (".") + if dotPos == -1: + raise ValueError ("Invalid condition tag: %s" % cond) + tagObject = cond[0:dotPos] + tagName = cond[dotPos + 1 : len(cond)] + if not self.handler.testCondition(object, tagObject, tagName): + self.writing += 1 + else: + self.writing += 1 + + elif tag[7:12] == "ENDIF": + if self.writing > 0: + self.writing -= 1 + + else: + equalPos = tag.find ("=") + if equalPos == -1: + dotPos = tag.find (".") + if dotPos == -1: + raise ValueError ("Invalid tag: %s" % tag) + tagObject = tag[7:dotPos] + tagName = tag[dotPos + 1:len (tag)] + if self.writing == 0: + self.handler.substHandler (object, stream, tagObject, tagName) + else: + tagKey = tag[7:equalPos] + tagVal = tag[equalPos + 1:len (tag)] + if self.writing == 0: + self.handler.setVariable (tagKey, tagVal) + + def expand (self, object): + fd = open (self.filename) + stream = StringIO () + + for line in fd: + self.expandLine (line, stream, object) + fd.close () + + return stream + + +class Makefile: + """ Object representing a makefile fragment """ + def __init__ (self, filelists, templateFiles, packagelist): + self.filelists = filelists + self.templateFiles = templateFiles + self.packagelist = packagelist + + def genGenSources (self, stream, variables): + mdir = variables["mgenDir"] + sdir = variables["specDir"] + stream.write (mdir + "/qmf-gen \\\n") + stream.write (" " + mdir + "/qmfgen/generate.py \\\n") + stream.write (" " + mdir + "/qmfgen/schema.py \\\n") + stream.write (" " + mdir + "/qmfgen/management-types.xml \\\n") + stream.write (" " + sdir + "/management-schema.xml \\\n") + first = True + for template in self.templateFiles: + if first: + first = False + stream.write (" ") + else: + stream.write (" \\\n ") + stream.write (mdir + "/qmfgen/templates/" + template) + + def genGenCppFiles (self, stream, variables): + first = True + for file in self.filelists["cpp"]: + if first: + first = False + else: + stream.write (" \\\n ") + stream.write (file) + + def genGenHFiles (self, stream, variables): + first = True + for file in self.filelists["h"]: + if first: + first = False + else: + stream.write (" \\\n ") + stream.write (file) + + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \\\n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(file) + + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + name = "_".join(package.split("/")) + stream.write(name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + if file.find("qmf/" + package) == 0: + if first: + first = False + else: + stream.write (" \\\n ") + stream.write(file) + stream.write("\n\n") + + def testQpidBroker(self, variables): + if "qpidbroker" in variables: + return variables["qpidbroker"] + return False + +class CMakeLists(Makefile): + """ Object representing a makefile fragment """ + + # Regardless of what normalize() did, switch all the dir separators back + # to '/' - cmake expects that regardless of platform. + def unNormCase (self, path): + return re.sub("\\\\", "/", path) + + def genGenSources (self, stream, variables): + mdir = self.unNormCase(variables["mgenDir"]) + sdir = self.unNormCase(variables["specDir"]) + stream.write (mdir + "/qmf-gen \n") + stream.write (" " + mdir + "/qmfgen/generate.py\n") + stream.write (" " + mdir + "/qmfgen/schema.py\n") + stream.write (" " + mdir + "/qmfgen/management-types.xml\n") + stream.write (" " + sdir + "/management-schema.xml\n") + first = True + for template in self.templateFiles: + if first: + first = False + stream.write (" ") + else: + stream.write ("\n ") + stream.write (mdir + "/qmfgen/templates/" + template) + + def genGenCppFiles (self, stream, variables): + first = True + for file in self.filelists["cpp"]: + if first: + first = False + else: + stream.write (" \n ") + stream.write (self.unNormCase(file)) + + def genGenHFiles (self, stream, variables): + first = True + for file in self.filelists["h"]: + if first: + first = False + else: + stream.write (" \n ") + stream.write (self.unNormCase(file)) + + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(self.unNormCase(file)) + + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + stream.write("#Come back to this later...\n") + name = "_".join(package.split("/")) + stream.write("#" + name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("#dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + file = self.unNormCase(file) + if file.find("qmf/" + package) == 0: + if first: + first = False + else: + stream.write ("\n ") + stream.write("#" + file) + stream.write("\n\n") + + +class Generator: + """ + This class manages code generation using template files. It is instantiated + once for an entire code generation session. + """ + def createPath (self, path): + exists = True + try: + mode = os.stat (path)[ST_MODE] + except OSError, (err,text): + if err == ENOENT or err == ESRCH: + exists = False + else: + raise + if exists and not S_ISDIR (mode): + raise ValueError ("path is not directory: %s" % path) + if not exists: + pair = os.path.split (path) + if pair[0] != '': + self.createPath (pair[0]) + os.mkdir (path) + + def normalize (self, path): + newpath = os.path.normcase (os.path.normpath (path)) + self.createPath (newpath) + return newpath + "/" + + def __init__ (self, destDir, templateDir): + self.dest = self.normalize (destDir) + self.input = self.normalize (templateDir) + self.packagePath = self.dest + self.filelists = {} + self.filelists["h"] = [] + self.filelists["cpp"] = [] + self.filelists["mk"] = [] + self.filelists["cmake"] = [] + self.packagelist = [] + self.templateFiles = [] + self.variables = {} + + def setPackage (self, packageName): + path = "/".join(packageName.split(".")) + self.packagelist.append(path) + self.packagePath = self.normalize(self.dest + path) + + def testGenQMFv1 (self, variables): + return variables["genQmfV1"] + + def genDisclaimer (self, stream, variables): + prefix = variables["commentPrefix"] + stream.write (prefix + " This source file was created by a code generator.\n") + stream.write (prefix + " Please do not edit.") + + def fileExt (self, path): + dot = path.rfind (".") + if dot == -1: + return "" + return path[dot + 1:] + + def writeIfChanged (self, stream, target, force=False): + ext = self.fileExt (target) + self.filelists[ext].append (target) + tempFile = target + ".gen.tmp" + fd = open (tempFile, "w") + fd.write (stream.getvalue ()) + fd.close () + + try: + if not force and filecmp.cmp (target, tempFile): + os.remove (tempFile) + return + except: + pass + + try: + os.remove (target) + except: + pass + + os.rename (tempFile, target) + print "Generated:", target + + def targetPackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "Package" + extension + return path + + def targetV2PackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "QmfPackage" + extension + return path + + def targetClassFile (self, _class, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + _class.getNameCap () + extension + return path + + def targetEventFile (self, event, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "Event" + event.getNameCap () + extension + return path + + def targetMethodFile (self, method, templateFile): + """ Return the file name for a method file """ + dot = templateFile.rfind(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:] + path = self.packagePath + "Args" + method.getFullName () + extension + return path + + def initExpansion (self): + self.variables = {} + + def substHandler (self, object, stream, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".gen" + tag + "(stream, self.variables)" + eval (call) + + def testCondition (self, object, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".test" + tag + "(self.variables)" + return eval (call) + + def setVariable (self, key, value): + self.variables[key] = value + + def makeClassFiles (self, templateFile, schema, force=False, vars=None): + """ Generate an expanded template per schema class """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + for _class in classes: + target = self.targetClassFile (_class, templateFile) + stream = template.expand (_class) + self.writeIfChanged (stream, target, force) + + def makeEventFiles (self, templateFile, schema, force=False, vars=None): + """ Generate an expanded template per schema event """ + events = schema.getEvents() + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + for event in events: + target = self.targetEventFile(event, templateFile) + stream = template.expand(event) + self.writeIfChanged(stream, target, force) + + def makeMethodFiles (self, templateFile, schema, force=False, vars=None): + """ Generate an expanded template per method-with-arguments """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + for _class in classes: + methods = _class.getMethods () + for method in methods: + if method.getArgCount () > 0: + target = self.targetMethodFile (method, templateFile) + stream = template.expand (method) + self.writeIfChanged (stream, target, force) + + def makePackageFile (self, templateFile, schema, force=False, vars=None): + """ Generate a package-specific file """ + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + target = self.targetPackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + + def makeV2PackageFile (self, templateFile, schema, force=False, vars=None): + """ Generate a QMFv2 package definition file """ + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + target = self.targetV2PackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + + def makeSingleFile (self, templateFile, target, force=False, vars=None): + """ Generate a single expanded template """ + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + className = templateFile[0:dot] + if className == "Makefile": + classType = Makefile + elif className == "CMakeLists": + classType = CMakeLists + else: + raise ValueError ("Invalid class name %s" % className) + makefile = classType (self.filelists, self.templateFiles, self.packagelist) + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + stream = template.expand (makefile) + self.writeIfChanged (stream, target, force) + + def getModulePath(): + return __file__ + + getModulePath = staticmethod(getModulePath) diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml new file mode 100644 index 0000000000..c88f0caeae --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -0,0 +1,77 @@ +<schema-types> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<!-- "unmap": cast to convert from Variant to native type constructor, + "map": cast to convert from native type to Variant constructor parameter +--> + +<type name="objId" base="REF" cpp="::qpid::management::ObjectId" + encode="{std::string _s; #.encode(_s); @.putRawData(_s);}" + decode="{std::string _s; @.getRawData(_s, #.encodedSize()); #.decode(_s);}" + stream="#.getV2Key()" size="16" accessor="direct" init="::qpid::management::ObjectId()" byRef="y"/> +<type name="uint8" base="U8" cpp="uint8_t" encode="@.putOctet(#)" decode="# = @.getOctet()" stream="#" size="1" accessor="direct" init="0"/> +<type name="uint16" base="U16" cpp="uint16_t" encode="@.putShort(#)" decode="# = @.getShort()" stream="#" size="2" accessor="direct" init="0"/> +<type name="uint32" base="U32" cpp="uint32_t" encode="@.putLong(#)" decode="# = @.getLong()" stream="#" size="4" accessor="direct" init="0"/> +<type name="uint64" base="U64" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" stream="#" size="8" accessor="direct" init="0"/> +<type name="int8" base="S8" cpp="int8_t" encode="@.putInt8(#)" decode="# = @.getInt8()" stream="#" size="1" accessor="direct" init="0"/> +<type name="int16" base="S16" cpp="int16_t" encode="@.putInt16(#)" decode="# = @.getInt16()" stream="#" size="2" accessor="direct" init="0"/> +<type name="int32" base="S32" cpp="int32_t" encode="@.putInt32(#)" decode="# = @.getInt32()" stream="#" size="4" accessor="direct" init="0"/> +<type name="int64" base="S64" cpp="int64_t" encode="@.putInt64(#)" decode="# = @.getInt64()" stream="#" size="8" accessor="direct" init="0"/> +<type name="bool" base="BOOL" cpp="bool" encode="@.putOctet(#?1:0)" decode="# = @.getOctet()==1" stream="#" size="1" accessor="direct" init="0"/> +<type name="sstr" base="SSTR" cpp="std::string" encode="@.putShortString(#)" decode="@.getShortString(#)" stream="#" size="(1 + #.length())" accessor="direct" init='""' byRef="y" unmap="(#).getString()"/> +<type name="lstr" base="LSTR" cpp="std::string" encode="@.putMediumString(#)" decode="@.getMediumString(#)" stream="#" size="(2 + #.length())" accessor="direct" init='""' byRef="y" unmap="(#).getString()"/> +<type name="absTime" base="ABSTIME" cpp="int64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" stream="#" size="8" accessor="direct" init="0"/> +<type name="deltaTime" base="DELTATIME" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" stream="#" size="8" accessor="direct" init="0"/> +<type name="float" base="FLOAT" cpp="float" encode="@.putFloat(#)" decode="# = @.getFloat()" stream="#" size="4" accessor="direct" init="0."/> +<type name="double" base="DOUBLE" cpp="double" encode="@.putDouble(#)" decode="# = @.getDouble()" stream="#" size="8" accessor="direct" init="0."/> +<type name="uuid" base="UUID" cpp="::qpid::types::Uuid" + encode="@.putRawData(#.data(), 16)" + decode="{ unsigned char d[16]; @.getRawData(d, 16); # = ::qpid::types::Uuid(d); }" + stream="#" size="16" accessor="direct" init="::qpid::types::Uuid()" byRef="y" + unmap="(#).asUuid().data()" + map="::qpid::types::Uuid((#).data())" /> +<type name="map" base="FTABLE" cpp="::qpid::types::Variant::Map" + encode="@.putMap(#)" + decode="@.getMap(#)" + size="::qpid::amqp_0_10::MapCodec::encodedSize(#)" + stream="#" accessor="direct" init="::qpid::types::Variant::Map()" byRef="y" unmap="(#).asMap()"/> +<type name="list" base="LIST" cpp="::qpid::types::Variant::List" + encode="@.putList(#)" + decode="@.getList(#)" + size="::qpid::amqp_0_10::ListCodec::encodedSize(#)" + stream="#" accessor="direct" init="::qpid::types::Variant::List()" byRef="y" unmap="(#).asList()"/> + +<type name="hilo8" base="U8" cpp="uint8_t" encode="@.putOctet(#)" decode="# = @.getOctet()" style="wm" stream="#" size="1" accessor="counter" init="0"/> +<type name="hilo16" base="U16" cpp="uint16_t" encode="@.putShort(#)" decode="# = @.getShort()" style="wm" stream="#" size="2" accessor="counter" init="0"/> +<type name="hilo32" base="U32" cpp="uint32_t" encode="@.putLong(#)" decode="# = @.getLong()" style="wm" stream="#" size="4" accessor="counter" init="0"/> +<type name="hilo64" base="U64" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" style="wm" stream="#" size="8" accessor="counter" init="0"/> + +<type name="count8" base="U8" cpp="uint8_t" encode="@.putOctet(#)" decode="# = @.getOctet()" stream="#" size="1" accessor="counter" init="0" perThread="y"/> +<type name="count16" base="U16" cpp="uint16_t" encode="@.putShort(#)" decode="# = @.getShort()" stream="#" size="2" accessor="counter" init="0" perThread="y"/> +<type name="count32" base="U32" cpp="uint32_t" encode="@.putLong(#)" decode="# = @.getLong()" stream="#" size="4" accessor="counter" init="0" perThread="y"/> +<type name="count64" base="U64" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" stream="#" size="8" accessor="counter" init="0" perThread="y"/> + +<!-- Min/Max/Average statistics --> +<type name="mma32" base="U32" cpp="uint32_t" encode="@.putLong(#)" decode="# = @.getLong()" style="mma" stream="#" size="4" accessor="direct" init="0" perThread="y"/> +<type name="mma64" base="U64" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" style="mma" stream="#" size="8" accessor="direct" init="0" perThread="y"/> +<type name="mmaTime" base="DELTATIME" cpp="uint64_t" encode="@.putLongLong(#)" decode="# = @.getLongLong()" style="mma" stream="#" size="8" accessor="direct" init="0" perThread="y"/> + +</schema-types> diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py new file mode 100755 index 0000000000..59e951fb6e --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -0,0 +1,1852 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from xml.dom.minidom import parse, parseString, Node +from cStringIO import StringIO +#import md5 +try: + import hashlib + _md5Obj = hashlib.md5 +except ImportError: + import md5 + _md5Obj = md5.new + +class Hash: + """ Manage the hash of an XML sub-tree """ + def __init__(self, node): + self.md5Sum = _md5Obj() + self._compute(node) + + def addSubHash(self, hash): + """ Use this method to add the hash of a dependend-on XML fragment that is not in the sub-tree """ + self.md5Sum.update(hash.getDigest()) + + def getDigest(self): + return self.md5Sum.digest() + + def _compute(self, node): + attrs = node.attributes + self.md5Sum.update(node.nodeName) + + for idx in range(attrs.length): + self.md5Sum.update(attrs.item(idx).nodeName) + self.md5Sum.update(attrs.item(idx).nodeValue) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self._compute(child) + + +#===================================================================================== +# +#===================================================================================== +class SchemaType: + def __init__ (self, node): + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.stream = "#" + self.size = "1" + self.accessor = None + self.init = "0" + self.perThread = False + self.byRef = False + self.unmap = "#" + self.map = "#" + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'base': + self.base = val + + elif key == 'cpp': + self.cpp = val + + elif key == 'encode': + self.encode = val + + elif key == 'decode': + self.decode = val + + elif key == 'style': + self.style = val + + elif key == 'stream': + self.stream = val + + elif key == 'size': + self.size = val + + elif key == 'accessor': + self.accessor = val + + elif key == 'init': + self.init = val + + elif key == 'perThread': + if val != 'y': + raise ValueError ("Expected 'y' in perThread attribute") + self.perThread = True + + elif key == 'byRef': + if val != 'y': + raise ValueError ("Expected 'y' in byRef attribute") + self.byRef = True + + elif key == 'unmap': + self.unmap = val + + elif key == 'map': + self.map = val + + else: + raise ValueError ("Unknown attribute in type '%s'" % key) + + if self.name == None or self.base == None or self.cpp == None or \ + self.encode == None or self.decode == None: + raise ValueError ("Missing required attribute(s) in type") + + if self.byRef: + self.asArg = "const " + self.cpp + "&" + else: + self.asArg = self.cpp + + def getName (self): + return self.name + + def genAccessor (self, stream, varName, changeFlag = None, optional = False): + if self.perThread: + prefix = "getThreadStats()->" + if self.style == "wm": + raise ValueError ("'wm' style types can't be per-thread") + else: + prefix = "" + if self.accessor == "direct": + stream.write (" inline void set_" + varName + " (" + self.asArg + " val) {\n"); + if not self.perThread: + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") + if self.style != "mma": + stream.write (" " + prefix + varName + " = val;\n") + if optional: + stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n") + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n") + if self.style == "mma": + stream.write (" " + prefix + varName + "Count++;\n") + stream.write (" " + prefix + varName + "Total += val;\n") + stream.write (" if (" + prefix + varName + "Min > val)\n") + stream.write (" " + prefix + varName + "Min = val;\n") + stream.write (" if (" + prefix + varName + "Max < val)\n") + stream.write (" " + prefix + varName + "Max = val;\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + if self.style != "mma": + stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); + if not self.perThread: + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" return " + prefix + varName + ";\n") + stream.write (" }\n") + if optional: + stream.write (" inline void clr_" + varName + "() {\n") + stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + stream.write (" inline bool isSet_" + varName + "() {\n") + stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) + stream.write (" }\n") + elif self.accessor == "counter": + stream.write (" inline void inc_" + varName + " (" + self.asArg + " by = 1) {\n"); + if not self.perThread: + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " += by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "High < " + varName + ")\n") + stream.write (" " + varName + "High = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); + if not self.perThread: + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " -= by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "Low > " + varName + ")\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + + def genHiLoStatResets (self, stream, varName): + if self.style == "wm": + stream.write (" " + varName + "High = " + varName + ";\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if self.style == "mma": + stream.write (" " + varName + "Count = 0;\n") + stream.write (" " + varName + "Total = 0;\n") + stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + + def genPerThreadHiLoStatResets (self, stream, varName, cpptype): + if self.style == "mma": + stream.write (" threadStats->" + varName + "Count = 0;\n") + stream.write (" threadStats->" + varName + "Total = 0;\n") + stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") + stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") + + def genRead (self, stream, varName, indent=" "): + stream.write(indent + self.decode.replace("@", "buf").replace("#", varName) + ";\n") + + def genUnmap (self, stream, varName, indent=" ", key=None, mapName="_map", + _optional=False): + if key is None: + key = varName + stream.write(indent + "if ((_i = " + mapName + ".find(\"" + key + "\")) != " + mapName + ".end()) {\n") + stream.write(indent + " " + varName + " = " + + self.unmap.replace("#", "_i->second") + ";\n") + if _optional: + stream.write(indent + " _found = true;\n") + stream.write(indent + "}\n") + + def genWrite (self, stream, varName, indent=" "): + if self.style != "mma": + stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style == "wm": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "High") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Low") + ";\n") + if self.style == "mma": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Max") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Total / " + + varName + "Count : 0") + ";\n") + + def genMap (self, stream, varName, indent=" ", key=None, mapName="_map"): + if key is None: + key = varName + if self.style != "mma": + var_cast = self.map.replace("#", varName) + stream.write(indent + mapName + "[\"" + key + "\"] = ::qpid::types::Variant(" + var_cast + ");\n") + if self.style == "wm": + var_cast_hi = self.map.replace("#", varName + "High") + var_cast_lo = self.map.replace("#", varName + "Low") + stream.write(indent + mapName + "[\"" + key + "High\"] = " + + "::qpid::types::Variant(" + var_cast_hi + ");\n") + stream.write(indent + mapName + "[\"" + key + "Low\"] = " + + "::qpid::types::Variant(" + var_cast_lo + ");\n") + if self.style == "mma": + var_cast = self.map.replace("#", varName + "Count") + stream.write(indent + mapName + "[\"" + key + "Count\"] = " + "::qpid::types::Variant(" + var_cast + ");\n") + var_cast = self.map.replace("#", varName + "Min") + stream.write(indent + mapName + "[\"" + key + "Min\"] = " + + "(" + varName + "Count ? ::qpid::types::Variant(" + var_cast + ") : ::qpid::types::Variant(0));\n") + var_cast = self.map.replace("#", varName + "Max") + stream.write(indent + mapName + "[\"" + key + "Max\"] = " + "::qpid::types::Variant(" + var_cast + ");\n") + + var_cast = self.map.replace("#", "(" + varName + "Total / " + varName + "Count)") + stream.write(indent + mapName + "[\"" + key + "Avg\"] = " + + "(" + varName + "Count ? ::qpid::types::Variant(" + var_cast + ") : ::qpid::types::Variant(0));\n") + + def getReadCode (self, varName, bufName): + result = self.decode.replace ("@", bufName).replace ("#", varName) + return result + + def getWriteCode (self, varName, bufName): + result = self.encode.replace ("@", bufName).replace ("#", varName) + return result + +#===================================================================================== +# +#===================================================================================== +class TypeSpec: + def __init__ (self, file): + self.types = {} + dom = parse (file) + document = dom.documentElement + if document.tagName != 'schema-types': + raise ValueError ("Expected 'schema-types' in type file") + + for child in document.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'type': + stype = SchemaType (child) + self.types[stype.getName ()] = stype + else: + raise ValueError ("Unknown type tag '%s'" % child.nodeName) + + def getType (self, name): + return self.types[name] + + +#===================================================================================== +# +#===================================================================================== +class Type: + def __init__ (self, name, typespec): + self.type = typespec.getType (name) + +#===================================================================================== +# +#===================================================================================== +class SchemaProperty: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.ref = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.isGeneralRef = 0 + self.isOptional = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + if self.type.type.accessor != 'direct': + raise ValueError ("Class properties must have a type with a direct accessor") + + elif key == 'references': + self.ref = val + + elif key == 'access': + self.access = val + + elif key == 'index': + if val != 'y': + raise ValueError ("Expected 'y' in index attribute") + self.isIndex = 1 + + elif key == 'parentRef': + if val != 'y': + raise ValueError ("Expected 'y' in parentRef attribute") + self.isParentRef = 1 + + elif key == 'isGeneralReference': + if val != 'y': + raise ValueError ("Expected 'y' in isGeneralReference attribute") + self.isGeneralRef = 1 + + elif key == 'optional': + if val != 'y': + raise ValueError ("Expected 'y' in optional attribute") + self.isOptional = 1 + + elif key == 'unit': + self.unit = val + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in property '%s'" % key) + + if self.access == "RC" and self.isOptional == 1: + raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in property") + if self.type == None: + raise ValueError ("Missing 'type' attribute in property") + + def getName (self): + return self.name + + def isConstructorArg (self): + if self.access == "RC" and self.isParentRef == 0: + return 1 + return 0 + + def genDeclaration (self, stream, prefix=" "): + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + + def genFormalParam (self, stream, variables): + stream.write (self.type.type.asArg + " _" + self.name) + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) + + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + stream.write (indent + prefix + self.name + " = " + val + ";\n") + + def genSchema (self, stream): + stream.write (" ft.clear();\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") + stream.write (" ft[ACCESS] = ACCESS_" + self.access + ";\n") + stream.write (" ft[IS_INDEX] = " + str (self.isIndex) + ";\n") + stream.write (" ft[IS_OPTIONAL] = " + str (self.isOptional) + ";\n") + if self.unit != None: + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") + if self.min != None: + stream.write (" ft[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" ft[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" ft[MAXLEN] = " + self.maxLen + ";\n") + if self.desc != None: + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") + + + def genSchemaMap(self, stream): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" _value[TYPE] = TYPE_" + self.type.type.base +";\n") + stream.write (" _value[ACCESS] = ACCESS_" + self.access + ";\n") + stream.write (" _value[IS_INDEX] = " + str (self.isIndex) + ";\n") + stream.write (" _value[IS_OPTIONAL] = " + str (self.isOptional) + ";\n") + if self.unit != None: + stream.write (" _value[UNIT] = \"" + self.unit + "\";\n") + if self.min != None: + stream.write (" _value[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" _value[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" _value[MAXLEN] = " + self.maxLen + ";\n") + if self.desc != None: + stream.write (" _value[DESC] = \"" + self.desc + "\";\n") + stream.write (" _props[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + + + + def genSize (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + stream.write("%ssize += %s; // %s\n" % (indent, self.type.type.size.replace("#", self.name), self.name)) + if self.isOptional: + stream.write(" }\n") + + def genRead (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genRead (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + def genWrite (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genWrite (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + def genUnmap (self, stream): + indent = " " + if self.isOptional: + stream.write(" _found = false;\n") + self.type.type.genUnmap (stream, self.name, indent, _optional=self.isOptional) + if self.isOptional: + stream.write(" if (_found) {\n") + stream.write(" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % + (self.name, self.name)) + stream.write(" }\n") + + def genMap (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genMap (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + + def __repr__(self): + m = {} + m["name"] = self.name + m["type"] = self.type + m["ref"] = self.ref + m["access"] = self.access + m["isIndex"] = self.isIndex + m["isParentRef"] = self.isParentRef + m["isGeneralRef"] = self.isGeneralRef + m["isOptional"] = self.isOptional + m["unit"] = self.unit + m["min"] = self.min + m["max"] = self.max + m["maxLen"] = self.maxLen + m["desc"] = self.desc + return str(m) + +#===================================================================================== +# +#===================================================================================== +class SchemaStatistic: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.desc = None + self.assign = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'desc': + self.desc = val + + elif key == 'assign': + self.assign = val + + else: + raise ValueError ("Unknown attribute in statistic '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in statistic") + if self.type == None: + raise ValueError ("Missing 'type' attribute in statistic") + + def getName (self): + return self.name + + def genDeclaration (self, stream, prefix=" "): + if self.type.type.style != "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style == 'wm': + stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") + if self.type.type.style == "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") + stream.write (prefix + "uint64_t " + self.name + "Total;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "instChanged") + + def genHiLoStatResets (self, stream): + self.type.type.genHiLoStatResets (stream, self.name) + + def genPerThreadHiLoStatResets (self, stream): + self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) + + def genSchemaText (self, stream, name, desc): + stream.write (" ft.clear();\n") + stream.write (" ft[NAME] = \"" + name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") + if self.unit != None: + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") + if desc != None: + stream.write (" ft[DESC] = \"" + desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") + + def genSchemaTextMap(self, stream, name, desc): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" _value[TYPE] = TYPE_" + self.type.type.base +";\n") + if self.unit != None: + stream.write (" _value[UNIT] = \"" + self.unit + "\";\n") + if desc != None: + stream.write (" _value[DESC] = \"" + desc + "\";\n") + stream.write (" _stats[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + + def genSchema (self, stream): + if self.type.type.style != "mma": + self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaText (stream, self.name + "High", descHigh) + self.genSchemaText (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaText (stream, self.name + "Samples", descCount) + self.genSchemaText (stream, self.name + "Min", descMin) + self.genSchemaText (stream, self.name + "Max", descMax) + self.genSchemaText (stream, self.name + "Average", descAverage) + + def genSchemaMap (self, stream): + if self.type.type.style != "mma": + self.genSchemaTextMap (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaTextMap (stream, self.name + "High", descHigh) + self.genSchemaTextMap (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaTextMap (stream, self.name + "Samples", descCount) + self.genSchemaTextMap (stream, self.name + "Min", descMin) + self.genSchemaTextMap (stream, self.name + "Max", descMax) + self.genSchemaTextMap (stream, self.name + "Average", descAverage) + + def genAssign (self, stream): + if self.assign != None: + if self.type.type.perThread: + prefix = " threadStats->" + else: + prefix = "" + stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + + ") (" + self.assign + ");\n") + + def genWrite (self, stream): + if self.type.type.perThread: + self.type.type.genWrite (stream, "totals." + self.name) + else: + self.type.type.genWrite (stream, self.name) + + def genMap (self, stream): + if self.type.type.perThread: + self.type.type.genMap(stream, "totals." + self.name, key=self.name) + else: + self.type.type.genMap(stream, self.name) + + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + if self.type.type.style != "mma": + stream.write (indent + prefix + self.name + " = " + val + ";\n") + if self.type.type.style == "wm": + stream.write (indent + prefix + self.name + "High = " + val + ";\n") + stream.write (indent + prefix + self.name + "Low = " + val + ";\n") + if self.type.type.style == "mma": + stream.write (indent + prefix + self.name + "Count = 0;\n") + stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (indent + prefix + self.name + "Total = 0;\n") + + def genInitializeTotalPerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->" + self.name + "Count = 0;\n") + stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (" totals->" + self.name + "Total = 0;\n") + else: + stream.write (" totals->" + self.name + " = 0;\n") + + def genAggregatePerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) + stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) + stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) + stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) + else: + stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaArg: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.dir = "I" + self.min = None + self.max = None + self.maxLen = None + self.desc = None + self.default = None + self.hash = Hash(node) + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'dir': + self.dir = val.upper () + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + elif key == 'default': + self.default = val + + else: + raise ValueError ("Unknown attribute in arg '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in arg") + if self.type == None: + raise ValueError ("Missing 'type' attribute in arg") + + def getName (self): + return self.name + + def getDir (self): + return self.dir + + def genSchema (self, stream, event=False): + stream.write (" ft.clear();\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") + if (not event): + stream.write (" ft[DIR] = \"" + self.dir + "\";\n") + if self.unit != None: + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") + if not event: + if self.min != None: + stream.write (" ft[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" ft[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" ft[MAXLEN] = " + self.maxLen + ";\n") + if self.default != None: + stream.write (" ft[DEFAULT] = \"" + self.default + "\";\n") + if self.desc != None: + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") + + def genSchemaMap (self, stream, event=False): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _avalue;\n") + stream.write (" _avalue[TYPE] = TYPE_" + self.type.type.base +";\n") + if (not event): + stream.write (" _avalue[DIR] = \"" + self.dir + "\";\n") + if self.unit != None: + stream.write (" _avalue[UNIT] = \"" + self.unit + "\";\n") + if not event: + if self.min != None: + stream.write (" _avalue[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" _avalue[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" _avalue[MAXLEN] = " + self.maxLen + ";\n") + if self.default != None: + stream.write (" _avalue[DEFAULT] = \"" + self.default + "\";\n") + if self.desc != None: + stream.write (" _avalue[DESC] = \"" + self.desc + "\";\n") + stream.write (" _args[\"" + self.name + "\"] = _avalue;\n") + stream.write (" }\n") + + + + def genFormalParam (self, stream, variables): + stream.write ("%s _%s" % (self.type.type.asArg, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaMethod: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in method '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown method tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ + self.name[1:] + + def getArgCount (self): + return len (self.args) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genNameUpper (self, stream, variables): + stream.write (self.getFullName ().upper ()) + + def genNameCamel (self, stream, variables): + stream.write (self.getFullName ()) + + def genOpenNamespaces (self, stream, variables): + self.parent.genOpenNamespaces(stream, variables) + + def genCloseNamespaces (self, stream, variables): + self.parent.genCloseNamespaces(stream, variables) + + def genArguments (self, stream, variables): + for arg in self.args: + ctype = arg.type.type.cpp + dirTag = arg.dir.lower() + "_" + stream.write (" " + ctype + " " + dirTag + arg.getName () + ";\n") + + def genNamePackageLower (self, stream, variables): + self.parent.genNamePackageLower(stream, variables) + + def genSchema (self, stream, variables): + stream.write (" ft.clear();\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[ARGCOUNT] = " + str (len (self.args)) + ";\n") + if self.desc != None: + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") + for arg in self.args: + arg.genSchema (stream) + + def genSchemaMap (self, stream, variables): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" ::qpid::types::Variant::Map _args;\n") + stream.write (" _value[ARGCOUNT] = " + str(len(self.args)) + ";\n") + if self.desc != None: + stream.write (" _value[DESC] = \"" + self.desc + "\";\n") + + for arg in self.args: + arg.genSchemaMap (stream) + + stream.write (" if (!_args.empty())\n") + stream.write (" _value[ARGS] = _args;\n") + + + stream.write (" _methods[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + +#===================================================================================== +# +#===================================================================================== +class SchemaEvent: + def __init__ (self, package, node, typespec, argset): + self.packageName = package + self.name = None + self.desc = None + self.sevText = "inform" + self.args = [] + self.hash = Hash(node) + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + elif key == 'sev': + self.sevText = val + + elif key == 'args': + list = val.replace(" ", "").split(",") + for item in list: + if item not in argset.args: + raise Exception("undefined argument '%s' in event" % item) + self.args.append(argset.args[item]) + self.hash.addSubHash(argset.args[item].hash) + + else: + raise ValueError ("Unknown attribute in event '%s'" % key) + + if self.sevText == "emerg" : self.sev = 0 + elif self.sevText == "alert" : self.sev = 1 + elif self.sevText == "crit" : self.sev = 2 + elif self.sevText == "error" : self.sev = 3 + elif self.sevText == "warn" : self.sev = 4 + elif self.sevText == "notice" : self.sev = 5 + elif self.sevText == "inform" : self.sev = 6 + elif self.sevText == "debug" : self.sev = 7 + else: + raise ValueError("Unknown severity '%s' in event '%s'" % (self.sevText, self.name)) + + def getName (self): + return self.name + + def getNameCap(self): + return capitalize(self.name) + + def getFullName (self): + return capitalize(self.package + capitalize(self.name)) + + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + + def getArgCount (self): + return len (self.args) + + def genArgCount (self, stream, variables): + stream.write("%d" % len(self.args)) + + def genArgDeclarations(self, stream, variables): + for arg in self.args: + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write(" const %s%s %s;\n" % (arg.type.type.cpp, ref, arg.name)) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genConstructorArgs(self, stream, variables): + pre = "" + for arg in self.args: + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write("%sconst %s%s _%s" % (pre, arg.type.type.cpp, ref, arg.name)) + pre = ",\n " + + def genConstructorInits(self, stream, variables): + pre = "" + for arg in self.args: + stream.write("%s%s(_%s)" % (pre, arg.name, arg.name)) + pre = ",\n " + + def genName(self, stream, variables): + stream.write(self.name) + + def genNameCap(self, stream, variables): + stream.write(capitalize(self.name)) + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genNameLower(self, stream, variables): + stream.write(self.name.lower()) + + def genNameUpper(self, stream, variables): + stream.write(self.name.upper()) + + def genNamePackageLower(self, stream, variables): + stream.write(self.packageName.lower()) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genSeverity(self, stream, variables): + stream.write("%d" % self.sev) + + def genArgEncodes(self, stream, variables): + for arg in self.args: + stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + + def genArgMap(self, stream, variables): + for arg in self.args: + arg.type.type.genMap(stream, arg.name, " ", mapName="map") + #stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + + + def genArgSchema(self, stream, variables): + for arg in self.args: + arg.genSchema(stream, True) + + def genArgSchemaMap(self, stream, variables): + for arg in self.args: + arg.genSchemaMap(stream, True) + + def genSchemaMD5(self, stream, variables): + sum = self.hash.getDigest() + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + + +class SchemaClass: + def __init__ (self, package, node, typespec, fragments, options): + self.packageName = package + self.properties = [] + self.statistics = [] + self.methods = [] + self.events = [] + self.options = options + self.hash = Hash(node) + + attrs = node.attributes + self.name = makeValidCppSymbol(attrs['name'].nodeValue) + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'property': + sub = SchemaProperty (child, typespec) + self.properties.append (sub) + + elif child.nodeName == 'statistic': + sub = SchemaStatistic (child, typespec) + self.statistics.append (sub) + + elif child.nodeName == 'method': + sub = SchemaMethod (self, child, typespec) + self.methods.append (sub) + + elif child.nodeName == 'group': + self.expandFragment (child, fragments) + + else: + raise ValueError ("Unknown class tag '%s'" % child.nodeName) + + # Adjust the 'assign' attributes for each statistic + for stat in self.statistics: + if stat.assign != None and stat.type.type.perThread: + stat.assign = self.adjust (stat.assign, self.statistics) + + def adjust (self, text, statistics): + result = text + start = 0 + while True: + next = None + for stat in statistics: + pos = result.find (stat.name, start) + if pos != -1 and (next == None or pos < next[0]): + next = (pos, stat.name) + if next == None: + return result + pos = next[0] + result = result[0:pos] + "threadStats->" + result[pos:] + start = pos + 9 + len(next[1]) + + def expandFragment (self, node, fragments): + attrs = node.attributes + name = attrs['name'].nodeValue + for fragment in fragments: + if fragment.name == name: + self.hash.addSubHash(fragment.hash) + for config in fragment.properties: + self.properties.append (config) + for inst in fragment.statistics: + self.statistics.append (inst) + for method in fragment.methods: + self.methods.append (method) + for event in fragment.events: + self.events.append (event) + return + raise ValueError ("Undefined group '%s'" % name) + + def getName (self): + return self.name + + def getNameCap (self): + return capitalize(self.name) + + def getMethods (self): + return self.methods + + def getEvents (self): + return self.events + + def getPackageNameCap (self): + return capitalize(self.packageName) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def testExistOptionals (self, variables): + for prop in self.properties: + if prop.isOptional == 1: + return True + return False + + def testExistPerThreadStats (self, variables): + for inst in self.statistics: + if inst.type.type.perThread: + return True + return False + + def testExistPerThreadAssign (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.assign != None: + return True + return False + + def testExistPerThreadResets (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.type.type.style == "mma": + return True + return False + + def testNoStatistics (self, variables): + return len (self.statistics) == 0 + + def genAccessorMethods (self, stream, variables): + for config in self.properties: + if config.access != "RC": + config.genAccessor (stream) + for inst in self.statistics: + if inst.assign == None: + inst.genAccessor (stream) + + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genConfigCount (self, stream, variables): + stream.write ("%d" % len (self.properties)) + + def genConfigDeclarations (self, stream, variables): + for element in self.properties: + element.genDeclaration (stream) + + def genConstructorArgs (self, stream, variables): + # Constructor args are config elements with read-create access + result = "" + for element in self.properties: + if element.isConstructorArg (): + stream.write (", ") + element.genFormalParam (stream, variables) + + def genConstructorInits (self, stream, variables): + for element in self.properties: + if element.isConstructorArg (): + stream.write ("," + element.getName () + "(_" + element.getName () + ")") + + def genDoMethodArgs (self, stream, variables): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string&, const string&, string& outStr, const string&") + else: + if inArgCount == 0: + stream.write ("string& methodName, const string&, string& outStr, const string& userId") + else: + stream.write ("string& methodName, const string& inStr, string& outStr, const string& userId") + + + def genDoMapMethodArgs (self, stream, variables): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string&," + + " const ::qpid::types::Variant::Map&," + + " ::qpid::types::Variant::Map& outMap, const string&") + else: + if inArgCount == 0: + stream.write ("string& methodName," + + " const ::qpid::types::Variant::Map&," + + " ::qpid::types::Variant::Map& outMap, const string& userId") + else: + stream.write ("string& methodName," + + " const ::qpid::types::Variant::Map& inMap," + + " ::qpid::types::Variant::Map& outMap, const string& userId") + + def genHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genHiLoStatResets (stream) + + def genPerThreadHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genPerThreadHiLoStatResets (stream) + + def genInitializeElements (self, stream, variables): + for prop in self.properties: + if not prop.isConstructorArg() and not prop.isParentRef: + prop.genInitialize(stream) + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genInitialize (stream) + + def genInitializePerThreadElements (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitialize (stream, "threadStats->", " ") + + def genInitializeTotalPerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitializeTotalPerThreadStats (stream) + + def genAggregatePerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAggregatePerThreadStats (stream) + + def genInstCount (self, stream, variables): + count = 0 + for inst in self.statistics: + count = count + 1 + if inst.type.type.style == "wm": + count = count + 2 + if inst.type.type.style == "mma": + count = count + 3 + stream.write ("%d" % count) + + def genInstDeclarations (self, stream, variables): + for element in self.statistics: + if not element.type.type.perThread: + element.genDeclaration (stream) + + def genPerThreadDeclarations (self, stream, variables): + for element in self.statistics: + if element.type.type.perThread: + element.genDeclaration (stream, " ") + + def genPrimaryKey (self, stream, variables): + first = 1 + for prop in self.properties: + # deliberately leave out the "vhostRef" fields since there's only one vhost, + # this serves to shorten the keys without compromising uniqueness + if prop.getName() != "vhostRef": + if prop.isIndex == 1: + if first: + first = None + else: + stream.write(" << \",\";\n") + var = prop.type.type.stream.replace("#", prop.getName()) + stream.write(" key << %s" % var) + if not first: + stream.write(";") + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genMethodArgIncludes (self, stream, variables): + for method in self.methods: + if method.getArgCount () > 0: + stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") + + def genMethodCount (self, stream, variables): + stream.write ("%d" % len (self.methods)) + + def genMethodHandlers (self, stream, variables): + inArgs = False + for method in self.methods: + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgs = True; + break + + if inArgs: + stream.write("\n") + stream.write(" char *_tmpBuf = new char[inStr.length()];\n") + stream.write(" memcpy(_tmpBuf, inStr.data(), inStr.length());\n") + stream.write(" ::qpid::management::Buffer inBuf(_tmpBuf, inStr.length());\n") + + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + stream.write (" _matched = true;\n") + if method.getArgCount () == 0: + stream.write (" ::qpid::management::ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getReadCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "inBuf") + ";\n") + + stream.write (" bool allow = coreObject->AuthorizeMethod(METHOD_" +\ + method.getName().upper() + ", ioArgs, userId);\n") + stream.write (" if (allow)\n") + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs, text);\n") + stream.write (" else\n") + stream.write (" status = Manageable::STATUS_FORBIDDEN;\n") + stream.write (" outBuf.putLong (status);\n") + stream.write (" outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getWriteCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "outBuf") + ";\n") + stream.write(" }\n") + + if inArgs: + stream.write ("\n delete [] _tmpBuf;\n") + + + + def genMapMethodHandlers (self, stream, variables): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + if method.getArgCount () == 0: + stream.write (" ::qpid::management::ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + stream.write (" ::qpid::types::Variant::Map::const_iterator _i;\n") + + # decode each input argument from the input map + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + arg.type.type.genUnmap(stream, + "ioArgs." + arg.dir.lower () + "_" + arg.name, + " ", + arg.name, + "inMap") + + stream.write (" bool allow = coreObject->AuthorizeMethod(METHOD_" +\ + method.getName().upper() + ", ioArgs, userId);\n") + stream.write (" if (allow)\n") + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs, text);\n") + stream.write (" else\n") + stream.write (" status = Manageable::STATUS_FORBIDDEN;\n") + stream.write (" outMap[\"_status_code\"] = (uint32_t) status;\n") + stream.write (" outMap[\"_status_text\"] = ::qpid::management::Manageable::StatusText(status, text);\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + arg.type.type.genMap(stream, + "ioArgs." + arg.dir.lower () + "_" + arg.name, + " ", + arg.name, + "outMap") + stream.write (" return;\n }\n") + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genPresenceMaskBytes (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + count += 1 + if count == 0: + stream.write("0") + else: + stream.write (str(((count - 1) / 8) + 1)) + + def genPresenceMaskConstants (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) + stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) + count += 1 + + def genPropertySchema (self, stream, variables): + for prop in self.properties: + prop.genSchema (stream) + + def genPropertySchemaMap (self, stream, variables): + for prop in self.properties: + prop.genSchemaMap(stream) + + def genSetGeneralReferenceDeclaration (self, stream, variables): + for prop in self.properties: + if prop.isGeneralRef: + stream.write ("void setReference(::qpid::management::ObjectId objectId) { " + prop.name + " = objectId; }\n") + + def genStatisticSchema (self, stream, variables): + for stat in self.statistics: + stat.genSchema (stream) + + def genStatisticSchemaMap (self, stream, variables): + for stat in self.statistics: + stat.genSchemaMap(stream) + + def genMethodIdDeclarations (self, stream, variables): + number = 1 + for method in self.methods: + stream.write (" static const uint32_t METHOD_" + method.getName().upper() +\ + " = %d;\n" % number) + number = number + 1 + + def genMethodSchema (self, stream, variables): + for method in self.methods: + method.genSchema (stream, variables) + + def genMethodSchemaMap(self, stream, variables): + for method in self.methods: + method.genSchemaMap(stream, variables) + + def genName (self, stream, variables): + stream.write (self.name) + + def genNameCap (self, stream, variables): + stream.write (capitalize(self.name)) + + def genNameLower (self, stream, variables): + stream.write (self.name.lower ()) + + def genNamePackageCap (self, stream, variables): + stream.write (self.getPackageNameCap ()) + + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + + def genNameUpper (self, stream, variables): + stream.write (self.name.upper ()) + + def genParentArg (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (", ::qpid::management::Manageable* _parent") + return + + def genParentRefAssignment (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (config.getName () + \ + " = _parent->GetManagementObject ()->getObjectId ();") + return + + def genSchemaMD5 (self, stream, variables): + sum = self.hash.getDigest() + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + + def genAssign (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genAssign (stream) + + def genPerThreadAssign (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAssign (stream) + + def genSizeProperties (self, stream, variables): + for prop in self.properties: + prop.genSize (stream) + + def genReadProperties (self, stream, variables): + for prop in self.properties: + prop.genRead (stream) + + def genWriteProperties (self, stream, variables): + for prop in self.properties: + prop.genWrite (stream) + + def genWriteStatistics (self, stream, variables): + for stat in self.statistics: + stat.genWrite (stream) + + def genMapEncodeProperties(self, stream, variables): + for prop in self.properties: + prop.genMap (stream) + + def genMapEncodeStatistics (self, stream, variables): + for stat in self.statistics: + stat.genMap (stream) + + def genMapDecodeProperties (self, stream, variables): + for prop in self.properties: + prop.genUnmap (stream) + +class SchemaEventArgs: + def __init__(self, package, node, typespec, fragments, options): + self.packageName = package + self.options = options + self.args = {} + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg(child, typespec) + self.args[arg.name] = arg + else: + raise Exception("Unknown tag '%s' in <eventArguments>" % child.nodeName) + +class SchemaPackage: + def __init__ (self, typefile, schemafile, options): + + self.classes = [] + self.fragments = [] + self.typespec = TypeSpec (typefile) + self.eventArgSet = None + self.events = [] + + dom = parse (schemafile) + document = dom.documentElement + if document.tagName != 'schema': + raise ValueError ("Expected 'schema' node") + attrs = document.attributes + pname = attrs['package'].nodeValue + namelist = pname.split('.') + self.packageName = ".".join(namelist) + + children = document.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'class': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.classes.append (cls) + + elif child.nodeName == 'group': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.fragments.append (cls) + + elif child.nodeName == 'eventArguments': + if self.eventArgSet: + raise Exception("Only one <eventArguments> may appear in a package") + self.eventArgSet = SchemaEventArgs(self.packageName, child, self.typespec, self.fragments, options) + + elif child.nodeName == 'event': + event = SchemaEvent(self.packageName, child, self.typespec, self.eventArgSet) + self.events.append(event) + + else: + raise ValueError ("Unknown schema tag '%s'" % child.nodeName) + + def getPackageName (self): + return self.packageName + + def getPackageNameCap (self): + return capitalize(self.packageName) + + def getPackageNameLower (self): + return self.packageName.lower() + + def getClasses (self): + return self.classes + + def getEvents(self): + return self.events + + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genPackageNameUpper (self, stream, variables): + up = "_".join(self.packageName.split(".")) + stream.write (up.upper()) + + def genPackageName (self, stream, variables): + stream.write(self.packageName) + + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + + def genClassIncludes (self, stream, variables): + for _class in self.classes: + stream.write ("#include \"") + _class.genNameCap (stream, variables) + stream.write (".h\"\n") + for _event in self.events: + stream.write ("#include \"Event") + _event.genNameCap(stream, variables) + stream.write (".h\"\n") + + def genClassRegisters(self, stream, variables): + for _class in self.classes: + stream.write(" ") + _class.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") + for _event in self.events: + stream.write(" Event") + _event.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") + + def genV2ClassMembers(self, stream, variables): + for _class in self.classes: + stream.write(" ::qmf::Schema data_%s;\n" % _class.name) + for _event in self.events: + stream.write(" ::qmf::Schema event_%s;\n" % _event.name) + + def genV2ClassDefines(self, stream, variables): + for _class in self.classes: + stream.write("\n //\n // Data: %s\n //\n" % _class.name) + stream.write(" data_%s = qmf::Schema(SCHEMA_TYPE_DATA, package, \"%s\");\n" % (_class.name, _class.name)) + + for prop in _class.properties: + typeName, subType = self.qmfv2Type(prop.type) + access = self.qmfv2Access(prop.access) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (prop.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + stream.write(" prop.setAccess(%s);\n" % access) + if prop.isIndex == 1: + stream.write(" prop.setIndex(true);\n") + if prop.isOptional == 1: + stream.write(" prop.setOptional(true);\n") + if prop.unit: + stream.write(" prop.setUnit(\"%s\");\n" % prop.unit) + if prop.desc: + stream.write(" prop.setDesc(\"%s\");\n" % prop.desc) + stream.write(" data_%s.addProperty(prop);\n" % _class.name) + stream.write(" }\n\n") + + for stat in _class.statistics: + typeName, subType = self.qmfv2Type(stat.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (stat.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + if stat.unit: + stream.write(" prop.setUnit(\"%s\");\n" % stat.unit) + if stat.desc: + stream.write(" prop.setDesc(\"%s\");\n" % stat.desc) + stream.write(" data_%s.addProperty(prop);\n" % _class.name) + stream.write(" }\n\n") + + for method in _class.methods: + stream.write(" {\n") + stream.write(" qmf::SchemaMethod method(\"%s\");\n" % method.name) + if method.desc: + stream.write(" method.setDesc(\"%s\");\n" % method.desc) + + for arg in method.args: + typeName, subType = self.qmfv2Type(arg.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty arg(\"%s\", %s);\n" % (arg.name, typeName)) + if subType: + stream.write(" arg.setSubtype(\"%s\");\n" % subType) + if arg.unit: + stream.write(" arg.setUnit(\"%s\");\n" % arg.unit) + if arg.desc: + stream.write(" arg.setDesc(\"%s\");\n" % arg.desc) + stream.write(" arg.setDirection(%s);\n" % self.qmfv2Dir(arg.dir)) + stream.write(" method.addArgument(arg);\n") + stream.write(" }\n\n") + + stream.write(" data_%s.addMethod(method);\n" % _class.name) + stream.write(" }\n\n") + + stream.write(" session.registerSchema(data_%s);\n" % _class.name) + + for _event in self.events: + stream.write("\n //\n // Event: %s\n //\n" % _event.name) + stream.write(" event_%s = qmf::Schema(SCHEMA_TYPE_EVENT, package, \"%s\");\n" % (_event.name, _event.name)) + stream.write(" event_%s.setDefaultSeverity(%s);\n" % (_event.name, self.qmfv2Severity(_event.sev))) + for prop in _event.args: + typeName, subType = self.qmfv2Type(prop.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (prop.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + if prop.unit: + stream.write(" prop.setUnit(\"%s\");\n" % prop.unit) + if prop.desc: + stream.write(" prop.setDesc(\"%s\");\n" % prop.desc) + stream.write(" event_%s.addProperty(prop);\n" % _event.name) + stream.write(" }\n\n") + + stream.write(" session.registerSchema(event_%s);\n" % _event.name) + + + def qmfv2Type(self, typecode): + base = typecode.type.base + if base == "REF" : return ("qmf::SCHEMA_DATA_MAP", "reference") + if base == "U8" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U16" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U32" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U64" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S8" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S16" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S32" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S64" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "BOOL" : return ("qmf::SCHEMA_DATA_BOOL", None) + if base == "SSTR" : return ("qmf::SCHEMA_DATA_STRING", None) + if base == "LSTR" : return ("qmf::SCHEMA_DATA_STRING", None) + if base == "ABSTIME" : return ("qmf::SCHEMA_DATA_INT", "abstime") + if base == "DELTATIME" : return ("qmf::SCHEMA_DATA_INT", "deltatime") + if base == "FLOAT" : return ("qmf::SCHEMA_DATA_FLOAT", None) + if base == "DOUBLE" : return ("qmf::SCHEMA_DATA_FLOAT", None) + if base == "UUID" : return ("qmf::SCHEMA_DATA_UUID", None) + if base == "FTABLE" : return ("qmf::SCHEMA_DATA_MAP", None) + if base == "LIST" : return ("qmf::SCHEMA_DATA_LIST", None) + raise ValueError("Unknown base type %s" % base) + + def qmfv2Access(self, code): + if code == "RC": return "qmf::ACCESS_READ_CREATE" + if code == "RO": return "qmf::ACCESS_READ_ONLY" + if code == "RW": return "qmf::ACCESS_READ_WRITE" + raise ValueError("Unknown access type %s" % code) + + def qmfv2Dir(self, code): + if code == "I" : return "qmf::DIR_IN" + if code == "O" : return "qmf::DIR_OUT" + if code == "IO": return "qmf::DIR_IN_OUT" + raise ValueError("Unknown direction type %s" % code) + + def qmfv2Severity(self, code): + if code == 0 : return "qmf::SEV_EMERG" + if code == 1 : return "qmf::SEV_ALERT" + if code == 2 : return "qmf::SEV_CRIT" + if code == 3 : return "qmf::SEV_ERROR" + if code == 4 : return "qmf::SEV_WARN" + if code == 5 : return "qmf::SEV_NOTICE" + if code == 6 : return "qmf::SEV_INFORM" + if code == 7 : return "qmf::SEV_DEBUG" + raise ValueError("Out of Range Severity %d" % code) + +#===================================================================================== +# Utility Functions +#===================================================================================== + +# Create a valid C++ symbol from the input string so that it can be +# used in generated C++ source. For instance, change "qpid.mgmt" to +# "qpidMgmt". +# +# Input: Raw string (str) to process +# Output: String (str) suitable for use as a C++ symbol +# +# Limitations: Currently, only strips periods ('.') from strings, +# eventually should strip :'s and ,'s and ''s, oh my! +def makeValidCppSymbol(input): + output = str() + capitalize = False + + for char in input: + skip = False + + if char == ".": + capitalize = True + skip = True + + if not skip: + output += capitalize and char.upper() or char + + capitalize = False + + return output + +# Capitalize a string by /only/ forcing the first character to be +# uppercase. The rest of the string is left alone. This is different +# from str.capitalize(), which forces the first character to uppercase +# and the rest to lowercase. +# +# Input: A string (str) to capitalize +# Output: A string (str) with the first character as uppercase +def capitalize(input): + return input[0].upper() + input[1:] diff --git a/qpid/cpp/managementgen/qmfgen/templates/Args.h b/qpid/cpp/managementgen/qmfgen/templates/Args.h new file mode 100644 index 0000000000..89a5bec9b9 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Args.h @@ -0,0 +1,40 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ +#define _ARGS_/*MGEN:Method.NameUpper*/_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Args.h" +#include <string> + +namespace qmf { +/*MGEN:Method.OpenNamespaces*/ + + class Args/*MGEN:Method.NameCamel*/ : public ::qpid::management::Args +{ + public: +/*MGEN:Method.Arguments*/ +}; + +}/*MGEN:Method.CloseNamespaces*/ + +#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake new file mode 100644 index 0000000000..d8a3b91b10 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake @@ -0,0 +1,39 @@ +#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+/*MGEN:commentPrefix=#*/
+/*MGEN:Root.Disclaimer*/
+/*MGEN:IF(CMakeLists.QpidBroker)*/
+/*MGEN:mgenDir=${mgen_dir}*/
+/*MGEN:specDir=${qpid-cpp_SOURCE_DIR}/../specs*/
+
+set(mgen_generator /*MGEN:CMakeLists.GenSources*/)
+
+set(mgen_broker_cpp /*MGEN:CMakeLists.GenCppFiles*/)
+
+# Header file install rules.
+#/*MGEN:CMakeLists.HeaderInstalls*/
+#if GENERATE
+#$(srcdir)/managementgen.mk: $(mgen_generator)
+# $(mgen_cmd)
+#
+#$(mgen_generator):
+#endif
+#/*MGEN:ENDIF*/
+
+set(qmfgen_sources /*MGEN:CMakeLists.GeneratedFiles*/)
diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp new file mode 100644 index 0000000000..fc0b9c8177 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -0,0 +1,339 @@ +/*MGEN:commentPrefix=//*/ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Manageable.h" +#include "qpid/management/Buffer.h" +#include "qpid/types/Variant.h" +#include "qpid/amqp_0_10/Codecs.h" +#include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" +#include "/*MGEN:Class.NameCap*/.h" +/*MGEN:Class.MethodArgIncludes*/ +#include <iostream> +#include <sstream> + +using namespace qmf::/*MGEN:Class.Namespace*/; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; +using qpid::management::Mutex; +using std::string; + +string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); +string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); +uint8_t /*MGEN:Class.NameCap*/::md5Sum[MD5_LEN] = + {/*MGEN:Class.SchemaMD5*/}; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent*, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_core)/*MGEN:Class.ConstructorInits*/ +{ + /*MGEN:Class.ParentRefAssignment*/ +/*MGEN:Class.InitializeElements*/ +/*MGEN:IF(Class.ExistOptionals)*/ + // Optional properties start out not-present + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = 0; +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + perThreadStatsArray = new struct PerThreadStats*[maxThreads]; + for (int idx = 0; idx < maxThreads; idx++) + perThreadStatsArray[idx] = 0; +/*MGEN:ENDIF*/ +} + +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () +{ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + for (int idx = 0; idx < maxThreads; idx++) + if (perThreadStatsArray[idx] != 0) + delete perThreadStatsArray[idx]; + delete[] perThreadStatsArray; +/*MGEN:ENDIF*/ +} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string ACCESS("access"); + const string IS_INDEX("index"); + const string IS_OPTIONAL("optional"); + const string UNIT("unit"); + const string MIN("min"); + const string MAX("max"); + const string MAXLEN("maxlen"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); + const string DIR("dir"); + const string DEFAULT("default"); +} + +void /*MGEN:Class.NameCap*/::registerSelf(ManagementAgent* agent) +{ + agent->registerClass(packageName, className, md5Sum, writeSchema); +} + +void /*MGEN:Class.NameCap*/::writeSchema (std::string& schema) +{ + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + ::qpid::types::Variant::Map ft; + + // Schema class header: + buf.putOctet (CLASS_KIND_TABLE); + buf.putShortString (packageName); // Package Name + buf.putShortString (className); // Class Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count + buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count + buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count + + // Properties +/*MGEN:Class.PropertySchema*/ + // Statistics +/*MGEN:Class.StatisticSchema*/ + // Methods +/*MGEN:Class.MethodSchema*/ + { + uint32_t _len = buf.getPosition(); + buf.reset(); + buf.getRawData(schema, _len); + } +} + +/*MGEN:IF(Class.ExistPerThreadStats)*/ +void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) const +{ +/*MGEN:Class.InitializeTotalPerThreadStats*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.AggregatePerThreadStats*/ + } + } +} +/*MGEN:ENDIF*/ + +/*MGEN:IF(Root.GenQMFv1)*/ +uint32_t /*MGEN:Class.NameCap*/::writePropertiesSize() const +{ + uint32_t size = writeTimestampsSize(); +/*MGEN:IF(Class.ExistOptionals)*/ + size += /*MGEN:Class.PresenceMaskBytes*/; +/*MGEN:ENDIF*/ +/*MGEN:Class.SizeProperties*/ + return size; +} + +void /*MGEN:Class.NameCap*/::readProperties (const std::string& _sBuf) +{ + char *_tmpBuf = new char[_sBuf.length()]; + memcpy(_tmpBuf, _sBuf.data(), _sBuf.length()); + ::qpid::management::Buffer buf(_tmpBuf, _sBuf.length()); + Mutex::ScopedLock mutex(accessLock); + + { + std::string _tbuf; + buf.getRawData(_tbuf, writeTimestampsSize()); + readTimestamps(_tbuf); + } + +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = buf.getOctet(); +/*MGEN:ENDIF*/ +/*MGEN:Class.ReadProperties*/ + + delete [] _tmpBuf; +} + +void /*MGEN:Class.NameCap*/::writeProperties (std::string& _sBuf) const +{ + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + + Mutex::ScopedLock mutex(accessLock); + configChanged = false; + + { + std::string _tbuf; + writeTimestamps(_tbuf); + buf.putRawData(_tbuf); + } + + +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + buf.putOctet(presenceMask[idx]); +/*MGEN:ENDIF*/ +/*MGEN:Class.WriteProperties*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); +} + +void /*MGEN:Class.NameCap*/::writeStatistics (std::string& _sBuf, bool skipHeaders) +{ + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + + Mutex::ScopedLock mutex(accessLock); + instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ +/*MGEN:Class.Assign*/ + if (!skipHeaders) { + std::string _tbuf; + writeTimestamps (_tbuf); + buf.putRawData(_tbuf); + } + +/*MGEN:Class.WriteStatistics*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + std::string text; + + bool _matched = false; + + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer outBuf(_msgChars, _bufSize); + +/*MGEN:Class.MethodHandlers*/ + + if (!_matched) { + outBuf.putLong(status); + outBuf.putShortString(Manageable::StatusText(status, text)); + } + + uint32_t _bufLen = outBuf.getPosition(); + outBuf.reset(); + + outBuf.getRawData(outStr, _bufLen); +} +/*MGEN:ENDIF*/ +std::string /*MGEN:Class.NameCap*/::getKey() const +{ + std::stringstream key; + +/*MGEN:Class.PrimaryKey*/ + return key.str(); +} + + + +void /*MGEN:Class.NameCap*/::mapEncodeValues (::qpid::types::Variant::Map& _map, + bool includeProperties, + bool includeStatistics) +{ + using namespace ::qpid::types; + Mutex::ScopedLock mutex(accessLock); + + if (includeProperties) { + configChanged = false; +/*MGEN:Class.MapEncodeProperties*/ + } + + if (includeStatistics) { + instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ +/*MGEN:Class.Assign*/ + +/*MGEN:Class.MapEncodeStatistics*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ + } +} + +void /*MGEN:Class.NameCap*/::mapDecodeValues (const ::qpid::types::Variant::Map& _map) +{ + ::qpid::types::Variant::Map::const_iterator _i; + Mutex::ScopedLock mutex(accessLock); +/*MGEN:IF(Class.ExistOptionals)*/ + bool _found; +/*MGEN:ENDIF*/ +/*MGEN:Class.MapDecodeProperties*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMapMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + std::string text; + +/*MGEN:Class.MapMethodHandlers*/ + outMap["_status_code"] = (uint32_t) status; + outMap["_status_text"] = Manageable::StatusText(status, text); +} diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h new file mode 100644 index 0000000000..4bcd423a26 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -0,0 +1,122 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementObject.h" + +namespace qpid { + namespace management { + class ManagementAgent; + } +} + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject +{ + private: + + static std::string packageName; + static std::string className; + static uint8_t md5Sum[MD5_LEN]; +/*MGEN:IF(Class.ExistOptionals)*/ + uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; +/*MGEN:Class.PresenceMaskConstants*/ +/*MGEN:ENDIF*/ + + // Properties +/*MGEN:Class.ConfigDeclarations*/ + // Statistics +/*MGEN:Class.InstDeclarations*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + // Per-Thread Statistics + struct PerThreadStats { +/*MGEN:Class.PerThreadDeclarations*/ + }; + + struct PerThreadStats** perThreadStatsArray; + + inline struct PerThreadStats* getThreadStats() { + int idx = getThreadIndex(); + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats == 0) { + threadStats = new(PerThreadStats); + perThreadStatsArray[idx] = threadStats; +/*MGEN:Class.InitializePerThreadElements*/ + } + return threadStats; + } + + void aggregatePerThreadStats(struct PerThreadStats*) const; +/*MGEN:ENDIF*/ + public: + static void writeSchema(std::string& schema); + void mapEncodeValues(::qpid::types::Variant::Map& map, + bool includeProperties=true, + bool includeStatistics=true); + void mapDecodeValues(const ::qpid::types::Variant::Map& map); + void doMethod(std::string& methodName, + const ::qpid::types::Variant::Map& inMap, + ::qpid::types::Variant::Map& outMap, + const std::string& userId); + std::string getKey() const; +/*MGEN:IF(Root.GenQMFv1)*/ + uint32_t writePropertiesSize() const; + void readProperties(const std::string& buf); + void writeProperties(std::string& buf) const; + void writeStatistics(std::string& buf, bool skipHeaders = false); + void doMethod(std::string& methodName, + const std::string& inBuf, + std::string& outBuf, + const std::string& userId); +/*MGEN:ENDIF*/ + + writeSchemaCall_t getWriteSchemaCall() { return writeSchema; } +/*MGEN:IF(Class.NoStatistics)*/ + // Stub for getInstChanged. There are no statistics in this class. + bool getInstChanged() { return false; } + bool hasInst() { return false; } +/*MGEN:ENDIF*/ + + /*MGEN:Class.NameCap*/(::qpid::management::ManagementAgent* agent, + ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); + ~/*MGEN:Class.NameCap*/(); + + /*MGEN:Class.SetGeneralReferenceDeclaration*/ + + static void registerSelf(::qpid::management::ManagementAgent* agent); + std::string& getPackageName() const { return packageName; } + std::string& getClassName() const { return className; } + uint8_t* getMd5Sum() const { return md5Sum; } + + // Method IDs +/*MGEN:Class.MethodIdDeclarations*/ + // Accessor Methods +/*MGEN:Class.AccessorMethods*/ +}; + +}/*MGEN:Class.CloseNamespaces*/ + +#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp new file mode 100644 index 0000000000..a8fdd0bd92 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -0,0 +1,101 @@ +/*MGEN:commentPrefix=//*/ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Manageable.h" +#include "qpid/management/Buffer.h" +#include "qpid/types/Variant.h" +#include "qpid/amqp_0_10/Codecs.h" +#include "qpid//*MGEN:Event.AgentHeaderLocation*//ManagementAgent.h" +#include "Event/*MGEN:Event.NameCap*/.h" + +using namespace qmf::/*MGEN:Event.Namespace*/; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; +using qpid::management::Mutex; +using std::string; + +string Event/*MGEN:Event.NameCap*/::packageName = string ("/*MGEN:Event.NamePackageLower*/"); +string Event/*MGEN:Event.NameCap*/::eventName = string ("/*MGEN:Event.Name*/"); +uint8_t Event/*MGEN:Event.NameCap*/::md5Sum[16] = + {/*MGEN:Event.SchemaMD5*/}; + +Event/*MGEN:Event.NameCap*/::Event/*MGEN:Event.NameCap*/ (/*MGEN:Event.ConstructorArgs*/) : + /*MGEN:Event.ConstructorInits*/ +{} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); +} + +void Event/*MGEN:Event.NameCap*/::registerSelf(ManagementAgent* agent) +{ + agent->registerEvent(packageName, eventName, md5Sum, writeSchema); +} + +void Event/*MGEN:Event.NameCap*/::writeSchema (std::string& schema) +{ + const int _bufSize = 65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + ::qpid::types::Variant::Map ft; + + // Schema class header: + buf.putOctet (CLASS_KIND_EVENT); + buf.putShortString (packageName); // Package Name + buf.putShortString (eventName); // Event Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count + + // Arguments +/*MGEN:Event.ArgSchema*/ + { + uint32_t _len = buf.getPosition(); + buf.reset(); + buf.getRawData(schema, _len); + } +} + +void Event/*MGEN:Event.NameCap*/::encode(std::string& _sBuf) const +{ + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + +/*MGEN:Event.ArgEncodes*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); +} + +void Event/*MGEN:Event.NameCap*/::mapEncode(::qpid::types::Variant::Map& map) const +{ + using namespace ::qpid::types; +/*MGEN:Event.ArgMap*/ +} diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.h b/qpid/cpp/managementgen/qmfgen/templates/Event.h new file mode 100644 index 0000000000..4f912cf220 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.h @@ -0,0 +1,58 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Event.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Event.NameUpper*/_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementEvent.h" + +namespace qmf { +/*MGEN:Event.OpenNamespaces*/ + +class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent +{ + private: + static void writeSchema (std::string& schema); + static std::string packageName; + static std::string eventName; + static uint8_t md5Sum[MD5_LEN]; + +/*MGEN:Event.ArgDeclarations*/ + + public: + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } + + Event/*MGEN:Event.NameCap*/(/*MGEN:Event.ConstructorArgs*/); + ~Event/*MGEN:Event.NameCap*/() {}; + + static void registerSelf(::qpid::management::ManagementAgent* agent); + std::string& getPackageName() const { return packageName; } + std::string& getEventName() const { return eventName; } + uint8_t* getMd5Sum() const { return md5Sum; } + uint8_t getSeverity() const { return /*MGEN:Event.Severity*/; } + void encode(std::string& buffer) const; + void mapEncode(::qpid::types::Variant::Map& map) const; +}; + +}/*MGEN:Event.CloseNamespaces*/ + +#endif /*!_MANAGEMENT_/*MGEN:Event.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk new file mode 100644 index 0000000000..b9adb4a2d2 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +/*MGEN:commentPrefix=#*/ +/*MGEN:Root.Disclaimer*/ +/*MGEN:IF(Makefile.QpidBroker)*/ +/*MGEN:mgenDir=$(mgen_dir)*/ +/*MGEN:specDir=$(top_srcdir)/../specs*/ + +mgen_generator=/*MGEN:Makefile.GenSources*/ + +mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ + +# Header file install rules. +/*MGEN:Makefile.HeaderInstalls*/ +if GENERATE +$(srcdir)/managementgen.mk: $(mgen_generator) + $(mgen_cmd) + +$(mgen_generator): +endif +/*MGEN:ENDIF*/ + +qmfgen_sources=/*MGEN:Makefile.GeneratedFiles*/ + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Package.cpp b/qpid/cpp/managementgen/qmfgen/templates/Package.cpp new file mode 100644 index 0000000000..f6bd7f4654 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Package.cpp @@ -0,0 +1,32 @@ +/*MGEN:commentPrefix=//*/ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "Package.h" +/*MGEN:Schema.ClassIncludes*/ + +using namespace qmf::/*MGEN:Schema.Namespace*/; + +Package::Package (::qpid::management::ManagementAgent* agent) +{ +/*MGEN:Schema.ClassRegisters*/ +} + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Package.h b/qpid/cpp/managementgen/qmfgen/templates/Package.h new file mode 100644 index 0000000000..569c7cfb33 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Package.h @@ -0,0 +1,41 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class Package +{ + public: + Package (::qpid::management::ManagementAgent* agent); + ~Package () {} +}; + +}/*MGEN:Class.CloseNamespaces*/ + + +#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp new file mode 100644 index 0000000000..2b6e231fe9 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp @@ -0,0 +1,37 @@ +/*MGEN:commentPrefix=//*/ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include "QmfPackage.h" +#include <qmf/Schema.h> +#include <qmf/SchemaProperty.h> +#include <qmf/SchemaMethod.h> +#include <string> + +using namespace std; +using namespace qmf::/*MGEN:Schema.Namespace*/; + +void PackageDefinition::configure(::qmf::AgentSession& session) +{ + string package("/*MGEN:Schema.PackageName*/"); +/*MGEN:Schema.V2ClassDefines*/ +} + diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.h b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h new file mode 100644 index 0000000000..1d4f907ab3 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h @@ -0,0 +1,46 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// + +/*MGEN:Root.Disclaimer*/ + +#include <qmf/AgentSession.h> +#include <qmf/Schema.h> +#include <qmf/Data.h> +#include <qmf/DataAddr.h> + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class PackageDefinition +{ + public: + ~PackageDefinition() {} + void configure(::qmf::AgentSession& session); + +/*MGEN:Schema.V2ClassMembers*/ +}; + +}/*MGEN:Class.CloseNamespaces*/ + + +#endif /*!_QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ |