########################################################################
#
# File Name:            Processor.py
#
# Documentation:        http://docs.4suite.org/4XLink/Processor.py.html
#
"""
Implement the XLink processor engine
WWW: http://4suite.org/4Link        e-mail: support@4suite.org

Copyright (c) 2000-2001 Fourthought, Inc., USA.   All Rights Reserved.
See  http://4suite.org/COPYRIGHT  for license and copyright information
"""

import string, os
import cStringIO
from Ft.Lib import pDomlette
from xml import xpath
from Ft.XLink import XLINK_NAMESPACE
from Ft.XLink import XLinkElements

class Processor:

    def runString(self, source, reader=None, refUri=''):
        if reader == None:
            reader = pDomlette.PyExpatReader()
        st = cStringIO.StringIO(source)
        doc = reader.fromStream(st, refUri)
        return self._run(doc, reader, refUri)

    def runUri(self, uri, reader=None):
        if reader == None:
            reader = pDomlette.PyExpatReader()
        doc = reader.fromUri(uri)
        return self._run(doc, reader, uri)

    def _run(self, node, reader, baseUri):
        """
        Warning: The document will be modified in place
        The reader class MUST be able to support reading from href values.
        (i.e., URIs, but could be anything).
        """
        document = node.ownerDocument or node
        context = xpath.CreateContext(document)
        context.processorNss.update({'xlink':XLINK_NAMESPACE})
        xlinks = xpath.Evaluate('/descendant-or-self::*[@xlink:type]', context=context)
        for link in xlinks:
            xlink = XLinkElements.Create(link, baseUri)
            xlink.process(reader)
        return document
