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:
sebd 2005-02-11 16:23:30 +00:00
parent 62c8a49ead
commit 70489eeef3
2 changed files with 87 additions and 4 deletions

View File

@ -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()

View File

@ -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: