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

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

E-mail: