blob: fb95eb4fb6624695e745f8ae52db1423a747d3cc [file] [log] [blame]
#!/usr/bin/env python
#
# Version 0.4
# Original work by Chuck Rolke
#
# 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.
#
# This code reads the AMQP 1.0 xml definitions and presents organized
# and cross referenced content in a web page.
#
# Originally this was to run in the proton-c source area but those
# xml files had the label fields stripped. The label fields add a lot
# to the result and so the source spec xml was hacked yet again for
# this work.
# The page layout generally follows the layout of the AMQP 1.0 spec.
#
# TODO: scavenge the ascii art from <doc> sections
# TODO: this code generates index data while printing table data.
# clean this up.
#
from __future__ import print_function
import sys, optparse, os, time, cgi
import xml.etree.ElementTree as ET
#
#
def log(text):
print("LOG: ", text, file=sys.stderr)
#
# construct data stores
typesPrimitive = [] # class == primitive
typesEnumerated = [] # no descriptor, choice count > 0
typesRestricted = [] # no descriptor, choice count == 0
typesDescribed = [] # contains descriptor
typesAll = {} # table[typename] = typenode for clean types
#
# indices computed while generating page
typeNameIndex = []
typeIndex = {} # key='name', value = [list of types]
fieldNameIndex = []
fieldIndex = {}
enumNameIndex = [] # names of enum values (not types)
enumIndex = {}
grandNameIndex = []
grandIndex = {}
xrefNameIndex = []
xrefIndex = {}
#
# provided types indexed by name of provided type, value is list of provider types
providedtypenames = []
provided = {} # {'name' : [type, type] with provides=name
#
# definition objects are constants
definitionsAll = []
#
# stats
class Stats():
def __init__(self):
self.nConstants = 0
self.nPrimitiveEncodings = 0
self.nEnumeratedTypes = 0
self.nRestrictedTypes = 0
self.nDescribedTypes = 0
self.nProvidedTypes = 0
self.nIndexedTypes = 0
self.nIndexedFields = 0
self.nIndexedEnumerations = 0
self.nIndexedGrand = 0
self.nIndexedXrefs = 0
def log(self):
log("STAT: nConstants = %s" % self.nConstants)
log("STAT: nPrimitiveEncodings = %s" % self.nPrimitiveEncodings)
log("STAT: nEnumeratedTypes = %s" % self.nEnumeratedTypes)
log("STAT: nRestrictedTypes = %s" % self.nRestrictedTypes)
log("STAT: nDescribedTypes = %s" % self.nDescribedTypes)
log("STAT: nProvidedTypes = %s" % self.nProvidedTypes)
log("STAT: nIndexedTypes = %s" % self.nIndexedTypes)
log("STAT: nIndexedFields = %s" % self.nIndexedFields)
log("STAT: nIndexedEnumerations = %s" % self.nIndexedEnumerations)
log("STAT: nIndexedGrand = %s" % self.nIndexedGrand)
log("STAT: nIndexedXrefs = %s" % self.nIndexedXrefs)
def statCheck(self, name, expectedValue):
currentValue = getattr(self, name)
if not currentValue == expectedValue:
log("WARNING stat %s expected %s but is actaully %s" % (name, expectedValue, currentValue))
stats = Stats()
class XmlStore():
def __init__(self, file_path):
self.tree = ET.parse(file_path)
self.root = self.tree.getroot() # root=Element 'amqp'
self.trimNamespace(self.root)
self.rootName = self.root.get("name")
self.sections = self.root.findall("section")
self.types = []
self.definitions = []
self.pictures = []
for section in self.sections:
ltypes = section.findall("type")
for type in ltypes:
# decorate and categorize each type
typesAll[type.get("name")] = type
type.text = self.rootName + ":" + section.get("name")
if type.get("class") == "primitive":
typesPrimitive.append(type)
else:
descr = type.find("descriptor")
if descr is None:
choices = type.find("choice")
if choices is None:
typesRestricted.append(type)
else:
typesEnumerated.append(type)
else:
typesDescribed.append(type)
provides = type.get("provides")
if provides is not None and not provides == "":
providelist = provides.replace(' ','').split(',')
for p in providelist:
if not p in provided:
providedtypenames.append(p)
provided[p] = []
provided[p].append(type)
self.types += section.findall("type")
ldefs = section.findall("definition")
for definition in ldefs:
#log("definition %s" % definition.get("name"))
definition.text = self.rootName + ":" + section.get("name")
definitionsAll.append(definition)
self.definitions += section.findall("definition")
sTitle = section.get("title")
if sTitle is None:
sTitle = ""
docs = section.findall("doc")
for doc in docs:
dTitle = doc.get("title")
if dTitle is None:
dTitle = ""
pics = doc.findall("picture")
for pic in pics:
pTitle = pic.get("title")
pic.caption = (self.rootName.capitalize() + " : " + sTitle + " : " + dTitle).strip()
self.pictures.append(pic)
def trimNamespace(self, node):
''' Strip out the "{amqp namespace}" ahead of each tag'''
pos = node.tag.find("}")
if pos > 0:
node.tag = node.tag[pos+1:]
for child in node:
self.trimNamespace(child)
def showPics(self):
nodeName = self.rootName.capitalize() + "Diag"
print("<a name=\"%sDiagrams\"</a><br>" % self.rootName.capitalize())
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%s%s<br>" %
((nodeName), lozenge(), nbsp(), self.rootName.capitalize() + " Diagrams"))
print("<div style=\"display: none; margin-bottom: 2px; margin-left: 10px\" id=\"%s\">" %
(nodeName))
for i in range(len(self.pictures)):
pic = self.pictures[i]
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%s<strong>%s</strong><br>" %
((nodeName + str(i)), lozenge(), nbsp(), pic.caption))
print("<div style=\"display: none; margin-bottom: 2px; margin-left: 10px\" id=\"%s\">" %
(nodeName + str(i)))
print("<pre>%s</pre><br>" % cgi.escape(pic.text))
print("</div>")
print("</div>")
print("<br>")
file_dir = sys.argv[1]
xmlTypes = XmlStore(os.path.join(file_dir, "types.xml"))
xmlTransport = XmlStore(os.path.join(file_dir, "transport.xml"))
xmlMessaging = XmlStore(os.path.join(file_dir, "messaging.xml"))
xmlSecurity = XmlStore(os.path.join(file_dir, "security.xml"))
xmlTransactions = XmlStore(os.path.join(file_dir, "transactions.xml"))
xmlStoreList = [xmlTypes, xmlTransport, xmlMessaging, xmlTransactions, xmlSecurity]
#
# Utilities
#
#
class ExitStatus(Exception):
"""Raised if a command wants a non-0 exit status from the script"""
def __init__(self, status): self.status = status
def nbsp():
return "&#160;"
def lozenge():
return "&#9674;"
def double_lozenge():
return lozenge() + lozenge()
def extract_descr_type_code(code):
return "0x" + code[19:]
def noNoneString(str):
if str:
return str
return ""
def noNoneTypeRef(str):
if str and not str == "":
res = "<a href=\"#TYPE_%s\">%s</a>" % (str, str)
return res
return ""
def noNoneProvideRef(str):
if str and not str == "":
res = ""
mylist = str.replace(' ','').split(',')
for e in mylist:
res += "<a href=\"#PROVIDEDTYPE_%s\">%s</a> " % (e, e)
return res
return ""
def addToIndex(name, section):
if not name in typeNameIndex:
typeNameIndex.append(name)
typeIndex[name] = []
typeIndex[name].append(section)
def addToFieldIndex(name, parentsection, parenttype):
if not name in fieldNameIndex:
fieldNameIndex.append(name)
fieldIndex[name] = []
fieldIndex[name].append( [parentsection, parenttype] )
def addToEnumIndex(name, parentsection, parenttype):
if not name in enumNameIndex:
enumNameIndex.append(name)
enumIndex[name] = []
enumIndex[name].append( [parentsection, parenttype] )
def addToGrandIndex(name, decoratedname, category, psect, ptype):
if not name in grandNameIndex:
grandNameIndex.append(name)
grandIndex[name] = []
grandIndex[name].append( [decoratedname, category, psect, ptype] )
def addToXrefIndex(name, decReferrerName, category, referrerSection):
if not name in xrefNameIndex:
xrefNameIndex.append(name)
xrefIndex[name] = []
xrefIndex[name].append( [decReferrerName, category, referrerSection] )
#
#
def print_start_body():
print ("""<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" type="text/javascript"></script>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" type="text/javascript"></script> -->
<!--
-
- 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.
-
-->
<script type="text/javascript">
function node_is_visible(node)
{
if(dojo.isString(node))
node = dojo.byId(node);
if(!node)
return false;
return node.style.display == "block";
}
function set_node(node, str)
{
if(dojo.isString(node))
node = dojo.byId(node);
if(!node) return;
node.style.display = str;
}
function toggle_node(node)
{
if(dojo.isString(node))
node = dojo.byId(node);
if(!node) return;
set_node(node, (node_is_visible(node)) ? 'none' : 'block');
}
function hide_node(node)
{
set_node(node, 'none');
}
function show_node(node)
{
set_node(node, 'block');
}
function go_back()
{
window.history.back();
}
""")
print("function show_all_tables()")
print("{")
print(" show_node('Constants');")
print(" show_node('PrimTypeName');")
print(" show_node('PrimTypeCode');")
print(" show_node('DescrTypes');")
print(" show_node('EnumTypes');")
print(" show_node('RestrTypes');")
print(" show_node('ProvTypes');")
print(" show_node('TypesDiag');")
print(" show_node('TransportDiag');")
print(" show_node('MessagingDiag');")
print(" show_node('TransactionsDiag');")
print(" show_node('SecurityDiag');")
print(" show_node('TypIndex');")
print(" show_node('FldIndex');")
print(" show_node('EnuIndex');")
print(" show_node('GndIndex');")
print(" show_node('XrefIndex');")
for type in typesDescribed:
print(" show_node('DT%s')" % type.get("name"))
for type in typesEnumerated:
print(" show_node('ET%s')" % type.get("name"))
print("}")
print("")
print("function hide_all_tables()")
print("{")
print(" hide_node('Constants');")
print(" hide_node('PrimTypeName');")
print(" hide_node('PrimTypeCode');")
print(" hide_node('DescrTypes');")
print(" hide_node('EnumTypes');")
print(" hide_node('RestrTypes');")
print(" hide_node('ProvTypes');")
print(" hide_node('TypesDiag');")
print(" hide_node('TransportDiag');")
print(" hide_node('MessagingDiag');")
print(" hide_node('TransactionsDiag');")
print(" hide_node('SecurityDiag');")
print(" hide_node('TypIndex');")
print(" hide_node('FldIndex');")
print(" hide_node('EnuIndex');")
print(" hide_node('GndIndex');")
print(" hide_node('XrefIndex');")
for type in typesDescribed:
print(" show_node('DT%s')" % type.get("name"))
for type in typesEnumerated:
print(" show_node('ET%s')" % type.get("name"))
print("}")
print ("</script>")
#
#
def print_toc():
# Table of Contents
print("<a href=\"#ConstantTypes\">Constants</a><br/>")
print("<a href=\"#Types\">Types</a><br/>")
print("%s%s<a href=\"#PrimitiveTypes\">Primitive Types</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#EnumeratedTypes\">Enumerated Types</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#RestrictedTypes\">Restricted Types</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#DescribedTypes\">Described Types</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#ProvidedTypes\">Provided Types</a><br/>" % (nbsp(), nbsp()))
print("<a href=\"#Diagrams\">Diagrams</a><br>")
print("<a href=\"#Indices\">Indices</a><br/>")
print("%s%s<a href=\"#TypeIndex\">Types</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#FieldIndex\">Fields</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#EnumerationIndex\">Enumerations</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#GrandIndex\">Grand Index</a><br/>" % (nbsp(), nbsp()))
print("%s%s<a href=\"#XrefIndex3\">Type Cross Reference</a><br/>" % (nbsp(), nbsp()))
print("<hr/>")
print("<strong>NOTE: Tables must be expanded or internal hyperlinks don't work.</strong><br/>")
print("<a href=\"javascript:show_all_tables()\"> %s </a>%sTable view: expand all.<br/>" % (lozenge(), nbsp()))
print("<a href=\"javascript:hide_all_tables()\"> %s </a>%sTable view: collapse all." % (lozenge(), nbsp()))
print("<hr/>")
def print_constants():
# print types sorted by class name
print("<a id=\"ConstantTypes\"></a>")
print("<h2>Constants</h2>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sConstants<br/>" % ("Constants", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"Constants\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Value</th>")
print(" <th>Label</th>")
print("</tr>")
for definition in definitionsAll:
print("<tr>")
print(" <td>%s</td>" % definition.text)
print(" <td><a id=\"TYPE_%s\"></a><strong>%s</strong></td>" % (definition.get("name"),definition.get("name")))
print(" <td>%s</td>" % definition.get("value"))
print(" <td>%s</td>" % definition.get("label"))
print("</tr>")
addToIndex(definition.get("name"), definition.text) # Constants
stats.nConstants += 1
print("</table>")
print("</div>")
print("<br/>")
#
#
encoding_typenames = []
encoding_codes = []
encoding_typemap = {}
encoding_codemap = {}
encoding_sectionmap = {}
primitive_anchors = []
def compute_primitive_types():
# create sorted lists for display
for type in typesPrimitive:
for enc in type.findall("encoding"):
typename = type.get("name")
if enc.get("name") is not None:
typename += ":" + enc.get("name")
typecode = enc.get("code")
enc.text = typename
if not typename in encoding_typenames:
encoding_typenames.append(typename)
encoding_codes.append(typecode)
encoding_typemap[typename] = enc
encoding_codemap[typecode] = enc
encoding_sectionmap[typename] = type.text
else:
raise ValueError("duplicate encoding type name: '%s'" % typename)
encoding_typenames.sort()
encoding_codes.sort()
def print_primitive_types():
# print types sorted by class name
print("<a id=\"Types\"></a>")
print("<h2>Types</h2>")
print("<a id=\"PrimitiveTypes\"></a>")
print("<h3>Primitive Types</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sby Name<br/>" % ("PrimTypeName", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"PrimTypeName\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Code</th>")
print(" <th>Category</th>")
print(" <th>Width</th>")
print(" <th>Label</th>")
print("</tr>")
for type in typesPrimitive:
if type.get("name") not in primitive_anchors:
primitive_anchors.append(type.get("name"))
else:
log("ERROR duplicate primitive type")
print("<tr>")
print(" <td>%s</td>" % type.text)
print(" <td><a id=\"TYPE_%s\"></a><strong>%s</strong></td>" % (type.get("name"), type.get("name")))
print(" <td></td>")
print(" <td></td>")
print(" <td></td>")
print(" <td>%s</td>" % type.get("label"))
print("</tr>")
addToIndex(type.get("name"), type.text) # Primitive category
for enc in type.findall("encoding"):
encodingTypeName = ""
if enc.text not in primitive_anchors:
encodingTypeName = "<a id=\"TYPE_%s\"></a>" % enc.text
print("<tr>")
print(" <td></td>")
print(" <td>%s<strong>%s</strong></td>" % (encodingTypeName, enc.text))
print(" <td>%s</td>" % enc.get("code"))
print(" <td>%s</td>" % enc.get("category"))
print(" <td>%s</td>" % enc.get("width"))
print(" <td>%s</td>" % enc.get("label"))
print("</tr>")
addToIndex(enc.text, "types:encodings") # Primitive type
stats.nPrimitiveEncodings += 1
# Phony primitive type "*"
print("<tr>")
print(" <td>spec:wildcard</td>")
print(" <td><a id=\"TYPE_*\"><strong>*</strong></a></td>")
print(" <td></td>")
print(" <td></td>")
print(" <td></td>")
print(" <td>A value of any type is permitted.</td>")
print("</tr>")
print("</table>")
print("</div>")
print("<br/>")
# print types sorted by class code
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sby Code<br/>" % ("PrimTypeCode", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"PrimTypeCode\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Code</th>")
print(" <th>Category</th>")
print(" <th>Width</th>")
print(" <th>Label</th>")
print("</tr>")
for code in encoding_codes:
enc = encoding_codemap[code]
print("<tr>")
print(" <td>%s</td>" % "types:encodings")
print(" <td><strong>%s</strong></td>" % enc.text)
print(" <td>%s</td>" % enc.get("code"))
print(" <td>%s</td>" % enc.get("category"))
print(" <td>%s</td>" % enc.get("width"))
print(" <td>%s</td>" % enc.get("label"))
print("</tr>")
print("</table>")
print("</div>")
print("<br/>")
#
#
descr_longnames = [] # "transport:performatives open"
descr_codes = [] # "0x10"
descr_codemap = {} # map[longname] = "0x10"
descr_mapcode = {} # map[code] = longname
descr_typemap = {} # map[longname] = type node
descr_fieldmap = {} # map[longname] = [list-of-field-nodes]
descr_fieldindex = [] # list of (fieldname, field's_parent_type_node)
# TODO: get the provides info
def compute_described_types():
for type in typesDescribed:
descriptor = type.find("descriptor")
descr_name = descriptor.get("name")
descr_code = extract_descr_type_code(descriptor.get("code"))
fields = type.findall("field")
longname = type.text + " " + type.get("name")
descr_longnames.append(longname)
descr_codes.append(descr_code)
descr_codemap[longname] = descr_code
descr_mapcode[descr_code] = longname
descr_typemap[longname] = type
if fields is not None:
descr_fieldmap[longname] = fields
for field in fields:
descr_fieldindex.append( (field.get("name"), type) )
descr_codes.sort()
#
#
def print_described_types():
print("<a id=\"DescribedTypes\"></a>")
print("<h3>Described Types</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sDescribed Types<br/>" % ("DescrTypes", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"DescrTypes\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Code</th>")
print(" <th>Type</th>")
print(" <th>Provides</th>")
print(" <th>Label</th>")
print("</tr>")
for code in descr_codes:
name = descr_mapcode[code]
descr_key = name.split()
section = descr_key[0]
descr_typename = descr_key[1]
type = descr_typemap[name]
print("<tr id=\"TYPE_%s\">" % descr_typename)
print(" <td>%s</td>" % section)
print(" <td><a href=\"#details_%s\"><strong>%s</strong></a></td>" % (descr_typename, descr_typename))
print(" <td>%s</td>" % code)
print(" <td><a href=\"#TYPE_%s\">%s</a></td>" % (type.get("source"), type.get("source")))
print(" <td>%s</td>" % noNoneProvideRef(type.get("provides")))
print(" <td>%s</td>" % noNoneString(type.get("label")))
print("</tr>")
addToIndex(descr_typename, section) # Described
stats.nDescribedTypes += 1
print("</table>")
print("<br/>")
for code in descr_codes:
name = descr_mapcode[code]
descr_key = name.split()
section = descr_key[0]
descr_typename = descr_key[1]
type = descr_typemap[name]
print("<a id=\"details_%s\"></a>" % descr_typename)
print("%s%s<a href=\"javascript:toggle_node('%s')\"> %s </a>%s %s<strong><a href=\"#TYPE_%s\">%s</a></strong><br/>" % \
(nbsp(), nbsp(), "DT"+descr_typename, lozenge(), nbsp(), "Described type: " + section + " - ", descr_typename, descr_typename))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"%s\">" % ("DT"+descr_typename))
print("<table>")
print("<tr>")
print(" <th>Tag</th>")
print(" <th>Name</th>")
print(" <th>Type</th>")
print(" <th>Requires</th>")
print(" <th>Default</th>")
print(" <th>Mandatory</th>")
print(" <th>Multiple</th>")
print(" <th>Label</th>")
print("</tr>")
for child in type:
childtag = ""
childtype = ""
printthis = True
if child.tag == "field":
childtype = "<a href=\"#TYPE_%s\">%s</a>" % (child.get("type"), child.get("type"))
childlabel = noNoneString(child.get("label"))
childname ="<a id=\"FIELD_%s_%s\">%s</a>" % (descr_typename, child.get("name"), child.tag)
childtag = " <td>%s</td>" % (childname)
addToFieldIndex(child.get("name"), section, descr_typename)
elif child.tag == "descriptor":
childlabel = noNoneString(type.get("label"))
childtag = " <td>%s</td>" % child.tag
else:
printthis = False
if printthis:
print("<tr>")
print("%s" % childtag)
print(" <td><strong>%s</strong></td>" % child.get("name"))
print(" <td>%s</td>" % (childtype))
print(" <td>%s</td>" % noNoneProvideRef(child.get("requires")))
print(" <td>%s</td>" % noNoneString(child.get("default")))
print(" <td>%s</td>" % noNoneString(child.get("mandatory")))
print(" <td>%s</td>" % noNoneString(child.get("multiple")))
print(" <td>%s</td>" % childlabel)
print("</tr>")
print("</table>")
print("<br/>")
print("</div>") # End one described type
print("</div>") # End described type details
print("<br/>")
#
#
enum_longnames = [] # "messaging:message-format terminus-durability"
enum_typemap = {} # map[longname] = type node
enum_choicemap = {} # map[longname] = [list-of-choice-fields]
enum_choiceindex = {} # list of (choicename, choice's_parent_type_node)
def compute_enumerated_types():
#log("typesEnumerated: %s" % typesEnumerated)
for type in typesEnumerated:
#log("processing enum %s" % type.get("name"))
longname = type.text + " " + type.get("name")
enum_longnames.append(longname)
enum_typemap[longname] = type
# if choices is not None:
# enum_choicemap[longname] = choices
# for choice in choices:
# log("processing enum choice %s" % choice.get("name"))
# enum_choiceindex.append( (choice.get("name"), type) )
choices = []
for child in type:
if child.tag == "choice":
choices += child
enum_choiceindex[child.get("name")] = type
addToEnumIndex(child.get("name"), type.text, type.get("name"))
enum_choicemap[longname] = choices
enum_longnames.sort()
def print_enumerated_types():
print("<a id=\"EnumeratedTypes\"></a>")
print("<h3>Enumerated Types</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sEnumerated Types<br/>" % ("EnumTypes", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"EnumTypes\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Type</th>")
print(" <th>Label</th>")
print(" <th>Provides</th>")
print("</tr>")
for lname in enum_longnames:
type = enum_typemap[lname]
print("<tr id=\"TYPE_%s\">" % type.get("name"))
print(" <td>%s</td>" % type.text)
print(" <td><a href=\"#details_%s\"><strong>%s</strong></a></td>" % (type.get("name"), type.get("name")))
print(" <td><a href=\"#TYPE_%s\">%s</a></td>" % (type.get("source"), type.get("source")))
print(" <td>%s</td>" % noNoneString(type.get("label")))
print(" <td>%s</td>" % noNoneProvideRef(type.get("provides")))
print("</tr>")
addToIndex(type.get("name"), type.text) # Enum
stats.nEnumeratedTypes += 1
print("</table>")
print("<br/>")
for lname in enum_longnames:
type = enum_typemap[lname]
enum_key = lname.split()
section = enum_key[0]
enum_typename = enum_key[1]
print("<a id=\"details_%s\"></a>" % (enum_typename))
print("%s%s<a href=\"javascript:toggle_node('%s')\"> %s </a>%s %s<strong><a href=\"#TYPE_%s\">%s</a></strong><br/>" % \
(nbsp(), nbsp(), "ET"+enum_typename, lozenge(), nbsp(), "Enumerated type: " + section + " - ", enum_typename, enum_typename))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"%s\">" % ("ET"+enum_typename))
print("<table>")
print("<tr>")
print(" <th>Name</th>")
print(" <th>Type/Value</th>")
print(" <th>Label</th>")
print(" <th>Provides</th>")
print("</tr>")
print("<tr>")
print(" <td><strong>%s</strong></td>" % (type.get("name")))
print(" <td><a href=\"#TYPE_%s\">%s</a></td>" % (type.get("source"), type.get("source")))
print(" <td>%s</td>" % noNoneString(type.get("label")))
print(" <td>%s</td>" % noNoneProvideRef(type.get("provides")))
print("</tr>")
for child in type.findall("choice"):
print("<tr>")
print(" <td><strong>%s</strong></td>" % child.get("name"))
print(" <td>%s</td>" % child.get("value"))
print("</tr>")
print("</table>")
print("<br/>")
print("</div>")
print("</div>") # End enumerated type details
print("<br/>")
#
#
def print_restricted_types():
print("<a id=\"RestrictedTypes\"></a>")
print("<h3>Restricted Types</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sRestricted Types<br/>" % ("RestrTypes", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"RestrTypes\">")
print("<table>")
print("<tr>")
print(" <th>Section</th>")
print(" <th>Name</th>")
print(" <th>Type</th>")
print(" <th>Label</th>")
print(" <th>Provides</th>")
print("</tr>")
for type in typesRestricted:
print("<tr>")
print(" <td>%s</td>" % type.text)
print(" <td><strong><a id=\"TYPE_%s\">%s</a></strong></td>" % (type.get("name"), type.get("name")))
print(" <td><a href=\"#TYPE_%s\">%s</a></td>" % (type.get("source"),type.get("source")))
print(" <td>%s</td>" % noNoneString(type.get("label")))
print(" <td>%s</td>" % noNoneProvideRef(type.get("provides")))
print("</tr>")
addToIndex(type.get("name"), type.text) # Restricted
stats.nRestrictedTypes += 1
# HACK ALERT: A phony type. real type is missing from spec
print("<tr>")
print(" <td>ERROR: unspecified</td>")
print(" <td><strong><a id=\"PROVIDEDTYPE_%s\">%s</a></strong></td>" % ("global-tx-id", "global-tx-id"))
print(" <td><a href=\"#TYPE_%s\">%s</a></td>" % ("binary", "binary"))
print(" <td>%s</td>" % "global transaction id")
print(" <td>%s</td>" % "")
print("</tr>")
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_provided_types():
providedtypenames.sort()
print("<a id=\"ProvidedTypes\"></a>")
print("<h3>Provided Types</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sProvided Types<br/>" % ("ProvTypes", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"ProvTypes\">")
print("<table>")
print("<tr>")
print(" <th>Provided Type</th>")
print(" <th>Provider</th>")
print(" <th>Provider Section</th>")
print("</tr>")
for ptype in providedtypenames:
anchor = " id=\"PROVIDEDTYPE_%s\"" % ptype
types = provided[ptype]
addToIndex(ptype, "PROVIDED")
stats.nProvidedTypes += 1
for type in types:
print("<tr%s>" % anchor)
anchor = ""
print(" <td>%s</td>" % ptype)
print(" <td>%s</td>" % noNoneTypeRef(type.get("name")))
print(" <td>%s</td>" % type.text)
print("</tr>")
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_asciiart():
print("<a id=\"Diagrams\"></a>")
print("<h2>Diagrams</h2>")
print("These diagrams may not make sense when taken out of the context of the ")
print("<a href=\"http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-overview-v1.0-os.html\">")
print("AMQP 1.0 Specification</a>. Please refer to the spec to get the complete narrative.<br>")
for x in xmlStoreList:
x.showPics()
#
#
def print_type_index():
typeNameIndex.sort()
print("<a id=\"Indices\"></a>")
print("<h2>Indices</h2>")
print("<a id=\"TypeIndex\"></a>")
print("<h3>Type Index</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sType Index<br/>" % ("TypIndex", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"TypIndex\">")
print("<table>")
print("<tr>")
print(" <th>Type Name</th>")
print(" <th>Section</th>")
print("</tr>")
for idx in typeNameIndex:
sections = typeIndex[idx]
for section in sections:
print("<tr>")
if section == "PROVIDED":
name = noNoneProvideRef(idx)
else:
name = noNoneTypeRef(idx)
print(" <td>%s</td>" % name)
print(" <td>%s</td>" % section)
print("</tr>")
addToGrandIndex(idx, name, "type", section, " ")
stats.nIndexedTypes += 1
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_field_index():
fieldNameIndex.sort()
print("<a id=\"FieldIndex\"></a>")
print("<h3>Field Index</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sField Index<br/>" % ("FldIndex", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"FldIndex\">")
print("<table>")
print("<tr>")
print(" <th>Field Name</th>")
print(" <th>Parent Type</th>")
print(" <th>Section</th>")
print("</tr>")
for idx in fieldNameIndex:
parents = fieldIndex[idx]
for parent in parents:
psect = parent[0]
ptype = parent[1]
print("<tr>")
name = "<a href=\"#FIELD_%s_%s\">%s</a>" % (ptype, idx, idx)
print(" <td>%s</td>" % name)
print(" <td>%s</td>" % ptype)
print(" <td>%s</td>" % psect)
print("</tr>")
addToGrandIndex(idx, name, "field", psect, ptype)
stats.nIndexedFields += 1
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_enumeration_index():
enumNameIndex.sort()
print("<a id=\"EnumerationIndex\"></a>")
print("<h3>Enumeration Index</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sEnumeration Index<br/>" % ("EnuIndex", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"EnuIndex\">")
print("<table>")
print("<tr>")
print(" <th>Enum Value</th>")
print(" <th>Enumeration</th>")
print(" <th>Section</th>")
print("</tr>")
for idx in enumNameIndex:
parents = enumIndex[idx]
for parent in parents:
psect = parent[0]
ptype = parent[1]
enum = "<a href=\"#TYPE_%s\">%s</a>" % (ptype, ptype)
print("<tr>")
print(" <td>%s</td>" % idx)
print(" <td>%s</td>" % enum)
print(" <td>%s</td>" % psect)
print("</tr>")
addToGrandIndex(idx, idx, "enum value", psect, enum)
stats.nIndexedEnumerations += 1
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_grand_index():
grandNameIndex.sort()
print("<a id=\"GrandIndex\"></a>")
print("<h3>Grand Index</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sGrand Index<br/>" % ("GndIndex", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"GndIndex\">")
print("<table>")
print("<tr>")
print(" <th>Name</th>")
print(" <th>Category</th>")
print(" <th>Parent</th>")
print(" <th>Section</th>")
print("</tr>")
for idx in grandNameIndex:
parents = grandIndex[idx]
for parent in parents:
print("<tr>")
print(" <td>%s</td>" % parent[0])
print(" <td>%s</td>" % parent[1])
print(" <td>%s</td>" % parent[2])
print(" <td>%s</td>" % parent[3])
print("</tr>")
stats.nIndexedGrand += 1
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_xref_index():
# Create xref name index from type index.
xrefNameIndex.append("*")
for idx in typeNameIndex:
sections = typeIndex[idx]
for section in sections:
name = idx
if section == "PROVIDED":
name += ",PROVIDED"
if name not in xrefNameIndex:
xrefNameIndex.append(name)
else:
# primitive type names get reused as encoding names...
pass
xrefNameIndex.sort()
for name in xrefNameIndex:
xrefIndex[name] = [] # list of types defined in terms of type 'name'
# Enum types
for lname in enum_longnames:
type = enum_typemap[lname]
decname = noNoneTypeRef(type.get("name"))
source = type.get("source")
category = "enum"
refSection = type.text
xrefIndex[source].append( [decname, category, refSection])
# Restricted types
for type in typesRestricted:
decname = noNoneTypeRef(type.get("name"))
source = type.get("source")
category = "restricted"
refSection = type.text
xrefIndex[source].append( [decname, category, refSection])
# Described types
for code in descr_codes:
name = descr_mapcode[code]
descr_key = name.split()
section = descr_key[0]
descr_typename = descr_key[1]
type = descr_typemap[name]
decname = noNoneTypeRef(descr_typename)
source = type.get("source")
category = "described"
refSection = section
xrefIndex[source].append( [decname, category, refSection])
# Described fields
for code in descr_codes:
name = descr_mapcode[code]
descr_key = name.split()
section = descr_key[0]
descr_typename = descr_key[1]
type = descr_typemap[name]
for child in type:
if child.tag == "field":
decname = "<a href=\"#FIELD_%s_%s\">%s</a>" % (descr_typename, child.get("name"), child.get("name"))
source = child.get("type")
category = "field"
refSection = "%s - %s" % (section, descr_typename)
xrefIndex[source].append( [decname, category, refSection])
# Provided types
for ptype in providedtypenames:
types = provided[ptype]
for type in types:
decname = noNoneTypeRef(type.get("name"))
source = "%s,%s" % (ptype, "PROVIDED")
category = "provided"
refSection = ""
xrefIndex[source].append( [decname, category, refSection])
print("<a id=\"XrefIndex3\"></a>")
print("<h3>Cross Reference Index</h3>")
print("<a href=\"javascript:toggle_node('%s')\"> %s </a>%sType Cross Reference<br/>" % ("XrefIndex", lozenge(), nbsp()))
print("<div style=\"display: block; margin-bottom: 2px\" id=\"XrefIndex\">")
print("<table>")
print("<tr>")
print(" <th>Referenced Type</th>")
print(" <th>Referrer</th>")
print(" <th>Section</th>")
print(" <th>Type</th>")
print("</tr>")
for idx in xrefNameIndex:
if ":" not in idx:
try:
idxlist = idx.split(',')
typetext = ""
typename = ""
if len(idxlist) == 1:
if idx == "*":
typetext = "spec:wildcard"
typename = "*"
else:
type = typesAll[idx]
typetext = type.text
typename = idxlist[0]
else:
typetext = "provided"
typename = "<a href=\"#PROVIDEDTYPE_%s\"> %s </a>" % (idxlist[0], idxlist[0])
refs = xrefIndex[idx]
if len(refs) == 0:
print("<tr>")
print(" <td>%s:<strong>%s</strong></td>" % (typetext, typename))
print(" <td>%s</td>" % nbsp())
print(" <td>%s</td>" % nbsp())
print(" <td>%s</td>" % nbsp())
print("</tr>")
for ref in refs:
print("<tr>")
print(" <td>%s:<strong>%s</strong></td>" % (typetext, typename))
print(" <td>%s</td>" % ref[0])
print(" <td>%s</td>" % ref[2])
print(" <td>%s</td>" % ref[1])
print("</tr>")
stats.nIndexedXrefs += 1
except:
#log("Can't resolve as type: %s" % idx) # constants can't be resolved
pass
print("</table>")
print("</div>")
print("<br/>")
#
#
def print_end_body():
pass
#
#
def main_except(argv):
# Compute tables and stuff that may be needed by show/hide functions
compute_primitive_types()
compute_described_types()
compute_enumerated_types()
# Print the web page
print_start_body()
print("<h1>AMQP 1.0 interactive type reference</h1>")
print_toc()
print_constants()
print_primitive_types()
print_enumerated_types()
print_restricted_types()
print_described_types()
print_provided_types()
print_asciiart()
print_type_index()
print_field_index()
print_enumeration_index()
print_grand_index()
print_xref_index()
print_end_body()
stats.statCheck("nConstants", 13)
stats.statCheck("nPrimitiveEncodings", 39)
stats.statCheck("nEnumeratedTypes", 13)
stats.statCheck("nRestrictedTypes", 19)
stats.statCheck("nDescribedTypes", 40)
stats.statCheck("nProvidedTypes", 14)
stats.statCheck("nIndexedTypes", 162)
stats.statCheck("nIndexedFields", 125)
stats.statCheck("nIndexedEnumerations", 54)
stats.statCheck("nIndexedGrand", 341)
stats.statCheck("nIndexedXrefs", 252)
#
#
def main(argv):
try:
main_except(argv)
return 0
except ExitStatus, e:
return e.status
except Exception, e:
print("%s: %s"%(type(e).__name__, e))
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv))