123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696 |
- /*##############################################################################
- Copyright (C) 2011 HPCC Systems.
- All rights reserved. This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- ############################################################################## */
- #include "xalan_processor.ipp"
- #include "jencrypt.hpp"
- #include "jexcept.hpp"
- #include "xalanc/XPath/XObjectFactory.hpp"
- #include "xalanc/PlatformSupport/Writer.hpp"
- /*
- class StringBufferOStreamBuf : public std::basic_streambuf<char, std::char_traits<char> >
- {
- StringBuffer & _inputbuffer;
- typedef std::char_traits<char> _Tr;
- protected:
- virtual int overflow(int = _Tr::eof());
- public:
- StringBufferOStreamBuf(StringBuffer &_str);
- };
- StringBufferOStreamBuf::StringBufferOStreamBuf(StringBuffer &_str) : _inputbuffer(_str)
- {
- }
- int StringBufferOStreamBuf::overflow(int c)
- {
- if(c == _Tr::eof()) return _Tr::not_eof(c);
- _inputbuffer.append((char) c);
- return c;
- }
- class StringBufferOStream : public std::basic_ostream<char, std::char_traits<char> >
- {
- StringBufferOStreamBuf _streambuffer;
- public:
- StringBufferOStream(StringBuffer &buf)
- : _streambuffer(buf),
- std::basic_ostream<char, std::char_traits<char> >(&_streambuffer)
- { clear(); }
- };
- */
- //-------------------------------------------------
- XALAN_USING_XALAN(Writer)
- XALAN_USING_XALAN(XalanOutputStream)
- XALAN_USING_XALAN(XalanDOMChar)
- class ISocketOutputStream : public IInterface
- {
- public:
- virtual Writer* getWriter() = 0;
- };
- //XALAN_CPP_NAMESPACE_BEGIN
- class SocketOutputStream : public CInterface, public ISocketOutputStream, public Writer
- {
- private:
- ISocket *m_socket;
- public:
- IMPLEMENT_IINTERFACE;
- SocketOutputStream(ISocket *s);
- ~SocketOutputStream() { close(); }
- virtual Writer* getWriter() { return this; }
- // Close the stream
- virtual void close();
- // Flush the stream
- virtual void flush();
- // Get the stream associated with the writer...
- virtual XalanOutputStream* getStream();
- // Get the stream associated with the writer...
- virtual const XalanOutputStream* getStream() const;
- // Writes a string
- virtual void write(const char* s, size_t theOffset = 0, size_t theLength = ~0u);
- // Writes a string
- virtual void write(const XalanDOMChar* s, XalanDOMString::size_type theOffset=0,
- XalanDOMString::size_type theLength = XalanDOMString::npos);
- // Writes a character
- virtual void write(XalanDOMChar c);
- // Writes a string
- virtual void write(const XalanDOMString& s, XalanDOMString::size_type theOffset = 0,
- XalanDOMString::size_type theLength = XalanDOMString::npos);
- };
- SocketOutputStream::SocketOutputStream(ISocket* s)
- {
- m_socket = s;
- }
- void SocketOutputStream::close()
- {
- //fprintf(stderr,"close()\n");
- //m_socket->shutdown();
- //m_socket->close();
- }
- void SocketOutputStream::flush()
- {
- //fprintf(stderr,"flush()\n");
- }
- XalanOutputStream* SocketOutputStream::getStream()
- {
- fprintf(stderr, "Unsupported getStream()!");
- return NULL;
- }
- const XalanOutputStream* SocketOutputStream::getStream() const
- {
- fprintf(stderr, "Unsupported getStream()!");
- return NULL;
- }
- void SocketOutputStream::write(const char* s, size_t offset, size_t length)
- {
- //wprintf(stderr,TEXT("write(char*='%s',offset=%d,length=%d)\n"),s,offset,length);
- m_socket->write(s + offset, length);
- }
- //XalanDOMChar: utf-8 or wchar_t
- void SocketOutputStream::write(const XalanDOMChar* s, XalanDOMString::size_type offset,
- XalanDOMString::size_type length)
- {
- //printf(stderr,"write(DOMChar='%s',offset=%d,length=%d)\n",s,offset,length);
- m_socket->write((const char* )(s+offset), length * sizeof(XalanDOMChar));
- }
- void SocketOutputStream::write(XalanDOMChar c)
- {
- //printf(stderr, "write(%c)", c);
- m_socket->write((const char*)&c, sizeof(XalanDOMChar));
- }
- void SocketOutputStream::write(const XalanDOMString& s, XalanDOMString::size_type offset,
- XalanDOMString::size_type length)
- {
- //printf(stderr,"write(DOMString='%s',offset=%d,length=%s", s.c_str(), offset, length);
- m_socket->write((const char*)(s.c_str()+offset), length*sizeof(XalanDOMChar));
- }
- extern ISocketOutputStream* createSocketOutputStream(ISocket* s)
- {
- return new SocketOutputStream(s);
- }
- //-------------------------------------------------
- class XalanStringBufferOutputHandler
- {
- StringBuffer & _inputbuffer;
- public:
- XalanStringBufferOutputHandler(StringBuffer &_str) : _inputbuffer(_str)
- {
- }
- static unsigned long callback(const char *data, unsigned long len, void *ctx)
- {
- XalanStringBufferOutputHandler *self = (XalanStringBufferOutputHandler *) ctx;
- self->_inputbuffer.append(len, data);
- return len;
- }
- };
- //----------------------------------------------------------------------------
- // CExternalFunction
- //----------------------------------------------------------------------------
- XObjectPtr CExternalFunction::execute( XPathExecutionContext& executionContext,
- XalanNode* /* context */,
- const XObjectPtr arg1,
- const Locator* /* locator */) const
- {
- assert(arg1.null() == false);
- const XalanDOMString& arg = arg1->str();
- //convert XalanDOMString (implemented as unsigned short*) into StringBuffer
- StringBuffer sbInput;
- sbInput.ensureCapacity(arg.length()+1);
- size32_t len = arg.length();
- for (size32_t i=0; i < len; i++)
- sbInput.append( (char) arg[i]);
- StringBuffer sbOutput;
- try
- {
- (*m_userFunction)(sbOutput, sbInput.str(), m_pTransform);
- }
- catch (IException* e)
- {
- StringBuffer msg;
- e->errorMessage(msg);
- e->Release();
- }
- catch (...)
- {
- }
- XalanDOMString xdsOutput( sbOutput.str() );
- return executionContext.getXObjectFactory().createString( xdsOutput );
- }
- //----------------------------------------------------------------------------
- // CXslProcessor
- //----------------------------------------------------------------------------
- extern IXslProcessor* getXslProcessor()
- {
- static CXslProcessor s_pXslProcessor;
- return LINK(&s_pXslProcessor);
- }
- // Should be called only once per-process
- class XslProcessorInitializer
- {
- public:
- XslProcessorInitializer()
- {
- // Call the static initializer for Xerces.
- XMLPlatformUtils::Initialize();
- // Initialize Xalan.
- XalanTransformer::initialize();
- }
- ~XslProcessorInitializer()
- {
- // Terminate Xalan.
- XalanTransformer::terminate();
- // Call the static terminator for Xerces.
- XMLPlatformUtils::Terminate();
- }
- };
- CXslProcessor::CXslProcessor()
- {
- static XslProcessorInitializer initializer;
- m_cachetimeout = XSLT_DEFAULT_CACHETIMEOUT;
- }
- // Should be called only once per-process
- CXslProcessor::~CXslProcessor()
- {
- }
- IXslTransform *CXslProcessor::createXslTransform()
- {
- return new CXslTransform(inch.get());
- }
- int CXslProcessor::execute(IXslTransform *pITransform)
- {
- return ((CXslTransform*)pITransform)->transform();
- }
- void CXslProcessor::setCacheTimeout(int timeout)
- {
- m_cachetimeout = timeout;
- IXslCache* xslcache = getXslCache();
- if(xslcache)
- xslcache->setCacheTimeout(timeout);
- }
- int CXslProcessor::getCacheTimeout()
- {
- return m_cachetimeout;
- }
- //----------------------------------------------------------------------------
- // CXslTransform
- //----------------------------------------------------------------------------
- /*static*/ const char* CXslTransform::SEISINT_NAMESPACE = "http://seisint.com";
- CXslTransform::CXslTransform(IIncludeHandler* handler) : m_XalanTransformer()
- {
- m_ParsedSource = 0;
- m_resultTarget = 0;
- m_ostrstream = 0;
- m_sourceResolver = NULL;
- m_pUserData = NULL;
- #ifdef _WIN32
- m_normalizeLinefeed = true; //default for Xalan
- #endif
- if (handler)
- setIncludeHandler(handler);
- //set an external function to handle non-fatal XSL messages
- m_fnMessage.setown(createExternalFunction("message", message));
- setExternalFunction(SEISINT_NAMESPACE, m_fnMessage.get(), true);
- }
- CXslTransform::~CXslTransform()
- {
- setExternalFunction(SEISINT_NAMESPACE, m_fnMessage.get(), false);
- if(m_sourceResolver != NULL)
- delete m_sourceResolver;
- if (m_xslsource)
- m_xslsource->clearIncludeHandler();
- if(m_ParsedSource)
- {
- m_XalanTransformer.destroyParsedSource(m_ParsedSource);
- m_ParsedSource = NULL;
- }
- closeResultTarget();
- }
- bool CXslTransform::checkSanity()
- {
- return (m_xslsource && m_ParsedSource);
- }
- int CXslTransform::transform(StringBuffer &target)
- {
- if(!m_ParsedSource)
- throw MakeStringException(1, "[XML source not set]");
- else if(!m_xslsource)
- throw MakeStringException(2, "[XSL stylesheet not set]");
- XalanCompiledStylesheet* pCompiledStylesheet = NULL;
- pCompiledStylesheet = m_xslsource->getStylesheet();
- if (!pCompiledStylesheet)
- {
- DBGLOG("[failed to compile XSLT stylesheet]");
- throw MakeStringException(2, "[failed to compile XSLT stylesheet]");
- }
- int rc=0;
- m_sMessages.clear();
- try
- {
- XalanStringBufferOutputHandler output(target);
- rc = m_XalanTransformer.transform(*m_ParsedSource, pCompiledStylesheet,
- (void*)&output, (XalanOutputHandlerType)output.callback, (XalanFlushHandlerType)0);
- }
- catch(...)
- {
- StringBuffer estr("[Exception running XSLT stylesheet]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- if (rc < 0)
- {
- StringBuffer estr;
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- return rc;
- }
- int CXslTransform::transform()
- {
- if(!m_ParsedSource)
- throw MakeStringException(1, "[XML source not set for XSLT[");
- else if(!m_xslsource)
- throw MakeStringException(2, "[XSL stylesheet not set]");
- else if(!m_resultTarget)
- throw MakeStringException(2, "[XSLT target file/buffer not set]");
- XalanCompiledStylesheet* pCompiledStylesheet = NULL;
- pCompiledStylesheet = m_xslsource->getStylesheet();
- if (!pCompiledStylesheet)
- {
- DBGLOG("[failed to compile XSLT stylesheet]");
- throw MakeStringException(2, "[failed to compile XSLT stylesheet]");
- }
- int rc=0;
- m_sMessages.clear();
- try
- {
- rc = m_XalanTransformer.transform(*m_ParsedSource, pCompiledStylesheet, *m_resultTarget);
- }
- catch(...)
- {
- StringBuffer estr("[Exception running XSLT stylesheet]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- if (rc < 0)
- {
- StringBuffer estr;
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- return rc;
- }
- int CXslTransform::transform(ISocket* targetSocket)
- {
- if(!m_ParsedSource)
- throw MakeStringException(1, "[XML source not set for XSLT[");
- else if(!m_xslsource)
- throw MakeStringException(2, "[XSL stylesheet not set]");
- XalanCompiledStylesheet* pCompiledStylesheet = NULL;
- pCompiledStylesheet = m_xslsource->getStylesheet();
- if (!pCompiledStylesheet)
- {
- DBGLOG("[failed to compile XSLT stylesheet]");
- throw MakeStringException(2, "[failed to compile XSLT stylesheet]");
- }
- int rc=0;
- m_sMessages.clear();
- try
- {
- m_resultTarget = new XSLTResultTarget();
- Owned<ISocketOutputStream> stream = createSocketOutputStream(targetSocket);
- m_resultTarget->setCharacterStream(stream->getWriter());
- rc = m_XalanTransformer.transform(*m_ParsedSource, pCompiledStylesheet, *m_resultTarget);
- }
- catch(...)
- {
- StringBuffer estr("[Exception running XSLT stylesheet]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- if (rc < 0)
- {
- StringBuffer estr;
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- return rc;
- }
- int CXslTransform::setXmlSource(const char *pszFileName)
- {
- if(m_ParsedSource != NULL)
- {
- m_XalanTransformer.destroyParsedSource(m_ParsedSource);
- m_ParsedSource = NULL;
- }
- int theResult = 0;
- try
- {
- std::ifstream theXMLStream(pszFileName);
- const XSLTInputSource xmlinput(&theXMLStream);
- theResult = m_XalanTransformer.parseSource(xmlinput, (const XalanParsedSource*&)m_ParsedSource);
- }
- catch(...)
- {
- m_ParsedSource = NULL;
- StringBuffer estr("[Exception compiling xml]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- if (!m_ParsedSource)
- {
- StringBuffer estr("[failed to compile xml]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- return theResult;
- }
- int CXslTransform::setXmlSource(const char *pszBuffer, unsigned int nSize)
- {
- if(m_ParsedSource != NULL)
- {
- m_XalanTransformer.destroyParsedSource(m_ParsedSource);
- m_ParsedSource = NULL;
- }
- int theResult = 0;
- try
- {
- //std::istringstream theXMLStream(pszBuffer, nSize);
- std::istringstream theXMLStream(pszBuffer);
- const XSLTInputSource xmlinput(&theXMLStream);
- theResult = m_XalanTransformer.parseSource(xmlinput, (const XalanParsedSource*&)m_ParsedSource);
- }
- catch(...)
- {
- m_ParsedSource = NULL;
- StringBuffer estr("[Exception compiling xml]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- if (!m_ParsedSource)
- {
- StringBuffer estr("[failed to compile xml]");
- estr.appendf("[%s]", m_XalanTransformer.getLastError());
- DBGLOG("%s", estr.str());
- throw MakeStringException(2, "%s", estr.str());
- }
- return theResult;
- }
- int CXslTransform::loadXslFromFile(const char *pszFileName, const char *cacheId)
- {
- m_xslsource.setown(new CXslSource(pszFileName, m_sourceResolver?m_sourceResolver->getIncludeHandler():NULL, cacheId));
- return 0;
- }
- int CXslTransform::loadXslFromEmbedded(const char *path, const char *cacheId)
- {
- m_xslsource.setown(new CXslSource(m_sourceResolver?m_sourceResolver->getIncludeHandler():NULL, cacheId, path));
- return 0;
- }
- int CXslTransform::setXslSource(const char *pszBuffer, unsigned int nSize, const char *cacheId, const char *rootpath)
- {
- assertex(cacheId && *cacheId);
- m_xslsource.setown(new CXslSource(pszBuffer, nSize, m_sourceResolver?m_sourceResolver->getIncludeHandler():NULL, cacheId, rootpath));
- return 0;
- }
- int CXslTransform::setXslNoCache(const char *pszBuffer, unsigned int nSize, const char *rootpath)
- {
- m_xslsource.setown(new CXslSource(pszBuffer, nSize, m_sourceResolver?m_sourceResolver->getIncludeHandler():NULL, NULL, rootpath));
- return 0;
- }
- int CXslTransform::setResultTarget(const char *pszFileName)
- {
- closeResultTarget();
- try
- {
- m_resultTargetFile.clear().append(pszFileName);
- m_resultTarget = new XSLTResultTarget(XalanDOMString(pszFileName));
- }
- catch(...)
- {
- throw MakeStringException(1, "Exception opening file %s", pszFileName);
- }
- return 0;
- }
- int CXslTransform::setResultTarget(char *pszBuffer, unsigned int nSize)
- {
- closeResultTarget();
- // Our output target that uses an ostrstream that will use the buffer
- try
- {
- //m_ostrstream = new std::ostringstream(pszBuffer, nSize);
- m_ostrstream = new std::ostringstream(pszBuffer);
- m_resultTarget = new XSLTResultTarget(m_ostrstream);
- }
- catch(...)
- {
- throw MakeStringException(1, "Exception in setting character buffer as XSLT result target.");
- }
- return 0;
- }
- int CXslTransform::closeResultTarget()
- {
- if (m_resultTarget)
- {
- delete m_resultTarget;
- m_resultTarget = 0;
- }
- if(m_ostrstream)
- {
- delete m_ostrstream;
- m_ostrstream = 0;
- }
- return 0;
- }
- int CXslTransform::setParameter(const char *pszName, const char *pszExpression)
- {
- m_XalanTransformer.setStylesheetParam(XalanDOMString(pszName), XalanDOMString(pszExpression));
- return 0;
- }
- int CXslTransform::setStringParameter(const char *pszName, const char *pszString)
- {
- m_XalanTransformer.setStylesheetParam(XalanDOMString(pszName), XalanDOMString(StringBuffer("'").append(pszString).append("'").str()));
- return 0;
- }
- int CXslTransform::setIncludeHandler(IIncludeHandler* handler)
- {
- if(handler == NULL)
- {
- throw MakeStringException(-1, "From CXslTransform::setIncludeHandler: a NULL handler is passed in");
- }
- if(m_sourceResolver == NULL)
- {
- m_sourceResolver = new MemSourceResolver();
- }
- m_sourceResolver->setHandler(handler);
- m_XalanTransformer.setEntityResolver(m_sourceResolver);
- if(m_xslsource.get() != NULL)
- {
- m_xslsource->setIncludeHandler(handler);
- }
- return 0;
- }
- int CXslTransform::setExternalFunction(const char* pszNameSpace, IXslFunction* pXslFunction, bool set)
- {
- CXslFunction* pFn = (CXslFunction*) pXslFunction;
- if (pFn == NULL || pFn->get() == NULL)
- throw MakeStringException(-1, "Null pointer violation in CXslTransform::setExternalFunction.");
- XalanDOMString nameSpace(pszNameSpace);
- XalanDOMString functionName(pFn->getName());
- bool bAssigned = pFn->isAssigned();
- if (set && !bAssigned)
- m_XalanTransformer.installExternalFunction(nameSpace, functionName, *pFn->get());
- else
- {
- if (!set && bAssigned)
- m_XalanTransformer.uninstallExternalFunction(nameSpace, functionName);
- else
- throw MakeStringException(-1, "XSLT external function assignment error!");
- }
- pFn->setAssigned(set);
- return 0;
- }
- /*static*/
- void CXslTransform::message(StringBuffer& out, const char* in, IXslTransform* pTransform)
- {
- CXslTransform* pTrans = dynamic_cast<CXslTransform*>(pTransform);
- pTrans->m_sMessages.append(in).append('\n');
- }
|