Annotation of parser3/src/classes/dom.C, revision 1.10

1.2       parser      1: /** @file
                      2:        Parser: @b dom parser class.
                      3: 
                      4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      5: 
                      6:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      7: */
1.10    ! parser      8: static const char *RCSId="$Id: dom.C,v 1.9 2001/09/10 11:17:41 parser Exp $"; 
1.2       parser      9: 
                     10: #if _MSC_VER
                     11: #      pragma warning(disable:4291)   // disable warning 
                     12: //     "no matching operator delete found; memory will not be freed if initialization throws an exception
                     13: #endif
                     14: 
                     15: #include "classes.h"
                     16: #include "pa_request.h"
                     17: #include "pa_vdom.h"
1.9       parser     18: #include "pa_vfile.h"
1.2       parser     19: 
                     20: #include <Include/PlatformDefinitions.hpp>
                     21: #include <util/PlatformUtils.hpp>
1.5       parser     22: #include <util/XMLString.hpp>
1.2       parser     23: #include <XalanTransformer/XalanTransformer.hpp>
1.4       parser     24: #include <XalanTransformer/XalanParsedSource.hpp>
1.10    ! parser     25: #include <XalanTransformer/XercesDOMParsedSource.hpp>
1.4       parser     26: #include <PlatformSupport/XalanFileOutputStream.hpp>
                     27: #include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>
1.6       parser     28: #include <PlatformSupport/DOMStringPrintWriter.hpp>
1.4       parser     29: #include <XMLSupport/FormatterToXML.hpp>
                     30: #include <XMLSupport/FormatterTreeWalker.hpp>
1.10    ! parser     31: #include <XercesParserLiaison/XercesDOMSupport.hpp>
        !            32: #include <XercesParserLiaison/XercesParserLiaison.hpp>
1.6       parser     33: 
1.2       parser     34: // defines
                     35: 
1.4       parser     36: #define DOM_CLASS_NAME "dom"
1.2       parser     37: 
                     38: // class
                     39: 
                     40: class MDom : public Methoded {
                     41: public: // VStateless_class
1.10    ! parser     42:        Value *create_new_value(Pool& pool) { return new(pool) VDom(pool, 0); }
1.2       parser     43: 
                     44: public:
                     45:        MDom(Pool& pool);
                     46: 
                     47: public: // Methoded
                     48:        bool used_directly() { return true; }
                     49: };
                     50: 
                     51: // methods
                     52: 
                     53: static void _load(Request& r, const String& method_name, MethodParams *params) {
                     54:        Pool& pool=r.pool();
1.10    ! parser     55:        VDom& vDom=*static_cast<VDom *>(r.self);
1.2       parser     56: 
1.10    ! parser     57:        // filespec
1.2       parser     58:        const String& filename=params->as_string(0, "file name must not be code");
                     59:        const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
                     60:        
                     61:        XSLTInputSource inputSource(filespec);
                     62:        XalanParsedSource* parsedSource;
1.10    ! parser     63:        int error=vDom.get_transformer().parseSource(inputSource, parsedSource);
1.2       parser     64: 
                     65:        if(error)
                     66:                PTHROW(0, 0,
                     67:                        &filename,
1.10    ! parser     68:                        vDom.get_transformer().getLastError());
1.2       parser     69: 
                     70:        // replace any previous node value
1.10    ! parser     71:        vDom.set_document(parsedSource->getDocument());
1.2       parser     72: }
                     73: 
1.5       parser     74: const char *strX(const XalanDOMString& s) {
                     75:        return XMLString::transcode(s.c_str());
                     76: }
                     77: 
                     78: static void _throw(Pool& pool, const String *source, const XSLException& e) {
                     79:        if(e.getURI().empty())
                     80:                PTHROW(0, 0,
                     81:                        source,
                     82:                        "%s (%s)",
                     83:                                strX(e.getMessage()),  // message for exception
                     84:                                strX(e.getType()) // type of exception
                     85:                );
                     86:        else
                     87:                PTHROW(0, 0,
                     88:                        source,
                     89:                        "%s (%s) %s(%d:%d)'", 
                     90:                                strX(e.getMessage()),  // message for exception
                     91:                                strX(e.getType()), // type of exception
                     92:                                
                     93:                                strX(e.getURI()),  // URI for the associated document, if any
                     94:                                e.getLineNumber(),  // line number, or -1 if unknown
                     95:                                e.getColumnNumber() // column number, or -1 if unknown
                     96:                );
                     97: }
                     98: 
