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