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