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
Ejemplo n.º 3
0
class SortElement(XsltElement):
    category = None
    content = ContentInfo.Empty
    legalAttrs = {
        'select' : AttributeInfo.StringExpression(default='.'),
        'lang' : AttributeInfo.NMTokenAvt(),
        # We don't support any additional data-types, hence no
        # AttributeInfo.QNameButNotNCName()
        'data-type' : AttributeInfo.ChoiceAvt(['text', 'number'],
                                              default='text'),
        'order' : AttributeInfo.ChoiceAvt(['ascending', 'descending'],
                                          default='ascending'),
        'case-order' : AttributeInfo.ChoiceAvt(['upper-first', 'lower-first']),
        }

    doesSetup = 1

    def setup(self):
        # optimize for constant AVT attribute values (i.e., no {})
        if self._data_type.isConstant() and self._order.isConstant() and \
           self._case_order.isConstant():
            self._comparer = self.makeComparer(self._order.evaluate(None),
                                               self._data_type.evaluate(None),
                                               self._case_order.evaluate(None),
                                               )
        else:
            self._comparer = None
        return

    def makeComparer(self, order, data_type, case_order):
        #if order not in ['ascending', 'descending']:
        #    raise XsltException(Error.ILLEGAL_SORT_ORDER_VALUE)
        #if data_type not in ['text', 'number']:
        #    raise XsltException(Error.ILLEGAL_SORT_DATA_TYPE_VALUE)
        #if case_order and case_order not in ['upper-first', 'lower-first']:
        #    raise XsltException(Error.ILLEGAL_SORT_CASE_ORDER_VALUE)

        if data_type == 'number':
            comparer = FloatCompare
        else:
            if case_order == 'lower-first':
                comparer = LowerFirstCompare
            elif case_order == 'upper-first':
                comparer = UpperFirstCompare
            else:
                # use default for this locale
                comparer = cmp

        if order == 'descending':
            comparer = Descending(comparer)

        return comparer

    def getComparer(self, context):
        if self._comparer: return self._comparer

        data_type = self._data_type.evaluate(context)
        order = self._order.evaluate(context)
        case_order = self._case_order and self._case_order.evaluate(context)
        return self.makeComparer(order, data_type, case_order)

    def evaluate(self, context):
        return Conversions.StringValue(self._select.evaluate(context))