########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Server/Xslt/DocumentDefinition.py,v 1.7 2005/04/06 23:05:46 jkloth Exp $
"""
XSLT extension elements and functions supporting the 4SS DocumentDefinition API

Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

import cStringIO

from Ft.Server.Common import CreationParams
from Ft.Xml.XPath import Conversions
from Ft.Xml.Xslt import XsltElement
from Ft.Xml.Xslt import ContentInfo, AttributeInfo
from Ft.Xml.Xslt import OutputParameters

from Ns import SCORE_NS
import FtssXsltBase


class AddBaseDocumentDefinitionElement(XsltElement):
    """
    Add a new document definition to a document definition's base defs.
    """

    content = ContentInfo.Empty

    legalAttrs = {
        'path' : AttributeInfo.UriReferenceAvt(
            description='The path of the document'),
        'docdef' : AttributeInfo.UriReferenceAvt(required=1,
            description='The document definition to use'),
        }

    def instantiate(self, context, processor):
        context.setProcessState(self)
        path = self._path.evaluate(context)
        dd = self._docdef.evaluate(context)
        base = FtssXsltBase.FetchBaseObject(processor, path)
        docdef = FtssXsltBase.FetchBaseObject(processor, dd)
        base.addBaseDocumentDefinition(docdef);
        return


def GetCreationParams(context, path=None):
    path = Conversions.StringValue(path)
    base = FtssXsltBase.FetchBaseObject(context.processor, path)

    cp = base.getCreationParams()
    doc = CreationParams.Serialize(cp)
    return [doc]


def GetBaseDefinitions(context, path=None):
    path = Conversions.StringValue(path)
    base = FtssXsltBase.FetchBaseObject(context.processor, path)

    proc = context.processor
    proc.pushResultTree(base.getAbsolutePath())
    for path in base.getBaseDefinitions():
        proc.writers[-1].startElement('BaseDocumentDefinition')
        proc.writers[-1].text(path.getAbsolutePath())
        proc.writers[-1].endElement('BaseDocumentDefinition')

    return proc.popResult().childNodes


def GetDerivedDefinitions(context, path=None):
    path = Conversions.StringValue(path)
    base = FtssXsltBase.FetchBaseObject(context.processor, path)

    proc = context.processor
    proc.pushResultTree(base.getAbsolutePath())
    for path in base.getDerivedDefinitions():
        proc.writers[-1].startElement('DerivedDocumentDefinition')
        proc.writers[-1].text(path.getAbsolutePath())
        proc.writers[-1].endElement('DerivedDocumentDefinition')

    return proc.popResult().childNodes



class RemoveBaseDocumentDefinitionElement(XsltElement):
    """
    Remove a document definition from a document definition's base defs.
    """

    content = ContentInfo.Empty

    legalAttrs = {
        'path' : AttributeInfo.UriReferenceAvt(
            description='The path of the document'),
        'docdef' : AttributeInfo.UriReferenceAvt(required=1,
            description='The document definition to use'),
        }

    def instantiate(self, context, processor):
        context.setProcessState(self)
        path = self._path.evaluate(context)
        dd = self._docdef.evaluate(context)
        base = FtssXsltBase.FetchBaseObject(processor, path)
        docdef = FtssXsltBase.FetchBaseObject(processor, dd)
        base.removeBaseDocumentDefinition(docdef);
        return


class SetCreationParamsElement(XsltElement):
    """
    Change the creation params of a document definition.

    The content of the fcore:set-creation-params element is a template for
    the new creation params in serialized format.
    """

    content = ContentInfo.Template

    legalAttrs = {
        'path' : AttributeInfo.UriReferenceAvt(
            description='The path for the new document'),
        }

    def __init__(self, root, namespaceUri, localName, baseUri):
        XsltElement.__init__(self, root, namespaceUri, localName, baseUri)
        self._output_parameters = OutputParameters.OutputParameters()
        return

    def instantiate(self, context, processor):
        context.setProcessState(self)
        path = self._path.evaluate(context)
        stream = cStringIO.StringIO()
        processor.addHandler(self._output_parameters, stream)
        self.processChildren(context, processor)
        processor.removeHandler()
        text = stream.getvalue()
        base = FtssXsltBase.FetchBaseObject(processor, path)
        cp = CreationParams.Deserialize(text)
        base.setCreationParams(cp);
        return


ExtFunctions = {
    (SCORE_NS, 'get-creation-params'): GetCreationParams,
    (SCORE_NS, 'get-base-definitions'): GetBaseDefinitions,
    (SCORE_NS, 'get-derived-definitions'): GetDerivedDefinitions,
}

ExtElements = {
    (SCORE_NS, 'set-creation-params'): SetCreationParamsElement,
    (SCORE_NS, 'add-base-document-definition'): AddBaseDocumentDefinitionElement,
    (SCORE_NS, 'remove-base-document-definition'): RemoveBaseDocumentDefinitionElement,
}
