Annotation of parser3/src/classes/xdoc.C, revision 1.37
1.1 parser 1: /** @file
1.2 parser 2: Parser: @b xdoc parser class.
1.1 parser 3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
6:
1.37 ! paf 7: $Id: xdoc.C,v 1.36 2001/10/26 12:23:16 paf Exp $
1.1 parser 8: */
1.30 parser 9: #include "pa_types.h"
1.1 parser 10: #include "classes.h"
11: #ifdef XML
12:
13: #include "pa_request.h"
14: #include "pa_vxdoc.h"
1.32 parser 15: #include "pa_stylesheet_manager.h"
1.1 parser 16: #include "pa_stylesheet_connection.h"
17: #include "pa_vfile.h"
18: #include "xnode.h"
19:
20: #include <strstream>
21: #include <Include/PlatformDefinitions.hpp>
22: #include <util/PlatformUtils.hpp>
1.5 parser 23: #include <util/TransENameMap.hpp>
1.13 parser 24: #include "XalanTransformer2.hpp"
1.1 parser 25: #include <XalanTransformer/XalanParsedSource.hpp>
1.9 parser 26: # include <XalanTransformer/XalanDefaultParsedSource.hpp>
27: # include <XalanSourceTree/XalanSourceTreeDocument.hpp>
1.10 parser 28: # include <XalanSourceTree/XalanSourceTreeContentHandler.hpp>
29: # include <sax2/XMLReaderFactory.hpp>
1.1 parser 30: #include <XMLSupport/FormatterToXML.hpp>
31: #include <XMLSupport/FormatterToHTML.hpp>
32: #include <XMLSupport/FormatterToText.hpp>
33: #include <XMLSupport/FormatterTreeWalker.hpp>
34: #include <PlatformSupport/XalanFileOutputStream.hpp>
35: #include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>
36: #include <PlatformSupport/DOMStringPrintWriter.hpp>
1.2 parser 37: #include <XalanDOM/XalanElement.hpp>
38: #include <XalanDOM/XalanNodeList.hpp>
1.16 parser 39: #include <XalanDOM/XalanDocumentFragment.hpp>
40: #include <XalanDOM/XalanCDATASection.hpp>
41: #include <XalanDOM/XalanEntityReference.hpp>
1.30 parser 42: #include <dom/DOM_Document.hpp>
1.21 parser 43: #include <XercesParserLiaison/XercesDocumentBridge.hpp>
44: #include <XalanTransformer/XercesDOMParsedSource.hpp>
1.1 parser 45:
46: // defines
47:
48: #define XDOC_CLASS_NAME "xdoc"
49:
50: #define XDOC_OUTPUT_METHOD_OPTION_NAME "method"
51: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "xml"
52: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "html"
53: #define XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "text"
54:
55: #define XDOC_OUTPUT_ENCODING_OPTION_NAME "encoding"
56:
57: #define XDOC_OUTPUT_DEFAULT_INDENT 4
58:
59: // class
60:
61: class MXdoc : public MXnode {
62: public: // VStateless_class
1.28 parser 63: Value *create_new_value(Pool& pool) { return new(pool) VXdoc(pool, 0, false); }
1.1 parser 64:
65: public:
66: MXdoc(Pool& pool);
67:
68: public: // Methoded
69: bool used_directly() { return true; }
1.5 parser 70: void configure_admin(Request& r);
1.1 parser 71: };
72:
73: // methods
74:
1.16 parser 75: // Element createElement(in DOMString tagName) raises(DOMException);
76: static void _createElement(Request& r, const String& method_name, MethodParams *params) {
77: Pool& pool=r.pool();
78: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
79:
1.37 ! paf 80: Temp_lang temp_lang(r, String::UL_XML);
! 81: Value& tagName_code=params->as_junction(0, "tagName must be string");
! 82: const String& tagName=r.process(tagName_code).as_string();
1.16 parser 83:
84: try {
85: XalanNode *node=
86: vdoc.get_document(pool, &method_name).
1.30 parser 87: createElement(*pool.transcode(tagName));
1.16 parser 88: // write out result
1.31 parser 89: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 90: r.write_no_lang(result);
91: } catch(const XalanDOMException& e) {
1.32 parser 92: Exception::provide_source(pool, &method_name, e);
1.16 parser 93: }
94: }
95:
96: // DocumentFragment createDocumentFragment()
1.26 parser 97: static void _createDocumentFragment(Request& r, const String& method_name, MethodParams *) {
1.16 parser 98: Pool& pool=r.pool();
99: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
100:
101: XalanNode *node=
102: vdoc.get_document(pool, &method_name).
103: createDocumentFragment();
104: // write out result
1.31 parser 105: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 106: r.write_no_lang(result);
107: }
108:
109: // Text createTextNode(in DOMString data);
110: static void _createTextNode(Request& r, const String& method_name, MethodParams *params) {
111: Pool& pool=r.pool();
112: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
113:
1.37 ! paf 114: Temp_lang temp_lang(r, String::UL_XML);
! 115: Value& data_code=params->as_junction(0, "data must be string");
! 116: const String& data=r.process(data_code).as_string();
1.16 parser 117:
118: XalanNode *node=
119: vdoc.get_document(pool, &method_name).
1.30 parser 120: createTextNode(*pool.transcode(data));
1.16 parser 121: // write out result
1.31 parser 122: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 123: r.write_no_lang(result);
124: }
125:
126: // Comment createComment(in DOMString data)
127: static void _createComment(Request& r, const String& method_name, MethodParams *params) {
128: Pool& pool=r.pool();
129: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
130:
1.26 parser 131: const String& data=params->as_string(0, "data must be string");
1.16 parser 132:
133: XalanNode *node=
134: vdoc.get_document(pool, &method_name).
1.30 parser 135: createComment(*pool.transcode(data));
1.16 parser 136: // write out result
1.31 parser 137: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 138: r.write_no_lang(result);
139: }
140:
141: // CDATASection createCDATASection(in DOMString data) raises(DOMException);
142: static void _createCDATASection(Request& r, const String& method_name, MethodParams *params) {
143: Pool& pool=r.pool();
144: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
145:
1.26 parser 146: const String& data=params->as_string(0, "data must be string");
1.16 parser 147:
148: try {
149: XalanNode *node=
150: vdoc.get_document(pool, &method_name).
1.30 parser 151: createCDATASection(*pool.transcode(data));
1.16 parser 152: // write out result
1.31 parser 153: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 154: r.write_no_lang(result);
155: } catch(const XalanDOMException& e) {
1.32 parser 156: Exception::provide_source(pool, &method_name, e);
1.16 parser 157: }
158: }
159:
160: // ProcessingInstruction createProcessingInstruction(in DOMString target,in DOMString data) raises(DOMException);
161: static void _createProcessingInstruction(Request& r, const String& method_name, MethodParams *params) {
162: Pool& pool=r.pool();
163: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
164:
1.26 parser 165: const String& target=params->as_string(0, "data must be string");
166: const String& data=params->as_string(1, "data must be string");
1.16 parser 167:
168: try {
169: XalanNode *node=
170: vdoc.get_document(pool, &method_name).
1.30 parser 171: createProcessingInstruction(*pool.transcode(target), *pool.transcode(data));
1.16 parser 172: // write out result
1.31 parser 173: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 174: r.write_no_lang(result);
175: } catch(const XalanDOMException& e) {
1.32 parser 176: Exception::provide_source(pool, &method_name, e);
1.16 parser 177: }
178: }
179:
180: // Attr createAttribute(in DOMString name) raises(DOMException);
181: static void _createAttribute(Request& r, const String& method_name, MethodParams *params) {
182: Pool& pool=r.pool();
183: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
184:
1.26 parser 185: const String& name=params->as_string(0, "name must be string");
1.16 parser 186:
187: try {
188: XalanNode *node=
189: vdoc.get_document(pool, &method_name).
1.30 parser 190: createAttribute(*pool.transcode(name));
1.16 parser 191: // write out result
1.31 parser 192: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 193: r.write_no_lang(result);
194: } catch(const XalanDOMException& e) {
1.32 parser 195: Exception::provide_source(pool, &method_name, e);
1.16 parser 196: }
197: }
198: // EntityReference createEntityReference(in DOMString name) raises(DOMException);
199: static void _createEntityReference(Request& r, const String& method_name, MethodParams *params) {
200: Pool& pool=r.pool();
201: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
202:
1.26 parser 203: const String& name=params->as_string(0, "name must be string");
1.16 parser 204:
205: try {
206: XalanNode *node=
207: vdoc.get_document(pool, &method_name).
1.30 parser 208: createEntityReference(*pool.transcode(name));
1.16 parser 209: // write out result
1.31 parser 210: VXnode& result=*new(pool) VXnode(pool, node, false);
1.16 parser 211: r.write_no_lang(result);
212: } catch(const XalanDOMException& e) {
1.32 parser 213: Exception::provide_source(pool, &method_name, e);
1.16 parser 214: }
215: }
216:
217: /*
218: static void _getElementsByTagName(Request& r, const String& method_name, MethodParams *params) {
219: Pool& pool=r.pool();
220: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
221:
222: // tagname
1.20 parser 223: const char *name=params->as_string(0, "name must be string").cstr(String::UL_XML);
1.16 parser 224:
225: VHash& result=*new(pool) VHash(pool);
226: if(const XalanNodeList *nodes=
227: vdoc.get_document(pool, &method_name).getElementsByTagName(XalanDOMString(name))) {
228: for(int i=0; i<nodes->getLength(); i++) {
229: String& skey=*new(pool) String(pool);
230: {
231: char *buf=(char *)pool.malloc(MAX_NUMBER);
232: snprintf(buf, MAX_NUMBER, "%d", i);
233: skey << buf;
234: }
235:
236: result.hash().put(skey, new(pool) VXnode(pool, nodes->item(i)));
237: }
238: }
239:
240: // write out result
241: r.write_no_lang(result);
242: }
243:
244: static void _getElementsByTagNameNS(Request& r, const String& method_name, MethodParams *params) {
245: Pool& pool=r.pool();
246: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
247:
248: // namespaceURI;localName
1.20 parser 249: const char *namespaceURI=params->as_string(0, "namespaceURI must be string").cstr(String::UL_XML);
250: const char *localName=params->as_string(0, "localName must be string").cstr(String::UL_XML);
1.16 parser 251:
252: VHash& result=*new(pool) VHash(pool);
253: if(const XalanNodeList *nodes=
254: vdoc.get_document(pool, &method_name).getElementsByTagNameNS(
255: XalanDOMString(namespaceURI), XalanDOMString(localName))) {
256: for(int i=0; i<nodes->getLength(); i++) {
257: String& skey=*new(pool) String(pool);
258: {
259: char *buf=(char *)pool.malloc(MAX_NUMBER);
260: snprintf(buf, MAX_NUMBER, "%d", i);
261: skey << buf;
262: }
263:
264: result.hash().put(skey, new(pool) VXnode(pool, nodes->item(i)));
265: }
266: }
267:
268: // write out result
269: r.write_no_lang(result);
270: }
271: */
272:
273:
1.1 parser 274: class ParserStringXalanOutputStream: public XalanOutputStream {
275: public:
276:
277: explicit ParserStringXalanOutputStream(String& astring) : fstring(astring) {}
278:
279: protected: // XalanOutputStream
280:
281: virtual void writeData(const char *theBuffer, unsigned long theBufferLength) {
282: char *copy=(char *)fstring.malloc((size_t)theBufferLength);
283: memcpy(copy, theBuffer, (size_t)theBufferLength);
1.2 parser 284: fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "xdoc", 0);
1.1 parser 285: }
286:
287: virtual void doFlush() {}
288:
289: private:
290:
291: String& fstring;
292:
293: };
294:
1.9 parser 295: class XalanSourceTreeParserLiaison2: public XalanSourceTreeParserLiaison {
296: public:
1.16 parser 297: XalanSourceTreeParserLiaison2(XalanSourceTreeDOMSupport& theSupport) : XalanSourceTreeParserLiaison(theSupport),
1.9 parser 298: ferror_handler(new HandlerBase) {
299: }
300:
1.10 parser 301: XalanDocument*
302: parseXMLStream2(
1.16 parser 303: const InputSource& inputSource) {
1.10 parser 304: XalanSourceTreeContentHandler theContentHandler(createXalanSourceTreeDocument());
305: XalanAutoPtr<SAX2XMLReader> theReader(XMLReaderFactory::createXMLReader());
306: theReader->setContentHandler(&theContentHandler);
307: theReader->setDTDHandler(&theContentHandler);
308: theReader->setErrorHandler(ferror_handler); // disable stderr output
309: theReader->setLexicalHandler(&theContentHandler);
310: EntityResolver* const theResolver = getEntityResolver();
311: if (theResolver != 0) {
312: theReader->setEntityResolver(theResolver);
313: }
314: theReader->parse(inputSource);
315: return theContentHandler.getDocument();
316: }
317:
1.9 parser 318: ~XalanSourceTreeParserLiaison2() {
1.11 parser 319: delete ferror_handler;
1.9 parser 320: }
321: private:
322: ErrorHandler *ferror_handler;
323: };
324:
325: class XalanDefaultParsedSource2 : public XalanParsedSource
326: {
327: public:
328:
1.16 parser 329: XalanDefaultParsedSource2(const XSLTInputSource& theInputSource);
1.9 parser 330:
331: virtual XalanDocument*
332: getDocument() const;
333:
334: virtual XalanParsedSourceHelper*
335: createHelper() const;
336:
337: private:
338:
339: XalanSourceTreeDOMSupport m_domSupport;
340:
1.10 parser 341: XalanSourceTreeParserLiaison2 m_parserLiaison2;
1.9 parser 342:
343: XalanSourceTreeDocument* const m_parsedSource;
344: };
345:
1.16 parser 346: XalanDefaultParsedSource2::XalanDefaultParsedSource2(const XSLTInputSource& theInputSource):
1.9 parser 347: XalanParsedSource(),
348: m_domSupport(),
1.10 parser 349: m_parserLiaison2(m_domSupport),
350: m_parsedSource(m_parserLiaison2.mapDocument(m_parserLiaison2.parseXMLStream2(theInputSource)))
1.9 parser 351: {
352: assert(m_parsedSource != 0);
353:
1.10 parser 354: m_domSupport.setParserLiaison(&m_parserLiaison2);
1.9 parser 355: }
356:
357:
358:
359: XalanDocument*
360: XalanDefaultParsedSource2::getDocument() const
361: {
362: return m_parsedSource;
363: }
364:
365:
366:
367: XalanParsedSourceHelper*
368: XalanDefaultParsedSource2::createHelper() const
369: {
370: return new XalanDefaultParsedSourceHelper(m_domSupport);
371: }
372:
373:
374:
375:
1.1 parser 376: static void create_optioned_listener(
377: const char *& content_type, const char *& charset, FormatterListener *& listener,
378: Pool& pool,
379: const String& method_name, MethodParams *params, int index, Writer& writer) {
380: // default encoding from pool
381: const String *scharset=&pool.get_charset();
382: const String *method=0;
383: XalanDOMString xalan_encoding;
384:
385: if(params->size()>index) {
1.20 parser 386: Value& voptions=params->as_no_junction(index, "options must be string");
1.1 parser 387: if(voptions.is_defined()) {
1.34 parser 388: if(Hash *options=voptions.get_hash(&method_name)) {
1.1 parser 389: // $.method[xml|html|text]
390: if(Value *vmethod=static_cast<Value *>(options->get(*new(pool)
391: String(pool, XDOC_OUTPUT_METHOD_OPTION_NAME))))
392: method=&vmethod->as_string();
393:
394: // $.encoding[windows-1251|...]
395: if(Value *vencoding=static_cast<Value *>(options->get(*new(pool)
396: String(pool, XDOC_OUTPUT_ENCODING_OPTION_NAME)))) {
397: scharset=&vencoding->as_string();
398: }
1.19 parser 399: }
1.1 parser 400: }
401: }
402:
403: xalan_encoding.append(charset=scharset->cstr());
404: if(!method/*default='xml'*/ || *method == XDOC_OUTPUT_METHOD_OPTION_VALUE_XML) {
405: content_type="text/xml";
406: listener=new FormatterToXML(writer,
407: XalanDOMString(), // version
408: true, // doIndent
409: XDOC_OUTPUT_DEFAULT_INDENT, // indent
410: xalan_encoding // encoding
411: );
412: } else if(*method == XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML) {
413: content_type="text/html";
414: listener=new FormatterToHTML(writer,
415: xalan_encoding, // encoding
416: XalanDOMString(), // mediaType
417: XalanDOMString(), // doctypeSystem; String to be printed at the top of the document
418: XalanDOMString(), // doctypePublic
419: true, // doIndent
420: XDOC_OUTPUT_DEFAULT_INDENT // indent
421: );
422: } else if(*method == XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT) {
423: content_type="text/plain";
424: listener=new FormatterToText(writer,
425: xalan_encoding // encoding
426: );
427: } else
1.29 parser 428: throw Exception(0, 0,
1.1 parser 429: method,
430: XDOC_OUTPUT_METHOD_OPTION_NAME " option is invalid; valid methods are: "
431: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_XML "', "
432: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_HTML "', "
433: "'" XDOC_OUTPUT_METHOD_OPTION_VALUE_TEXT "'");
434:
435: // never reached
436: }
437:
438: static void _save(Request& r, const String& method_name, MethodParams *params) {
439: Pool& pool=r.pool();
440: VXnode& vnode=*static_cast<VXnode *>(r.self);
441:
442: // filespec
1.20 parser 443: const String& file_name=params->as_string(0, "file name must be string");
1.1 parser 444: const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC);
445:
446: // node
447: XalanNode& node=vnode.get_node(pool, &method_name);
448:
449: try {
450: XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec)));
451: XalanOutputStreamPrintWriter writer(stream);
452: const char *content_type, *charset;
453: FormatterListener *formatterListener;
454: create_optioned_listener(content_type, charset, formatterListener,
455: pool, method_name, params, 1, writer);
456: FormatterTreeWalker treeWalker(*formatterListener);
457: treeWalker.traverse(&node); // Walk that node and produce the XML...
458: } catch(const XSLException& e) {
1.32 parser 459: Exception::provide_source(pool, &method_name, e);
1.1 parser 460: }
461: }
462:
463: static void _string(Request& r, const String& method_name, MethodParams *params) {
464: Pool& pool=r.pool();
1.21 parser 465: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 466:
467: // node
1.21 parser 468: XalanNode *node=&vdoc.get_document(pool, &method_name);//.getDocumentElement();
469: if(!node)
1.29 parser 470: throw Exception(0, 0,
1.21 parser 471: &method_name,
472: "no documentElement");
1.1 parser 473:
474: try {
475: String parserString=*new(pool) String(pool);
476: ParserStringXalanOutputStream stream(parserString);
1.23 parser 477: XalanOutputStreamPrintWriter writer(stream);
478: const char *content_type, *charset;
479: FormatterListener *formatterListener;
480: create_optioned_listener(content_type, charset, formatterListener,
481: pool, method_name, params, 0, writer);
482: FormatterTreeWalker treeWalker(*formatterListener);
483: treeWalker.traverse(node); // Walk that node and produce the XML...
1.1 parser 484:
485: // write out result
486: r.write_no_lang(parserString);
487: } catch(const XSLException& e) {
1.32 parser 488: Exception::provide_source(pool, &method_name, e);
1.1 parser 489: }
490: }
491:
492:
493: static void _file(Request& r, const String& method_name, MethodParams *params) {
494: Pool& pool=r.pool();
495: VXnode& vnode=*static_cast<VXnode *>(r.self);
496:
497: // node
498: XalanNode& node=vnode.get_node(pool, &method_name);
499:
500: try {
501: String& parserString=*new(pool) String(pool);
502: ParserStringXalanOutputStream stream(parserString);
503: XalanOutputStreamPrintWriter writer(stream);
504: const char *content_type, *charset;
505: FormatterListener *formatterListener;
506: create_optioned_listener(content_type, charset, formatterListener,
507: pool, method_name, params, 0, writer);
508: FormatterTreeWalker treeWalker(*formatterListener);
509: treeWalker.traverse(&node); // Walk that node and produce the XML...
510:
511: // write out result
512: VFile& vfile=*new(pool) VFile(pool);
513: const char *cstr=parserString.cstr();
514: String *scontent_type=new(pool) String(pool, content_type);
515: Value *vcontent_type;
516: if(charset) {
517: VHash *vhcontent_type=new(pool) VHash(pool);
518: vhcontent_type->hash().put(*value_name, new(pool) VString(*scontent_type));
519: String *scharset=new(pool) String(pool, charset);
520: vhcontent_type->hash().put(*new(pool) String(pool, "charset"), new(pool) VString(*scharset));
521: vcontent_type=vhcontent_type;
522: } else
523: vcontent_type=new(pool) VString(*scontent_type);
524: vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*file_name*/, vcontent_type);
525: r.write_no_lang(vfile);
526: } catch(const XSLException& e) {
1.32 parser 527: Exception::provide_source(pool, &method_name, e);
1.1 parser 528: }
529: }
530:
531: static void _set(Request& r, const String& method_name, MethodParams *params) {
1.15 parser 532: //_asm int 3;
1.1 parser 533: Pool& pool=r.pool();
1.5 parser 534: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 535:
536: Value& vxml=params->as_junction(0, "xml must be code");
537: Temp_lang temp_lang(r, String::UL_XML);
538: const String& xml=r.process(vxml).as_string();
539:
540: std::istrstream stream(xml.cstr());
541: const XalanParsedSource* parsedSource;
1.9 parser 542:
1.11 parser 543: try {
544: parsedSource = new XalanDefaultParsedSource2(&stream);
1.9 parser 545: }
1.10 parser 546: catch (XSLException& e) {
1.32 parser 547: Exception::provide_source(pool, &method_name, e);
1.10 parser 548: }
549: catch (SAXParseException& e) {
1.32 parser 550: Exception::provide_source(pool, &method_name, e);
1.9 parser 551: }
1.10 parser 552: catch (SAXException& e) {
1.32 parser 553: Exception::provide_source(pool, &method_name, e);
1.9 parser 554: }
1.10 parser 555: catch (XMLException& e) {
1.32 parser 556: Exception::provide_source(pool, &method_name, e);
1.9 parser 557: }
1.16 parser 558: catch(const XalanDOMException& e) {
1.32 parser 559: Exception::provide_source(pool, &method_name, e);
1.9 parser 560: }
1.1 parser 561:
562: // replace any previous parsed source
1.5 parser 563: vdoc.set_parsed_source(*parsedSource);
1.1 parser 564: }
565:
1.17 parser 566: static void _create(Request& r, const String& method_name, MethodParams *params) {
1.27 parser 567: //_asm int 3;
1.17 parser 568: Pool& pool=r.pool();
569: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
570:
1.26 parser 571: const String& qualifiedName=params->as_string(0, "qualifiedName must be string");
1.17 parser 572:
1.25 parser 573: XalanDocument& document=*new XercesDocumentBridge(
574: DOM_Document::createDocument(),
1.21 parser 575: 0,
576: false /*threadSafe*/,
1.22 parser 577: false /*don' buildBridge -- too early, empty document*/);
1.17 parser 578:
1.25 parser 579: /// +createXMLDecl ?
1.30 parser 580: document.appendChild(document.createElement(*pool.transcode(qualifiedName)));
1.25 parser 581:
1.21 parser 582: // replace any previous document
1.28 parser 583: vdoc.set_document(document, true/*owns*/);
1.17 parser 584: }
585:
1.1 parser 586: static void _load(Request& r, const String& method_name, MethodParams *params) {
587: Pool& pool=r.pool();
1.5 parser 588: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
1.1 parser 589:
590: // filespec
1.20 parser 591: const String& file_name=params->as_string(0, "file name must be string");
1.1 parser 592: const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC);
593:
594: const XalanParsedSource* parsedSource;
1.12 parser 595: try {
596: parsedSource = new XalanDefaultParsedSource2(filespec);
597: }
598: catch (XSLException& e) {
1.32 parser 599: Exception::provide_source(pool, &method_name, e);
1.12 parser 600: }
601: catch (SAXParseException& e) {
1.32 parser 602: Exception::provide_source(pool, &method_name, e);
1.12 parser 603: }
604: catch (SAXException& e) {
1.32 parser 605: Exception::provide_source(pool, &method_name, e);
1.12 parser 606: }
607: catch (XMLException& e) {
1.32 parser 608: Exception::provide_source(pool, &method_name, e);
1.12 parser 609: }
1.16 parser 610: catch(const XalanDOMException& e) {
1.32 parser 611: Exception::provide_source(pool, &method_name, e);
1.12 parser 612: }
1.1 parser 613:
614: // replace any previous parsed source
1.5 parser 615: vdoc.set_parsed_source(*parsedSource);
1.1 parser 616: }
617:
618: static void add_xslt_param(const Hash::Key& aattribute, Hash::Val *ameaning,
619: void *info) {
1.13 parser 620: XalanTransformer2& transformer=*static_cast<XalanTransformer2 *>(info);
1.1 parser 621: const char *attribute_cstr=aattribute.cstr();
622: const char *meaning_cstr=static_cast<Value *>(ameaning)->as_string().cstr();
623:
624: transformer.setStylesheetParam(
625: XalanDOMString(attribute_cstr),
626: XalanDOMString(meaning_cstr));
627: }
628:
1.24 parser 629: static void _transform(Request& r, const String& method_name, MethodParams *params) {
630: Pool& pool=r.pool();
631: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
632:
633: // params
634: if(params->size()>1) {
635: Value& vparams=params->as_no_junction(1, "transform parameters parameter must be string");
636: if(vparams.is_defined())
1.34 parser 637: if(Hash *params=vparams.get_hash(&method_name))
1.24 parser 638: params->for_each(add_xslt_param, &vdoc.transformer());
639: else
1.29 parser 640: throw Exception(0, 0,
1.24 parser 641: &method_name,
642: "transform parameters parameter must be hash");
643: }
644:
645: // stylesheet
646: const String& stylesheet_file_name=params->as_string(0, "file name must be string");
647: const String& stylesheet_filespec=r.absolute(stylesheet_file_name);
648: //_asm int 3;
1.32 parser 649: Stylesheet_connection& connection=stylesheet_manager->get_connection(stylesheet_filespec);
1.24 parser 650:
651: // target
1.35 paf 652: XalanDocument* target=vdoc.parser_xerces_liaison().createDocument();
1.24 parser 653:
654: // transform
655: try {
1.36 paf 656: // note:
657: // actually, never found any difference between the two
658: // but still there some extra "xerces" words at start of transform body
659: // wich were originally "xalan"
660: // not daring to change that
1.35 paf 661: if(vdoc.has_parsed_source()) { // set|load, not create?
662: vdoc.transformer().transform2(
663: vdoc.get_parsed_source(pool, &method_name),
664: &connection.stylesheet(true/*nocache*/),
665: target);
666: } else {
667: target=vdoc.parser_xerces_liaison().createDocument();
668: vdoc.transformer().transform2(
669: vdoc.get_document(pool, &method_name),
670: &connection.stylesheet(true/*nocache*/),
671: target);
672: }
1.13 parser 673: }
674: catch (XSLException& e) {
675: connection.close();
1.32 parser 676: Exception::provide_source(pool, &stylesheet_file_name, e);
1.13 parser 677: }
678: catch (SAXParseException& e) {
679: connection.close();
1.32 parser 680: Exception::provide_source(pool, &stylesheet_file_name, e);
1.13 parser 681: }
682: catch (SAXException& e) {
683: connection.close();
1.32 parser 684: Exception::provide_source(pool, &stylesheet_file_name, e);
1.13 parser 685: }
686: catch (XMLException& e) {
687: connection.close();
1.32 parser 688: Exception::provide_source(pool, &stylesheet_file_name, e);
1.13 parser 689: }
1.16 parser 690: catch(const XalanDOMException& e) {
1.13 parser 691: connection.close();
1.32 parser 692: Exception::provide_source(pool, &stylesheet_file_name, e);
1.13 parser 693: }
1.1 parser 694:
695: // write out result
1.28 parser 696: VXdoc& result=*new(pool) VXdoc(pool, target, false/*owns not*/);
1.1 parser 697: r.write_no_lang(result);
698: }
699:
1.2 parser 700: static void _getElementById(Request& r, const String& method_name, MethodParams *params) {
701: Pool& pool=r.pool();
702: VXdoc& vdoc=*static_cast<VXdoc *>(r.self);
703:
704: // elementId
1.26 parser 705: const String& elementId=params->as_string(0, "elementID must be string");
1.2 parser 706:
1.16 parser 707: if(XalanNode *node=
1.30 parser 708: vdoc.get_document(pool, &method_name).getElementById(*pool.transcode(elementId))) {
1.2 parser 709: // write out result
1.31 parser 710: VXnode& result=*new(pool) VXnode(pool, node, false);
1.2 parser 711: r.write_no_lang(result);
712: }
713: }
1.16 parser 714: // constructor
1.2 parser 715:
1.16 parser 716: MXdoc::MXdoc(Pool& apool) : MXnode(apool) {
717: set_name(*NEW String(pool(), XDOC_CLASS_NAME));
1.2 parser 718:
1.16 parser 719: /// @test how to create empty type html?
1.2 parser 720:
1.16 parser 721: /// DOM1
1.2 parser 722:
1.16 parser 723: // Element createElement(in DOMString tagName) raises(DOMException);
724: add_native_method("createElement", Method::CT_DYNAMIC, _createElement, 1, 1);
725: // DocumentFragment createDocumentFragment();
726: add_native_method("createDocumentFragment", Method::CT_DYNAMIC, _createDocumentFragment, 0, 0);
727: // Text createTextNode(in DOMString data);
728: add_native_method("createTextNode", Method::CT_DYNAMIC, _createTextNode, 1, 1);
729: // Comment createComment(in DOMString data);
730: add_native_method("createComment", Method::CT_DYNAMIC, _createComment, 1, 1);
731: // CDATASection createCDATASection(in DOMString data) raises(DOMException);
732: add_native_method("createCDATASection", Method::CT_DYNAMIC, _createCDATASection, 1, 1);
733: // ProcessingInstruction createProcessingInstruction(in DOMString target, in DOMString data) raises(DOMException);
734: add_native_method("createProcessingInstruction", Method::CT_DYNAMIC, _createProcessingInstruction, 2, 2);
735: // Attr createAttribute(in DOMString name) raises(DOMException);
736: add_native_method("createAttribute", Method::CT_DYNAMIC, _createAttribute, 1, 1);
737: // EntityReference createEntityReference(in DOMString name) raises(DOMException);
738: add_native_method("createEntityReference", Method::CT_DYNAMIC, _createEntityReference, 1, 1);
739: // NodeList getElementsByTagName(in DOMString tagname);
740: /*
741: // ^xdoc.getElementsByTagName[tagname]
742: add_native_method("getElementsByTagName", Method::CT_DYNAMIC, _getElementsByTagName, 1, 1);
743:
744: // ^xdoc.getElementsByTagNameNS[namespaceURI;localName] = array of nodes
745: add_native_method("getElementsByTagNameNS", Method::CT_DYNAMIC, _getElementsByTagNameNS, 2, 2);
746: */
1.2 parser 747:
1.16 parser 748: /// DOM2(?)
1.2 parser 749:
1.16 parser 750: // ^xdoc.getElementById[elementId]
751: add_native_method("getElementById", Method::CT_DYNAMIC, _getElementById, 1, 1);
1.1 parser 752:
1.16 parser 753: /// parser
754:
1.2 parser 755: // ^xdoc.save[some.xml]
756: // ^xdoc.save[some.xml;options hash]
1.1 parser 757: add_native_method("save", Method::CT_DYNAMIC, _save, 1, 2);
758:
1.2 parser 759: // ^xdoc.string[] <doc/>
760: // ^xdoc.string[options hash] <doc/>
1.1 parser 761: add_native_method("string", Method::CT_DYNAMIC, _string, 0, 1);
762:
1.2 parser 763: // ^xdoc.file[] file with "<doc/>"
764: // ^xdoc.file[options hash] file with "<doc/>"
1.1 parser 765: add_native_method("file", Method::CT_DYNAMIC, _file, 0, 1);
766:
1.2 parser 767: // ^xdoc::set[<some>xml</some>]
1.1 parser 768: add_native_method("set", Method::CT_DYNAMIC, _set, 1, 1);
1.18 parser 769: // ^xdoc::create{qualifiedName}
1.19 parser 770: add_native_method("create", Method::CT_DYNAMIC, _create, 1, 1);
1.1 parser 771:
1.2 parser 772: // ^xdoc::load[some.xml]
1.1 parser 773: add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
774:
1.8 parser 775: // ^xdoc.transform[stylesheet file_name]
776: // ^xdoc.transform[stylesheet file_name;params hash]
777: add_native_method("transform", Method::CT_DYNAMIC, _transform, 1, 2);
1.2 parser 778:
1.1 parser 779: }
1.5 parser 780:
781: void MXdoc::configure_admin(Request& r) {
782: }
783:
1.1 parser 784: // global variable
785:
786: Methoded *Xdoc_class;
787:
788: // creator
789:
790: #endif
791:
792: Methoded *MXdoc_create(Pool& pool) {
793: return
794: #ifdef XML
1.33 parser 795: Xdoc_class=new(pool) MXdoc(pool)
1.1 parser 796: #else
797: 0
798: #endif
799: ;
800: }
E-mail: