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