xsec/transformers/TXFMXSL.cpp (108 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * XSEC * * TXFMXSL := Class that performs XPath transforms * * $Id$ * */ #include <xsec/dsig/DSIGConstants.hpp> #include <xsec/framework/XSECError.hpp> #include <xsec/transformers/TXFMXSL.hpp> #ifdef XSEC_HAVE_XSLT // Xerces #include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOMImplementation.hpp> #include <xercesc/dom/DOMImplementationLS.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/framework/MemBufInputSource.hpp> #include <xercesc/util/Janitor.hpp> XERCES_CPP_NAMESPACE_USE #include <iostream> #include <strstream> #include <fstream> XALAN_USING_XALAN(XSLTResultTarget) // Function used to output data to a safeBuffer extern "C" { typedef struct TransformXSLOutputHolderStruct { safeBuffer buffer; int offset; } TransformXSLOutputHolder; CallbackSizeType TransformXSLOutputFn(const char * s, CallbackSizeType sz, void * data) { TransformXSLOutputHolder * output = (TransformXSLOutputHolder *) data; output->buffer.sbMemcpyIn(output->offset, s, (int) sz); output->offset += (int) sz; output->buffer[output->offset] = '\0'; return sz; } } // ----------------------------------------------------------------------- // For expanding name spaces when necessary // ----------------------------------------------------------------------- bool TXFMXSL::nameSpacesExpanded(void) const { // NOTE : Do not check inputs as this has its own document return (mp_nse != NULL); } void TXFMXSL::expandNameSpaces(void) { if (mp_nse != NULL) return; // Already done if (docOut != NULL) { XSECnew(mp_nse, XSECNameSpaceExpander(docOut)); mp_nse->expandNameSpaces(); } } // ----------------------------------------------------------------------- // Transform functions // ----------------------------------------------------------------------- TXFMXSL::TXFMXSL(DOMDocument *doc) : TXFMBase(doc), xds(xpl) { // Zeroise all the pointers xd = NULL; } TXFMXSL::~TXFMXSL() { if (docOut != NULL) { if (mp_nse != NULL) { delete mp_nse; // Don't bother collapsing mp_nse = NULL; } docOut->release(); } } // Methods to set the inputs void TXFMXSL::setInput(TXFMBase *newInput) { input = newInput; if (newInput->getOutputType() != TXFMBase::BYTE_STREAM) { throw XSECException(XSECException::TransformInputOutputFail, "XSL requires DOM_NODES input type"); } // Should have a method to check if the input is a straight URL - if it is, just read the // URL name and create an XSLTInputSource with this as the input ID. int size = 0; int count = 0; unsigned char buf[512]; while ((count = input->readBytes((XMLByte *) buf, 512)) != 0) { sbInDoc.sbMemcpyIn(size, buf, count); size += count; } sbInDoc[size] = '\0'; } void TXFMXSL::evaluateStyleSheet(const safeBuffer &sbStyleSheet) { // Set up iostreams for input std::istrstream theXMLStream((char *) sbInDoc.rawBuffer(), (int) strlen((char *) sbInDoc.rawBuffer())); std::istrstream theXSLStream((char *) sbStyleSheet.rawBuffer(), (int) strlen((char *) sbStyleSheet.rawBuffer())); // Now resolve XalanTransformer xt; TransformXSLOutputHolder txoh; txoh.buffer.sbStrcpyIn(""); txoh.offset = 0; /*int res = */ xt.transform(&theXMLStream, &theXSLStream, (void *) & txoh, TransformXSLOutputFn); // Should check res // Now use xerces to "re parse" this back into a DOM_Nodes document XercesDOMParser * parser = new XercesDOMParser; Janitor<XercesDOMParser> j_parser(parser); parser->setDoNamespaces(true); parser->setCreateEntityReferenceNodes(true); parser->setLoadExternalDTD(false); parser->setDoSchema(true); SecurityManager securityManager; parser->setSecurityManager(&securityManager); // Create an input source MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) txoh.buffer.rawBuffer(), txoh.offset, "XSECMem"); Janitor<MemBufInputSource> j_memIS(memIS); int errorCount = 0; parser->parse(*memIS); errorCount = parser->getErrorCount(); if (errorCount > 0) throw XSECException(XSECException::XSLError, "Errors occurred when XSL result was parsed back to DOM_Nodes"); docOut = parser->adoptDocument(); // Janitors clean up } // Methods to get tranform output type and input requirement TXFMBase::ioType TXFMXSL::getInputType(void) const { return TXFMBase::DOM_NODES; } TXFMBase::ioType TXFMXSL::getOutputType(void) const { return TXFMBase::DOM_NODES; } TXFMBase::nodeType TXFMXSL::getNodeType(void) const { return TXFMBase::DOM_NODE_DOCUMENT; } // Methods to get output data unsigned int TXFMXSL::readBytes(XMLByte * const toFill, unsigned int maxToFill) { return 0; } DOMDocument * TXFMXSL::getDocument() const { return docOut; } #endif /* XSEC_HAVE_XSLT */