Annotation of parser3/src/classes/xnode.C, revision 1.9

1.1       parser      1: /** @file
                      2:        Parser: @b dom parser class.
                      3: 
                      4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      5:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      6: 
1.9     ! parser      7:        $Id: xnode.C,v 1.8 2001/10/16 14:44:40 parser Exp $
1.1       parser      8: */
                      9: #include "classes.h"
                     10: #ifdef XML
                     11: 
                     12: #include "pa_request.h"
                     13: #include "pa_vxnode.h"
                     14: 
                     15: #include "xnode.h"
                     16: 
                     17: #include <util/XMLString.hpp>
                     18: #include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
                     19: #include <XPath/XPathEvaluator.hpp>
                     20: #include <XPath/NodeRefList.hpp>
1.6       parser     21: #include <XalanDOM/XalanElement.hpp>
                     22: #include <XalanDOM/XalanAttr.hpp>
                     23: #include <XalanDOM/XalanNodeList.hpp>
1.1       parser     24: 
                     25: // defines
                     26: 
                     27: #define XNODE_CLASS_NAME "xnode"
                     28: 
1.6       parser     29: // helpers
                     30: 
                     31: XalanNode& as_node(Pool& pool, const String& method_name, MethodParams *params, 
                     32:                                                int index, const char *msg) {
                     33:        Value& value=params->as_no_junction(index, msg);
                     34:        if(strcmp(value.type(), VXNODE_TYPE)!=0)
                     35:                PTHROW(0, 0,
                     36:                        &method_name,
                     37:                        msg);
                     38: 
                     39:        VXnode& vnode=*static_cast<VXnode *>(&value);
                     40:        return vnode.get_node(pool, &method_name);
                     41: }
                     42: 
                     43: // helpers
                     44: 
                     45: XalanAttr& as_attr(Pool& pool, const String& method_name, MethodParams *params, 
                     46:                                                int index, const char *msg) {
                     47:        XalanNode& node=as_node(pool, method_name, params, index, msg);
                     48: 
                     49:        if(node.getNodeType()!=XalanNode::ATTRIBUTE_NODE)
                     50:                PTHROW(0, 0, 
                     51:                        &method_name,
                     52:                        msg);
                     53: 
                     54:        return *reinterpret_cast<XalanAttr *>(&node);
                     55: }
1.1       parser     56: 
                     57: // methods
                     58: 
