Method getDescription looks for a description related to the element Type.
Added Element methods prefixFieldNames, getValue, getValueList. Added ElementFeature attributes typeName and typeNamespace. Added modules.getRegisteredElementClasses and modules.registerElementType
This commit is contained in:
parent
62c8a49ead
commit
70489eeef3
|
@ -398,7 +398,11 @@ class Element(stations.AbstractStation, nodes.NodeWrapper):
|
|||
pass
|
||||
else:
|
||||
descriptionAbsolutePath = feature.descriptionAbsolutePath
|
||||
|
||||
# Otherwise, ask the element's schema type for a description
|
||||
if descriptionAbsolutePath is None:
|
||||
type = self.getType()
|
||||
if type is not None:
|
||||
descriptionAbsolutePath = type.getDescriptionAbsolutePath()
|
||||
if descriptionAbsolutePath is None:
|
||||
self._description = "none"
|
||||
else:
|
||||
|
@ -484,6 +488,23 @@ class Element(stations.AbstractStation, nodes.NodeWrapper):
|
|||
return None
|
||||
return schema.getGlobalElementType(self, self.node.name)
|
||||
|
||||
def getValue(self, fieldName):
|
||||
""" Returns the value of the "field".
|
||||
This is much more forgiving than getContentAtXpath, and simpler to use.
|
||||
This calls method prefixFieldName to get a parsable xpath expression out of the "fieldName".
|
||||
In case of several matching values, returns the first found value.
|
||||
In case of no matching value, returns None.
|
||||
"""
|
||||
if fieldName[0] == "@":
|
||||
return self.node.prop(fieldName[1:])
|
||||
for node in self.evaluateXpath(self.prefixFieldName(fieldName)):
|
||||
return node.getContent()
|
||||
|
||||
def getValueList(self, fieldNameList):
|
||||
""" Returns a list of values matching the list of field names.
|
||||
"""
|
||||
return [self.getValue(fieldName) for fieldName in fieldNameList]
|
||||
|
||||
def layoutRequiresForm(self):
|
||||
description = self.getDescription()
|
||||
if description is not None:
|
||||
|
@ -535,6 +556,35 @@ class Element(stations.AbstractStation, nodes.NodeWrapper):
|
|||
data, mimeType = dataHolder.mimeType,
|
||||
modificationTime = dataHolder.getModificationTime())
|
||||
|
||||
def prefixFieldName(self, path, prefix = None):
|
||||
""" Returns path with element namespaces names prefixed.
|
||||
The default prefix is self's node's own namespace name.
|
||||
|
||||
Examples:
|
||||
"yep:name" -> "yep:name"
|
||||
"name" -> "yep:name"
|
||||
"fee/amount" -> "yep:fee/yep:amount"
|
||||
"/card/@userId" -> "/yep:card/@userId"
|
||||
"""
|
||||
if prefix is None:
|
||||
prefix = self.getNamespacePrefix()
|
||||
if prefix is None:
|
||||
return path
|
||||
if path[0] == "@":
|
||||
return path
|
||||
if path[0] == "/":
|
||||
return "/%s" % prefixFieldName(path[1:], prefix)
|
||||
try:
|
||||
slashPosition = path.index("/")
|
||||
except ValueError:
|
||||
if ":" in path:
|
||||
return path
|
||||
return "%s:%s" % (prefix, path)
|
||||
name = path[:slashPosition]
|
||||
if ":" not in name:
|
||||
name = "%s:%s" % (prefix, name)
|
||||
return "%s/%s" % (name, prefixFieldName(path[slashPosition + 1:], prefix))
|
||||
|
||||
def prepareForSaving(self):
|
||||
""" gives a chance to the Element instance for self-checking
|
||||
|
||||
|
@ -728,9 +778,12 @@ class ElementFeature(object):
|
|||
holderConstructor = None
|
||||
namespaceUri = None
|
||||
schemaAbsolutePath = None
|
||||
typeName = None
|
||||
typeNamespace = None
|
||||
|
||||
def __init__(self, namespaceUri, elementName, elementClass = None, schemaAbsolutePath = None,
|
||||
descriptionAbsolutePath = None, holderClass = None, holderConstructor = None):
|
||||
descriptionAbsolutePath = None, holderClass = None, holderConstructor = None,
|
||||
typeName = None, typeNamespace = None):
|
||||
if namespaceUri is not None:
|
||||
self.namespaceUri = namespaceUri
|
||||
if elementName is not None:
|
||||
|
@ -745,6 +798,10 @@ class ElementFeature(object):
|
|||
self.holderClass = holderClass
|
||||
if holderConstructor is not None:
|
||||
self.holderConstructor = holderConstructor
|
||||
if typeName is not None:
|
||||
self.typeName = typeName
|
||||
if typeNamespace is not None:
|
||||
self.typeNamespace = typeNamespace
|
||||
|
||||
def newXmlHolder(self, directoryHolder, pathFragment = None, uriPathFragment = None,
|
||||
temporary = False):
|
||||
|
@ -770,6 +827,8 @@ class ElementFeature(object):
|
|||
if self.holderClass is not None:
|
||||
self.holderClass.register()
|
||||
modules.registerHolderClass(self.namespaceUri, self.elementName, self.holderClass)
|
||||
if self.typeName and self.typeNamespace:
|
||||
modules.registerElementType(self.typeNamespace, self.typeName, self)
|
||||
|
||||
|
||||
class AuthenticatedUsers(Element):
|
||||
|
@ -935,7 +994,8 @@ def newElement(node, previous = None, parent = None, uriPathFragment = None, own
|
|||
|
||||
|
||||
def registerElement(namespaceUri, elementName, elementClass = None, schemaLocation = None,
|
||||
descriptionLocation = None, holderClass = None, holderConstructor = None):
|
||||
descriptionLocation = None, holderClass = None, holderConstructor = None,
|
||||
typeName = None, typeNamespace = None):
|
||||
# The locations are relative to Python data. Convert them to absolute paths
|
||||
schemaAbsolutePath = None
|
||||
if schemaLocation:
|
||||
|
@ -975,7 +1035,7 @@ def registerElement(namespaceUri, elementName, elementClass = None, schemaLocati
|
|||
descriptionAbsolutePath = None
|
||||
elementFeature = ElementFeature(
|
||||
namespaceUri, elementName, elementClass, schemaAbsolutePath, descriptionAbsolutePath,
|
||||
holderClass, holderConstructor)
|
||||
holderClass, holderConstructor, typeName, typeNamespace)
|
||||
elementFeature.register()
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ _defaultElementClass = None
|
|||
_elementClasses = {}
|
||||
_elementFeatures = {}
|
||||
_elementNamespaceUriAndNameCouples = {}
|
||||
_elementTypes = {}
|
||||
_holderClasses = {}
|
||||
_holderNamespaceUriAndNameCouples = {}
|
||||
|
||||
|
@ -79,6 +80,10 @@ def getElementFeature(namespaceUri, elementName):
|
|||
return _elementFeatures[namespaceUri][elementName]
|
||||
|
||||
|
||||
def getElementFeatureFromType(typeNamespace, typeName):
|
||||
return _elementTypes[typeNamespace][typeName]
|
||||
|
||||
|
||||
def getHolderConstructorNamespaceAndElementNames():
|
||||
import elements
|
||||
namespaceNameAndNameCouples = []
|
||||
|
@ -91,6 +96,18 @@ def getHolderConstructorNamespaceAndElementNames():
|
|||
return namespaceNameAndNameCouples
|
||||
|
||||
|
||||
def getRegisteredElementClasses():
|
||||
""" Returns the list of all registered element classes.
|
||||
"""
|
||||
r = []
|
||||
for namespaceUri in _elementClasses:
|
||||
for elementName in _elementClasses[namespaceUri]:
|
||||
clas = _elementClasses[namespaceUri][elementName]
|
||||
if clas not in r:
|
||||
r.append(clas)
|
||||
return r
|
||||
|
||||
|
||||
def registerElementClass(namespaceUri, elementName, elementClass):
|
||||
assert namespaceUri
|
||||
if namespaceUri not in _elementClasses:
|
||||
|
@ -107,6 +124,12 @@ def registerElementFeature(namespaceUri, name, elementFeature):
|
|||
_elementFeatures[namespaceUri][name] = elementFeature
|
||||
|
||||
|
||||
def registerElementType(typeNamespace, typeName, elementFeature):
|
||||
if typeNamespace not in _elementTypes:
|
||||
_elementTypes[typeNamespace] = {}
|
||||
_elementTypes[typeNamespace][typeName] = elementFeature
|
||||
|
||||
|
||||
def registerHolderClass(namespaceUri, elementName, holderClass):
|
||||
assert namespaceUri
|
||||
if namespaceUri not in _holderClasses:
|
||||
|
|
Reference in New Issue