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