1.6       parser     59: // DOM1 node
                     60: 
                     61: // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
                     62: static void _insertBefore(Request& r, const String& method_name, MethodParams *params) {
                     63:        Pool& pool=r.pool();
                     64:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                     65:        XalanNode& node=vnode.get_node(pool, &method_name);
                     66: 
                     67:        XalanNode& newChild=as_node(pool, method_name, params, 0, "newChild must be node");
                     68:        XalanNode& refChild=as_node(pool, method_name, params, 1, "refChild must be node");
                     69:        
                     70:        try {
                     71:                node.insertBefore(&newChild, &refChild);
                     72:        } catch(const XalanDOMException& e)     {
                     73:                pool.exception()._throw(pool, &method_name, e);
                     74:        }
                     75: }
                     76: 
                     77: // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
                     78: static void _replaceChild(Request& r, const String& method_name, MethodParams *params) {
                     79:        Pool& pool=r.pool();
                     80:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                     81:        XalanNode& node=vnode.get_node(pool, &method_name);
                     82: 
                     83:        XalanNode& newChild=as_node(pool, method_name, params, 0, "newChild must be node");
                     84:        XalanNode& refChild=as_node(pool, method_name, params, 1, "refChild must be node");
                     85:        
                     86:        try {
                     87:                node.replaceChild(&newChild, &refChild);
                     88:        } catch(const XalanDOMException& e)     {
                     89:                pool.exception()._throw(pool, &method_name, e);
                     90:        }
                     91: }
                     92: 
                     93: // Node removeChild(in Node oldChild) raises(DOMException);
                     94: static void _removeChild(Request& r, const String& method_name, MethodParams *params) {
                     95:        Pool& pool=r.pool();
                     96:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                     97:        XalanNode& node=vnode.get_node(pool, &method_name);
                     98: 
                     99:        XalanNode& oldChild=as_node(pool, method_name, params, 0, "oldChild must be node");
                    100:        
                    101:        try {
                    102:                node.removeChild(&oldChild);
                    103:        } catch(const XalanDOMException& e)     {
                    104:                pool.exception()._throw(pool, &method_name, e);
                    105:        }
                    106: }
                    107: 
                    108: // Node appendChild(in Node newChild) raises(DOMException);
                    109: static void _appendChild(Request& r, const String& method_name, MethodParams *params) {
                    110:        Pool& pool=r.pool();
                    111:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    112:        XalanNode& node=vnode.get_node(pool, &method_name);
                    113: 
                    114:        XalanNode& newChild=as_node(pool, method_name, params, 0, "newChild must be node");
                    115:        
                    116:        try {
                    117:                node.appendChild(&newChild);
                    118:        } catch(const XalanDOMException& e)     {
                    119:                pool.exception()._throw(pool, &method_name, e);
                    120:        }
                    121: }
                    122: 
                    123: // boolean hasChildNodes();
                    124: static void _hasChildNodes(Request& r, const String& method_name, MethodParams *) {
                    125:        Pool& pool=r.pool();
                    126:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    127:        XalanNode& node=vnode.get_node(pool, &method_name);
                    128: 
                    129:        // write out result
                    130:        VBool& result=*new(pool) VBool(pool, node.hasChildNodes());
                    131:        result.set_name(method_name);
                    132:        r.write_no_lang(result);
                    133: }
                    134: 
                    135: // Node cloneNode(in boolean deep);
                    136: /// @test 1. who frees it up? 2. ownerDocument=?
                    137: static void _cloneNode(Request& r, const String& method_name, MethodParams *params) {
                    138:        Pool& pool=r.pool();
                    139:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    140:        XalanNode& node=vnode.get_node(pool, &method_name);
                    141: 
                    142:        bool deep=params->as_bool(0, "deep must be bool", r);
                    143: 
                    144:        // write out result
                    145:        VXnode& result=*new(pool) VXnode(pool, node.cloneNode(deep));
                    146:        result.set_name(method_name);
                    147:        r.write_no_lang(result);
                    148: }
                    149: 
                    150: // DOM1 element
                    151: 
                    152: XalanElement& get_self_element(Request& r, const String& method_name) {
                    153:        Pool& pool=r.pool();
                    154:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    155:        XalanNode& node=vnode.get_node(pool, &method_name);
                    156: 
                    157:        if(node.getNodeType()!=XalanNode::ELEMENT_NODE)
                    158:                PTHROW(0, 0, 
                    159:                        &method_name,
                    160:                        "method can be called on node of ELEMENT type");
                    161: 
                    162:        return *reinterpret_cast<XalanElement *>(&node);
                    163: }
                    164: 
                    165: // DOMString getAttribute(in DOMString name);
                    166: static void _getAttribute(Request& r, const String& method_name, MethodParams *params) {
                    167:        Pool& pool=r.pool();
                    168:        XalanElement& element=get_self_element(r, method_name);
1.9     ! parser    169:        const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
1.6       parser    170: 
                    171:        const XalanDOMString& attribute_value=element.getAttribute(XalanDOMString(name));
                    172:        // write out result
                    173:        r.write_no_lang(*new(pool) VString(pool.transcode(attribute_value)));
                    174: }
                    175: 
                    176: // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
                    177: static void _setAttribute(Request& r, const String& method_name, MethodParams *params) {
                    178:        Pool& pool=r.pool();
                    179:        XalanElement& element=get_self_element(r, method_name);
1.9     ! parser    180:        const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
        !           181:        const char *attribute_value=params->as_string(1, "value must be string").cstr(String::UL_XML);
1.6       parser    182: 
                    183:        try {
                    184:                element.setAttribute(
                    185:                        XalanDOMString(name), 
                    186:                        XalanDOMString(attribute_value));
                    187:        } catch(const XalanDOMException& e)     {
                    188:                pool.exception()._throw(pool, &method_name, e);
                    189:        }
                    190: }
                    191: 
                    192: // void removeAttribute(in DOMString name) raises(DOMException);
                    193: static void _removeAttribute(Request& r, const String& method_name, MethodParams *params) {
                    194:        Pool& pool=r.pool();
                    195:        XalanElement& element=get_self_element(r, method_name);
1.9     ! parser    196:        const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
1.6       parser    197: 
                    198:        try {
                    199:                element.removeAttribute(XalanDOMString(name));
                    200:        } catch(const XalanDOMException& e)     {
                    201:                pool.exception()._throw(pool, &method_name, e);
                    202:        }
                    203: }
                    204: 
                    205: // Attr getAttributeNode(in DOMString name);
                    206: static void _getAttributeNode(Request& r, const String& method_name, MethodParams *params) {
                    207:        Pool& pool=r.pool();
                    208:        XalanElement& element=get_self_element(r, method_name);
1.9     ! parser    209:        const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
1.6       parser    210: 
                    211:        if(XalanAttr *attr=element.getAttributeNode(XalanDOMString(name))) {
                    212:                // write out result
                    213:                VXnode& result=*new(pool) VXnode(pool, attr);
                    214:                r.write_no_lang(result);
                    215:        }
                    216: }      
                    217: 
                    218: // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
                    219: static void _setAttributeNode(Request& r, const String& method_name, MethodParams *params) {
                    220:        Pool& pool=r.pool();
                    221:        XalanElement& element=get_self_element(r, method_name);
                    222:        XalanAttr& newAttr=as_attr(pool, method_name, params, 0, "newAttr must be ATTRIBUTE node");
                    223: 
                    224:        try {
                    225:                if(XalanAttr *returnAttr=element.setAttributeNode(&newAttr)) {
                    226:                        // write out result
                    227:                        VXnode& result=*new(pool) VXnode(pool, returnAttr);
                    228:                        r.write_no_lang(result);
                    229:                }
                    230:        } catch(const XalanDOMException& e)     {
                    231:                pool.exception()._throw(pool, &method_name, e);
                    232:        }
                    233: }      
                    234: 
                    235: // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
                    236: static void _removeAttributeNode(Request& r, const String& method_name, MethodParams *params) {
                    237:        Pool& pool=r.pool();
                    238:        XalanElement& element=get_self_element(r, method_name);
                    239:        XalanAttr& oldAttr=as_attr(pool, method_name, params, 0, "oldAttr must be ATTRIBUTE node");
                    240: 
                    241:        try {
1.8       parser    242:                /*XalanAttr *returnAttr*/element.removeAttributeNode(&oldAttr);
1.6       parser    243:        } catch(const XalanDOMException& e)     {
                    244:                pool.exception()._throw(pool, &method_name, e);
                    245:        }
                    246: }      
                    247: 
                    248: // NodeList getElementsByTagName(in DOMString name);
                    249: static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) {
                    250:        Pool& pool=r.pool();
                    251:        XalanElement& element=get_self_element(r, method_name);
                    252: 
1.9     ! parser    253:        const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
1.6       parser    254: 
                    255:        VHash& result=*new(pool) VHash(pool);
                    256:        if(const XalanNodeList *nodes=
                    257:                element.getElementsByTagName(XalanDOMString(name))) {
                    258:                for(int i=0; i<nodes->getLength(); i++) {
                    259:                        String& skey=*new(pool) String(pool);
                    260:                        {
                    261:                                char *buf=(char *)pool.malloc(MAX_NUMBER);
                    262:                                snprintf(buf, MAX_NUMBER, "%d", i);
                    263:                                skey << buf;
                    264:                        }
                    265: 
                    266:                        result.hash().put(skey, new(pool) VXnode(pool, nodes->item(i)));
                    267:                }
                    268:        }
                    269: 
                    270:        // write out result
                    271:        r.write_no_lang(result);
                    272: }
                    273: 
                    274: // void normalize();
                    275: static void _normalize(Request& r, const String& method_name, MethodParams *) {
                    276:        XalanElement& element=get_self_element(r, method_name);
                    277: 
                    278:        element.normalize();
                    279: }
                    280: 
                    281: 
