Example #1
0
    def before_finalize(self):
        picket = cherrypy.response.body

        if not isinstance(picket, Picket): return

        stylesheet = self.default_stylesheet

        if picket.stylesheet:
            stylesheet = picket.stylesheet

        if stylesheet is None:
            # If a stylesheet was not set, then raise an error
            raise ValueError, "Missing XSLT stylesheet"

        extDir = cherrypy.config.get("picket.extensionDir")
        if extDir != self.extensionDir:
            self.extensionDir =extDir
            self.ext_functions, self.ext_elements = _getExtensions(self.extensionDir)

        try:
            processor = self.processorPool.get_processor(
                stylesheet, self.ext_functions, self.ext_elements)
            cherrypy.response.body = processor.run(
                DefaultFactory.fromString(picket.document,
                                          picket.uri),
                topLevelParams=picket.parameters)
            if self.default_content_type:
                cherrypy.response.headers['Content-Type'] = self.default_content_type
            if picket.content_type:
                cherrypy.response.headers['Content-Type'] = picket.content_type
        finally:
            self.processorPool.release_processor(stylesheet)
Example #2
0
        def produce_final_output(response, response_headers=response_headers):
            log = sys.stderr
            if not send_browser_xslt and environ[ACTIVE_FLAG]:
                use_pi = False
                if force_server_side and force_server_side != True:
                    #True is a special flag meaning "don't delegate to the browser but still check for XSLT PIs"
                    xslt = force_server_side
                else:
                    #Check for a Stylesheet PI
                    parser = sax.reader()
                    parser.setFeature(sax.FEATURE_GENERATOR, True)
                    handler = find_xslt_pis(parser)
                    pi_iter = parser.parse(inputsource(response))
                    try:
                        #Note: only grabs the first PI.  Consider whether we should handle multiple
                        xslt = pi_iter.next()
                    except StopIteration:
                        xslt = None
                    use_pi = True
                if xslt:
                    xslt = xslt.encode('utf-8')
                    result = StringIO()
                    #self.xslt_sources = environ.get(
                    #    'wsgixml.applyxslt.xslt_sources', {})
                    source = InputSource.DefaultFactory.fromString(
                        response, uri=get_request_url(environ))
                    params = {}
                    for ns in self.stock_xslt_params:
                        params.update(setup_xslt_params(ns, self.stock_xslt_params[ns]))
                    start = time.time()

                    '''
                        processor = self.processorPool.get_processor(
                            stylesheet, self.ext_functions, self.ext_elements)
                        cherrypy.response.body = processor.run(
                            DefaultFactory.fromString(picket.document,
                                                      picket.uri),
                            topLevelParams=picket.parameters)
                        if self.default_content_type:
                            cherrypy.response.headers['Content-Type'] = self.default_content_type
                        if picket.content_type:
                            cherrypy.response.headers['Content-Type'] = picket.content_type
                    finally:
                        self.processorPool.release_processor(stylesheet)
                        '''


                    if xslt in self.processor_cache:
                        processor = self.processor_cache[xslt]
                        #Any transform would have already been loaded
                        use_pi = False
                        print >> log, 'Using cached processor instance for transform', xslt
                    else:
                        print >> log, 'Creating new processor instance for transform', xslt
                        processor = Processor.Processor()
                        if self.ext_modules:
                            processor.registerExtensionModules(self.ext_modules)
                        if self.use_wsgi_env:
                            params.update(setup_xslt_params(WSGI_NS, environ))
                        #srcAsUri = OsPathToUri()
                        #if False:
                        if environ.has_key('paste.recursive.include'):
                            #paste's recursive facilities are available, to
                            #so we can get the XSLT with a middleware call
                            #rather than a full Web invocation
                            #print environ['paste.recursive.include']
                            xslt_resp = environ['paste.recursive.include'](xslt)
                            #FIXME: this should be relative to the XSLT, not XML
                            #print xslt_resp, xslt_resp.body
                            isrc = InputSource.DefaultFactory.fromString(
                                xslt_resp.body, get_request_url(environ))
                            processor.appendStylesheet(isrc)
                        else:
                            #We have to make a full Web call to get the XSLT.
                            #4Suite will do that for us in processing the PI
                            if not use_pi:
                                uri = Uri.Absolutize(xslt, get_request_url(environ))
                                isrc = InputSource.DefaultFactory.fromUri(uri)
                                processor.appendStylesheet(isrc)
                        self.processor_cache[xslt] = processor
                    processor.run(source, outputStream=result,
                                  ignorePis=not use_pi, topLevelParams=params)

                    #Strip content-length if present (needs to be
                    #recalculated by server)
                    #Also strip content-type, which will be replaced below
                    response_headers = [ (name, value)
                        for name, value in response_headers
                            if ( name.lower()
                                 not in ['content-length', 'content-type'])
                    ]
                    #Put in the updated content type
                    imt = processor.outputParams.mediaType
                    content = result.getvalue()
                    if environ.get(CACHEABLE_FLAG):
                        self.path_cache[path] = imt, content
                    response_headers.append(('content-type', imt))
                    start_response(status, response_headers, exc_info)
                    end = time.time()
                    print >> log, '%s: elapsed time: %0.3f\n'%(xslt, end-start)
                    #environ['wsgi.errors'].write('%s: elapsed time: %0.3f\n'%(xslt, end-start))
                    return content
                    
            #If it reaches this point, no XSLT was applied.
            return