1.6       parser     99: class ParserStringOutputStream: public XalanOutputStream {
                    100: public:
                    101:        
1.7       parser    102:        explicit ParserStringOutputStream(String& astring) : fstring(astring) {}
                    103: 
                    104: protected: // XalanOutputStream
                    105: 
                    106:        virtual void writeData(const char *theBuffer, unsigned long theBufferLength) {
1.6       parser    107:                char *copy=(char *)fstring.malloc((size_t)theBufferLength);
                    108:                memcpy(copy, theBuffer, (size_t)theBufferLength);
                    109:                fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "dom", -1);
                    110:        }
                    111: 
1.7       parser    112:        virtual void doFlush() {}
1.6       parser    113: 
                    114: private:
                    115: 
                    116:        String& fstring;
                    117:        
                    118: };
                    119: 
                    120: 
1.3       parser    121: static void _save(Request& r, const String& method_name, MethodParams *params) {
                    122:        Pool& pool=r.pool();
1.10    ! parser    123:        VDom& vDom=*static_cast<VDom *>(r.self);
1.3       parser    124: 
1.7       parser    125:        // encoding
                    126:        const char *encoding=params->as_string(0, "encoding must not be code").cstr();
1.3       parser    127: 
                    128:        // filespec
1.7       parser    129:        const String& filename=params->as_string(1, "file name must not be code");
1.3       parser    130:        const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
                    131:        
1.10    ! parser    132:        XalanDocument *document=vDom.get_document();
        !           133:        if(!document)
1.4       parser    134:                PTHROW(0, 0,
                    135:                        &method_name,
                    136:                        "on empty document");
1.3       parser    137: 
1.5       parser    138:        try {
1.6       parser    139:                XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec)));
                    140:                XalanOutputStreamPrintWriter writer(stream);
1.7       parser    141:                FormatterToXML formatterListener(writer,
                    142:                        XalanDOMString(),  // version
                    143:                        true , // doIndent
                    144:                        4, // indent 
                    145:                        XalanDOMString(encoding, strlen(encoding))  // encoding
                    146:                );
1.6       parser    147:                FormatterTreeWalker treeWalker(formatterListener);
                    148:                treeWalker.traverse(document); // Walk the document and produce the XML...
                    149:        } catch(const XSLException& e) {
                    150:                _throw(pool, &method_name, e);
                    151:        }
                    152: }
                    153: 
                    154: static void _string(Request& r, const String& method_name, MethodParams *params) {
                    155:        Pool& pool=r.pool();
1.10    ! parser    156:        VDom& vDom=*static_cast<VDom *>(r.self);
1.6       parser    157: 
1.7       parser    158:        // encoding
                    159:        const char *encoding=params->as_string(0, "encoding must not be code").cstr();
                    160: 
1.10    ! parser    161:        XalanDocument *document=vDom.get_document();
        !           162:        if(!document)
1.6       parser    163:                PTHROW(0, 0,
                    164:                        &method_name,
                    165:                        "on empty document");
                    166: 
                    167:        try {
1.9       parser    168:                String parserString=*new(pool) String(pool);
                    169:                ParserStringOutputStream stream(parserString);
1.6       parser    170:                XalanOutputStreamPrintWriter writer(stream);
1.7       parser    171:                FormatterToXML formatterListener(writer,
                    172:                        XalanDOMString(),  // version
                    173:                        true , // doIndent
                    174:                        4, // indent 
                    175:                        XalanDOMString(encoding, strlen(encoding)),  // encoding
                    176:                        XalanDOMString(),  // mediaType
                    177:                        XalanDOMString(),  // doctypeSystem
                    178:                        XalanDOMString(),  // doctypePublic
                    179:                        false // xmlDecl 
                    180:                );
1.6       parser    181:                FormatterTreeWalker treeWalker(formatterListener);
                    182:                treeWalker.traverse(document); // Walk the document and produce the XML...
                    183: 
                    184:                // write out result
1.9       parser    185:                r.write_no_lang(parserString);
1.5       parser    186:        } catch(const XSLException& e) {
                    187:                _throw(pool, &method_name, e);
                    188:        }
1.3       parser    189: }
                    190: 