1.1       parser    282: static void _select(Request& r, const String& method_name, MethodParams *params) {
                    283: //     _asm int 3;
                    284:        Pool& pool=r.pool();
                    285:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    286: 
                    287:        // expression
1.9     ! parser    288:        const String& expression=params->as_string(0, "expression must be string");
1.1       parser    289:        const char *expression_cstr=expression.cstr(String::UL_AS_IS);
                    290:        XalanDOMString dstring(expression_cstr);
                    291:        const XalanDOMChar *expression_dcstr=dstring.c_str();
                    292: 
                    293:        XPathEvaluator evaluator;
                    294:        // We'll use these to parse the XML file.
                    295:        XalanSourceTreeDOMSupport dom_support;
                    296: 
                    297:        try {
                    298:                NodeRefList list=evaluator.selectNodeList(dom_support, 
                    299:                        &vnode.get_node(pool, &method_name), 
                    300:                        expression_dcstr);
                    301: 
                    302:                VHash& result=*new(pool) VHash(pool);
                    303:                for(int i=0; i<list.getLength(); i++) {
                    304:                        String& skey=*new(pool) String(pool);
                    305:                        {
                    306:                                char *buf=(char *)pool.malloc(MAX_NUMBER);
                    307:                                snprintf(buf, MAX_NUMBER, "%d", i);
                    308:                                skey << buf;
                    309:                        }
                    310: 
                    311:                        result.hash().put(skey, new(pool) VXnode(pool, list.item(i)));
                    312:                }
                    313:                result.set_name(method_name);
                    314:                r.write_no_lang(result);
                    315:        } catch(const XSLException& e) {
1.4       parser    316:                pool.exception()._throw(pool, &expression, e);
1.1       parser    317:        }
                    318: }
                    319: 
1.9     ! parser    320: static void _selectSingle(Request& r, const String& method_name, MethodParams *params) {
1.1       parser    321: //     _asm int 3;
                    322:        Pool& pool=r.pool();
                    323:        VXnode& vnode=*static_cast<VXnode *>(r.self);
                    324: 
                    325:        // expression
1.9     ! parser    326:        const String& expression=params->as_string(0, "expression must be string");
1.1       parser    327:        const char *expression_cstr=expression.cstr(String::UL_AS_IS);
                    328:        XalanDOMString dstring(expression_cstr);
                    329:        const XalanDOMChar *expression_dcstr=dstring.c_str();
                    330: 
                    331:        XPathEvaluator evaluator;
                    332:        // Initialize the XalanSourceTree subsystem...
                    333: //     XalanSourceTreeInit             theSourceTreeInit;
                    334:        // We'll use these to parse the XML file.
                    335:        XalanSourceTreeDOMSupport dom_support;
                    336: 
                    337:        try {
                    338:                 if(XalanNode *node=evaluator.selectSingleNode(dom_support, 
                    339:                        &vnode.get_node(pool, &method_name), 
                    340:                        expression_dcstr)) {
                    341: 
                    342:                        VXnode& result=*new(pool) VXnode(pool, node);
                    343:                        result.set_name(method_name);
                    344:                        r.write_no_lang(result);
                    345:                }
                    346:        } catch(const XSLException& e) {
1.4       parser    347:                pool.exception()._throw(pool, &expression, e);
1.1       parser    348:        }
                    349: }
                    350: 
                    351: // constructor
                    352: 
1.2       parser    353: MXnode::MXnode(Pool& apool) : Methoded(apool), 
                    354:        consts(apool) {
1.1       parser    355:        set_name(*NEW String(pool(), XNODE_CLASS_NAME));
1.6       parser    356: 
                    357:        /// DOM1 node
                    358: 
                    359:        // Node insertBefore(in Node newChild,in Node refChild) raises(DOMException);
                    360:        add_native_method("insertBefore", Method::CT_DYNAMIC, _insertBefore, 2, 2);
                    361:        // Node replaceChild(in Node newChild,in Node oldChild) raises(DOMException);
                    362:        add_native_method("replaceChild", Method::CT_DYNAMIC, _replaceChild, 2, 2);
                    363:        // Node removeChild(in Node oldChild) raises(DOMException);
                    364:        add_native_method("removeChild", Method::CT_DYNAMIC, _removeChild, 1, 1);
                    365:        // Node appendChild(in Node newChild) raises(DOMException);
                    366:        add_native_method("appendChild", Method::CT_DYNAMIC, _appendChild, 1, 1);
                    367:        // boolean hasChildNodes();
                    368:        add_native_method("hasChildNodes", Method::CT_DYNAMIC, _hasChildNodes, 0, 0);
                    369:        // Node cloneNode(in boolean deep);
                    370:        add_native_method("cloneNode", Method::CT_DYNAMIC, _cloneNode, 1, 1);
                    371: 
                    372:        /// DOM1 element
                    373: 
                    374:        // DOMString getAttribute(in DOMString name);
                    375:        add_native_method("getAttribute", Method::CT_DYNAMIC, _getAttribute, 1, 1);
                    376:        // void setAttribute(in DOMString name, in DOMString value) raises(DOMException);
                    377:        add_native_method("setAttribute", Method::CT_DYNAMIC, _setAttribute, 2, 2);
                    378:        // void removeAttribute(in DOMString name) raises(DOMException);
                    379:        add_native_method("removeAttribute", Method::CT_DYNAMIC, _removeAttribute, 1, 1);
                    380:        // Attr getAttributeNode(in DOMString name);
                    381:        add_native_method("getAttributeNode", Method::CT_DYNAMIC, _getAttributeNode, 1, 1);
                    382:        // Attr setAttributeNode(in Attr newAttr) raises(DOMException);
                    383:        add_native_method("setAttributeNode", Method::CT_DYNAMIC, _setAttributeNode, 1, 1);
                    384:        // Attr removeAttributeNode(in Attr oldAttr) raises(DOMException);
                    385:        add_native_method("removeAttributeNode", Method::CT_DYNAMIC, _removeAttributeNode, 1, 1);
                    386:        // NodeList getElementsByTagName(in DOMString name);
                    387:        add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
                    388:        // void normalize();
                    389:        add_native_method("normalize", Method::CT_DYNAMIC, _normalize, 0, 0);
                    390: 
                    391:        /// parser
1.1       parser    392: 
                    393:        // ^node.select[/some/xpath/query] = hash $.#[dnode]
                    394:        add_native_method("select", Method::CT_DYNAMIC, _select, 1, 1);
                    395: 
1.5       parser    396:        // ^node.selectSingle[/some/xpath/query] = first dnode
1.9     ! parser    397:        add_native_method("selectSingle", Method::CT_DYNAMIC, _selectSingle, 1, 1);
1.2       parser    398: 
                    399:        // consts
                    400: 
                    401: #define CONST(name, value) \
                    402:        consts.put(*new(pool()) String(pool(), #name), new(pool()) VInt(pool(), value))
                    403: 
                    404:        CONST(ELEMENT_NODE, 1);
                    405:     CONST(ATTRIBUTE_NODE,  2);
                    406:     CONST(TEXT_NODE,  3);
                    407:     CONST(CDATA_SECTION_NODE,  4);
                    408:     CONST(ENTITY_REFERENCE_NODE,  5);
                    409:     CONST(ENTITY_NODE,  6);
                    410:     CONST(PROCESSING_INSTRUCTION_NODE,  7);
                    411:     CONST(COMMENT_NODE,  8);
                    412:     CONST(DOCUMENT_NODE,  9);
                    413:     CONST(DOCUMENT_TYPE_NODE,  10);
                    414:     CONST(DOCUMENT_FRAGMENT_NODE,  11);
                    415:     CONST(NOTATION_NODE,  12);
1.1       parser    416: 
                    417: }
1.3       parser    418: 
1.1       parser    419: // global variable
                    420: 
                    421: Methoded *Xnode_class;
                    422: 
                    423: #endif
                    424: 
                    425: // creator
                    426: Methoded *MXnode_create(Pool& pool) {
                    427:        return 
                    428: #ifdef XML
                    429:                Xnode_class=new(pool) MXnode(pool)
                    430: #else
                    431:                0
                    432: #endif
                    433:                ;
                    434: }

E-mail: