Ejemplo n.º 1
0
class FtOutputElement(XsltElement):
    """
    f:output is similar to xsl:output, but it allows you to compute the
    output parameters dynamically (as attribute value templates). Unlike
    xsl:output, this element is not expected to be empty; the output
    parameters apply only to the serialization of the element's content.
    """
    content = ContentInfo.Template
    legalAttrs = {
        'method': AttributeInfo.QNameAvt(),
        'version': AttributeInfo.NMTokenAvt(),
        'encoding': AttributeInfo.StringAvt(),
        'omit-xml-declaration': AttributeInfo.YesNoAvt(),
        'standalone': AttributeInfo.YesNoAvt(),
        'doctype-public': AttributeInfo.StringAvt(),
        'doctype-system': AttributeInfo.StringAvt(),
        'cdata-section-elements': AttributeInfo.QNamesAvt(),
        'indent': AttributeInfo.YesNoAvt(),
        'media-type': AttributeInfo.StringAvt(),
    }

    def __init__(self, *args, **kwds):
        XsltElement.__init__(self, *args, **kwds)
        self._output_parameters = OutputParameters.OutputParameters()
        return

    def instantiate(self, context, processor):
        context.processorNss = self.namespaces
        context.currentInstruction = self

        # this uses attributes directly from self
        self._output_parameters.avtParse(self, context)

        processor.addHandler(self._output_parameters,
                             processor.writer.getStream())
        try:
            for child in self.children:
                child.instantiate(context, processor)
        finally:
            processor.removeHandler()

        return
Ejemplo n.º 2
0
class DocumentElement(XsltElement):
    """
    For the basic specification, see:
    http://www.exslt.org/exsl/elements/document/index.html
    The only URI scheme supported by 4Suite currently is 'file:'
    Security note:
    As a precaution, if you try to overwrite an existing file, it will be
    saved to a temporary file (there will be a warning with the file name).
    If this this precaution fails, the instruction will abort.  You can
    override this precaution, always allowing the function to overwrite
    a document by using the f:overwrite-okay extension attribute.
    """

    content = ContentInfo.Template
    legalAttrs = {
        'href' : AttributeInfo.UriReferenceAvt(required=1),
        'method' : AttributeInfo.QNameAvt(),
        'version' : AttributeInfo.NMTokenAvt(),
        'encoding' : AttributeInfo.StringAvt(),
        'omit-xml-declaration' : AttributeInfo.YesNoAvt(),
        'standalone' : AttributeInfo.YesNoAvt(),
        'doctype-public' : AttributeInfo.StringAvt(),
        'doctype-system' : AttributeInfo.StringAvt(),
        'cdata-section-elements' : AttributeInfo.QNamesAvt(),
        'indent' : AttributeInfo.YesNoAvt(),
        'media-type' : AttributeInfo.StringAvt(),
        'f:overwrite-safeguard' : AttributeInfo.YesNoAvt(
            default='no',
            description='Whether or not to make backup copies of any file before it\'s overwritten.'),
        'f:utfbom' : AttributeInfo.YesNoAvt(
            default='no',
            description='Whether to force output of a byte order mark (BOM).  Usually used to generate a UTF-8 BOM.  Do not use this unless you\'re sure you know what you\'re doing'),
        }

    doesSetup = True

    def setup(self):
        self._output_parameters = OutputParameters.OutputParameters()
        return

    def instantiate(self, context, processor):
        context.processorNss = self.namespaces
        context.currentInstruction = self

        # this uses attributes directly from self
        self._output_parameters.avtParse(self, context)
        href = self._href.evaluate(context)

        if Uri.IsAbsolute(href):
            uri = href
        else:
            try:
                uri = Uri.Absolutize(href,
                  Uri.OsPathToUri(processor.writer.getStream().name))
            except Exception, e:
                raise XsltRuntimeException(
                        ExsltError.NO_EXSLTDOCUMENT_BASE_URI,
                        context.currentInstruction, href)
        path = Uri.UriToOsPath(uri)
        if (self.attributes.get((FT_EXT_NAMESPACE, 'overwrite-safeguard') == u'yes')
            and os.access(path, os.F_OK)):
            # Kick in the safety measures
            # FIXME: Security hole.  Switch to the mkstemp as soon as we
            #   mandate Python 2.3 mnimum
            savefile = tempfile.mktemp('', os.path.split(path)[-1]+'-')
            processor.warn("The file you are trying to create with"
                           " exsl:document already exists.  As a safety"
                           " measure it will be copied to a temporary file"
                           " '%s'." % savefile)  #FIXME: l10n
            try:
                shutil.copyfile(path, savefile)
            except:
                raise XsltRuntimeException(
                    ExsltError.ABORTED_EXSLDOCUMENT_OVERWRITE,
                    context.currentInstruction, path, savefile)
        try:
            stream = open(path, 'w')
        except IOError:
            dirname = os.path.dirname(path)
            # Should we also check base path writability with os.W_OK?
            if not os.access(dirname, os.F_OK):
                os.makedirs(dirname)
                stream = open(path, 'w')
            else:
                raise

        processor.addHandler(self._output_parameters, stream)
        try:
            self.processChildren(context, processor)
        finally:
            processor.removeHandler()
            stream.close()
        return