1.9       parser    191: 
                    192: static void _file(Request& r, const String& method_name, MethodParams *params) {
                    193:        Pool& pool=r.pool();
1.10    ! parser    194:        VDom& vDom=*static_cast<VDom *>(r.self);
1.9       parser    195: 
                    196:        // encoding
                    197:        const char *encoding=params->as_string(0, "encoding must not be code").cstr();
                    198: 
1.10    ! parser    199:        XalanDocument *document=vDom.get_document();
        !           200:        if(!document)
1.9       parser    201:                PTHROW(0, 0,
                    202:                        &method_name,
                    203:                        "on empty document");
                    204: 
                    205:        try {
                    206:                String& parserString=*new(pool) String(pool);
                    207:                ParserStringOutputStream stream(parserString);
                    208:                XalanOutputStreamPrintWriter writer(stream);
                    209:                FormatterToXML formatterListener(writer,
                    210:                        XalanDOMString(),  // version
                    211:                        true , // doIndent
                    212:                        4, // indent 
                    213:                        XalanDOMString(encoding, strlen(encoding))  // encoding
                    214:                );
                    215:                FormatterTreeWalker treeWalker(formatterListener);
                    216:                treeWalker.traverse(document); // Walk the document and produce the XML...
                    217: 
                    218:                // write out result
                    219:                VFile& vfile=*new(pool) VFile(pool);
                    220:                const char *cstr=parserString.cstr();
                    221:                vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*filename*/, new(pool) String(pool, "text/xml"));
                    222:                r.write_no_lang(vfile);
                    223:        } catch(const XSLException& e) {
                    224:                _throw(pool, &method_name, e);
                    225:        }
                    226: }
                    227: 
                    228: 
1.10    ! parser    229: static void _xslt(Request& r, const String& method_name, MethodParams *params) {
        !           230:        Pool& pool=r.pool();
        !           231:        VDom& vDom=*static_cast<VDom *>(r.self);
        !           232: 
        !           233:        // source
        !           234:        XalanDocument *source_document=vDom.get_document();
        !           235:        if(!source_document)
        !           236:                PTHROW(0, 0,
        !           237:                        &method_name,
        !           238:                        "on empty document");
        !           239: 
        !           240:        // stylesheet
        !           241:        const String& stylesheet_filename=params->as_string(0, "file name must not be code");
        !           242:        const char *stylesheet_filespec=r.absolute(stylesheet_filename).cstr(String::UL_FILE_NAME);
        !           243: 
        !           244:        // target
        !           245:        XercesDOMSupport domSupport;
        !           246:        XercesParserLiaison     parserLiaison(domSupport);
        !           247:        XalanDocument* target=parserLiaison.createDocument();
        !           248:        XSLTResultTarget domResultTarget(target);
        !           249: 
        !           250:        // transform
        !           251:        int error=vDom.get_transformer().transform(
        !           252:                source_document, stylesheet_filespec, domResultTarget);
        !           253:        if(error)
        !           254:                PTHROW(0, 0,
        !           255:                        &stylesheet_filename,
        !           256:                        vDom.get_transformer().getLastError());
        !           257: 
        !           258:        // write out result
        !           259:        r.write_no_lang(*new(pool) VDom(pool, target));
        !           260: }
        !           261: 
1.2       parser    262: // constructor
                    263: 
                    264: MDom::MDom(Pool& apool) : Methoded(apool) {
1.4       parser    265:        set_name(*NEW String(pool(), DOM_CLASS_NAME));
1.2       parser    266: 
1.3       parser    267:        // ^dom::load[some.xml]
1.2       parser    268:        add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
1.3       parser    269: 
1.9       parser    270:        // ^dom.save[encoding;some.xml]
1.8       parser    271:        add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2);
1.2       parser    272: 
1.9       parser    273:        // ^dom.string[encoding] <doc/>
1.7       parser    274:        add_native_method("string", Method::CT_DYNAMIC, _string, 1, 1);
1.9       parser    275: 
                    276:        // ^dom.file[encoding] file with "<doc/>"
                    277:        add_native_method("file", Method::CT_DYNAMIC, _file, 1, 1);
1.10    ! parser    278: 
        !           279:        // ^dom.xslt[stylesheet filename]
        !           280:        /// ^dom.xslt[stylesheet filename;params hash]
        !           281:        add_native_method("xslt", Method::CT_DYNAMIC, _xslt, 1, 1);
1.6       parser    282: 
1.2       parser    283: }
                    284: // global variable
                    285: 
                    286: Methoded *Dom_class;
                    287: 
                    288: // creator
                    289: 
                    290: Methoded *MDom_create(Pool& pool) {
                    291:        // Use the static initializers to initialize the Xalan-C++ and Xerces-C++ platforms. 
                    292:        // You must initialize Xerces-C++ once per process
                    293:        XMLPlatformUtils::Initialize();
                    294:        XalanTransformer::initialize();
                    295: 
                    296:        return Dom_class=new(pool) MDom(pool);
                    297: }

E-mail: