######################################################################## # # File name: DocumentDefinitionSerialization.py # # """ WWW: http://4suite.org e-mail: support@4suite.org Copyright 2002 Fourthought Inc, USA. See http://4suite.org/COPYRIGHT for license and copyright information """ import cStringIO from Ft.Xml.Domlette import Print, GetAllNs from Ft.Xml import XML_NAMESPACE, XMLNS_NAMESPACE, EMPTY_PREFIX, EMPTY_NAMESPACE from Ft.Xml import Domlette, XPath from Ft.Server import FTSERVER_NAMESPACE, RESERVED_NAMESPACE from Ft import Rdf import CreationParams from Ft.Xml.XLink import XLINK_NAMESPACE from Ft.Xml.XPath import Util def Serialize(bns, nss, maps, cp): """Serialize a XPath Document Definition from discrete components""" doc = Domlette.implementation.createDocument(None, None, None) de = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:DocDef') doc.appendChild(de) _SerializeBaseNames(doc, bns) nsm = _SerializeNsMap(doc, nss) if nsm: doc.documentElement.appendChild(nsm) rm = _SerializeRdfMaps(doc, maps) if rm: doc.documentElement.appendChild(rm) params = CreationParams._Serialize(doc, cp) doc.documentElement.appendChild(params) st = cStringIO.StringIO() Print(doc, stream=st) return st.getvalue() def Deserialize(dd_dom): """Deserialize a document definition into its pieces""" con = XPath.Context.Context(dd_dom, processorNss={'ftss': FTSERVER_NAMESPACE}) creationParams = CreationParams._Deserialize(con) bns = _DeserializeBaseNames(con) rdf_maps = _DeserializeRdfMaps(con) ns_maps = _DeserializeNsMaps(con) return bns, ns_maps, rdf_maps, creationParams def _SerializeBaseNames(doc, bns): root = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:BaseNames') for b in bns: base = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:Base') base.setAttributeNS(XLINK_NAMESPACE, u'xlink:type', u'simple') base.setAttributeNS(XLINK_NAMESPACE, u'xlink:href', b) base.setAttributeNS(XLINK_NAMESPACE, u'xlink:actuate', u'onLoad') base.setAttributeNS(XLINK_NAMESPACE, u'xlink:show', u'embed') root.appendChild(base) doc.documentElement.appendChild(root) def _SerializeNsMap(doc, nss): root = None for prefix, ns in nss.items(): if not prefix: continue name = 'xmlns:'+prefix if doc.documentElement.hasAttributeNS(XMLNS_NAMESPACE,name): if doc.documentElement.getAttributeNS(XMLNS_NAMESPACE,name) != ns: #What the heck do we do here raise "If you ever get this then we need to talk" else: doc.documentElement.setAttributeNS(XMLNS_NAMESPACE,name, ns) #Make sure there is nothing extra there keys = map(lambda x: str(x),nss.keys()) for node in doc.documentElement.attributes.values(): if (node.namespaceURI == XMLNS_NAMESPACE and not node.localName in keys): doc.documentElement.removeAttributeNode(node) return root def _SerializeRdfMaps(doc, maps): root = None if maps: root = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:RdfMappings') for map in maps: m = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:RdfMapping') s = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:Subject') s.appendChild(doc.createTextNode(map[0])) m.appendChild(s) p = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:Predicate') p.appendChild(doc.createTextNode(map[1])) m.appendChild(p) o = doc.createElementNS(FTSERVER_NAMESPACE, u'ftss:Object') o.appendChild(doc.createTextNode(map[2])) if (len(map) == 4): if map[3] == Rdf.OBJECT_TYPE_RESOURCE: o.setAttributeNS(EMPTY_NAMESPACE, u'type', u'rdf:Resource') m.appendChild(o) root.appendChild(m) return root def _DeserializeBaseNames(con): res = XPath.Evaluate('/ftss:DocDef/ftss:BaseNames/ftss:Base/@xlink:href', context=con) return map(lambda x:x.value,res) _nsMapExpression = XPath.Compile('ftss:DocDef/ftss:NsMappings/ftss:NsMapping') _nsMapUriExpression = XPath.Compile('string(ftss:Uri)') _nsMapPrefixExpression = XPath.Compile('string(ftss:Prefix)') def _DeserializeNsMaps(con): ownerDoc = con.node.rootNode ns_maps = GetAllNs(ownerDoc.documentElement) maps = _nsMapExpression.evaluate(con) oNode = con.node for nsm in maps: con.node = nsm prefix = _nsMapPrefixExpression.evaluate(con) uri = _nsMapUriExpression.evaluate(con) ns_maps[prefix] = uri con.node = oNode return ns_maps _rdfMapExpression = XPath.Compile('ftss:DocDef/ftss:RdfMappings/ftss:RdfMapping') _rdfMapSubjectExpression = XPath.Compile('string(ftss:Subject)') _rdfMapPredicateExpression = XPath.Compile('string(ftss:Predicate)') _rdfMapObjectExpression = XPath.Compile('string(ftss:Object)') _rdfMapObjectTypeExpression = XPath.Compile('string(ftss:Object/@type)') from Ft.Rdf import RDF_MS_BASE, OBJECT_TYPE_UNKNOWN, OBJECT_TYPE_LITERAL, OBJECT_TYPE_RESOURCE def _DeserializeRdfMaps(con): maps = _rdfMapExpression.evaluate(con) rdf_maps = [] oNode = con.node for rdfm in maps: con.node = rdfm subj = _rdfMapSubjectExpression.evaluate(con) pred = _rdfMapPredicateExpression.evaluate(con) obj = _rdfMapObjectExpression.evaluate(con) obj_type = OBJECT_TYPE_UNKNOWN if _rdfMapObjectTypeExpression.evaluate(con): obj_type_str = _rdfMapObjectTypeExpression.evaluate(con) #For backward compat if obj_type_str in ["RESOURCE", "LITERAL"]: obj_type = OBJECT_TYPE_LITERAL if obj_type_str == "RESOURCE": obj_type = OBJECT_TYPE_RESOURCE else: exp_name = Util.ExpandQName(obj_type_str, refNode=con.node) if exp_name == (RDF_MS_BASE, u'Resource'): obj_type = OBJECT_TYPE_RESOURCE elif exp_name == (RDF_MS_BASE, u'Literal'): obj_type = OBJECT_TYPE_LITERAL else: #For now obj_type = OBJECT_TYPE_LITERAL rdf_maps.append((subj, pred, obj, obj_type)) con.node = oNode return rdf_maps