Annotation of parser3/src/classes/dom.C, revision 1.10
1.2 parser 1: /** @file
2: Parser: @b dom parser class.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
7: */
1.10 ! parser 8: static const char *RCSId="$Id: dom.C,v 1.9 2001/09/10 11:17:41 parser Exp $";
1.2 parser 9:
10: #if _MSC_VER
11: # pragma warning(disable:4291) // disable warning
12: // "no matching operator delete found; memory will not be freed if initialization throws an exception
13: #endif
14:
15: #include "classes.h"
16: #include "pa_request.h"
17: #include "pa_vdom.h"
1.9 parser 18: #include "pa_vfile.h"
1.2 parser 19:
20: #include <Include/PlatformDefinitions.hpp>
21: #include <util/PlatformUtils.hpp>
1.5 parser 22: #include <util/XMLString.hpp>
1.2 parser 23: #include <XalanTransformer/XalanTransformer.hpp>
1.4 parser 24: #include <XalanTransformer/XalanParsedSource.hpp>
1.10 ! parser 25: #include <XalanTransformer/XercesDOMParsedSource.hpp>
1.4 parser 26: #include <PlatformSupport/XalanFileOutputStream.hpp>
27: #include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>
1.6 parser 28: #include <PlatformSupport/DOMStringPrintWriter.hpp>
1.4 parser 29: #include <XMLSupport/FormatterToXML.hpp>
30: #include <XMLSupport/FormatterTreeWalker.hpp>
1.10 ! parser 31: #include <XercesParserLiaison/XercesDOMSupport.hpp>
! 32: #include <XercesParserLiaison/XercesParserLiaison.hpp>
1.6 parser 33:
1.2 parser 34: // defines
35:
1.4 parser 36: #define DOM_CLASS_NAME "dom"
1.2 parser 37:
38: // class
39:
40: class MDom : public Methoded {
41: public: // VStateless_class
1.10 ! parser 42: Value *create_new_value(Pool& pool) { return new(pool) VDom(pool, 0); }
1.2 parser 43:
44: public:
45: MDom(Pool& pool);
46:
47: public: // Methoded
48: bool used_directly() { return true; }
49: };
50:
51: // methods
52:
53: static void _load(Request& r, const String& method_name, MethodParams *params) {
54: Pool& pool=r.pool();
1.10 ! parser 55: VDom& vDom=*static_cast<VDom *>(r.self);
1.2 parser 56:
1.10 ! parser 57: // filespec
1.2 parser 58: const String& filename=params->as_string(0, "file name must not be code");
59: const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
60:
61: XSLTInputSource inputSource(filespec);
62: XalanParsedSource* parsedSource;
1.10 ! parser 63: int error=vDom.get_transformer().parseSource(inputSource, parsedSource);
1.2 parser 64:
65: if(error)
66: PTHROW(0, 0,
67: &filename,
1.10 ! parser 68: vDom.get_transformer().getLastError());
1.2 parser 69:
70: // replace any previous node value
1.10 ! parser 71: vDom.set_document(parsedSource->getDocument());
1.2 parser 72: }
73:
1.5 parser 74: const char *strX(const XalanDOMString& s) {
75: return XMLString::transcode(s.c_str());
76: }
77:
78: static void _throw(Pool& pool, const String *source, const XSLException& e) {
79: if(e.getURI().empty())
80: PTHROW(0, 0,
81: source,
82: "%s (%s)",
83: strX(e.getMessage()), // message for exception
84: strX(e.getType()) // type of exception
85: );
86: else
87: PTHROW(0, 0,
88: source,
89: "%s (%s) %s(%d:%d)'",
90: strX(e.getMessage()), // message for exception
91: strX(e.getType()), // type of exception
92:
93: strX(e.getURI()), // URI for the associated document, if any
94: e.getLineNumber(), // line number, or -1 if unknown
95: e.getColumnNumber() // column number, or -1 if unknown
96: );
97: }
98:
1.6 parser 99: class ParserStringOutputStream: public XalanOutputStream {
100: public:
101:
1.7 parser 102: explicit ParserStringOutputStream(String& astring) : fstring(astring) {}
103:
104: protected: // XalanOutputStream
105:
106: virtual void writeData(const char *theBuffer, unsigned long theBufferLength) {
1.6 parser 107: char *copy=(char *)fstring.malloc((size_t)theBufferLength);
108: memcpy(copy, theBuffer, (size_t)theBufferLength);
109: fstring.APPEND_CLEAN(copy, (size_t)theBufferLength, "dom", -1);
110: }
111:
1.7 parser 112: virtual void doFlush() {}
1.6 parser 113:
114: private:
115:
116: String& fstring;
117:
118: };
119:
120:
1.3 parser 121: static void _save(Request& r, const String& method_name, MethodParams *params) {
122: Pool& pool=r.pool();
1.10 ! parser 123: VDom& vDom=*static_cast<VDom *>(r.self);
1.3 parser 124:
1.7 parser 125: // encoding
126: const char *encoding=params->as_string(0, "encoding must not be code").cstr();
1.3 parser 127:
128: // filespec
1.7 parser 129: const String& filename=params->as_string(1, "file name must not be code");
1.3 parser 130: const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME);
131:
1.10 ! parser 132: XalanDocument *document=vDom.get_document();
! 133: if(!document)
1.4 parser 134: PTHROW(0, 0,
135: &method_name,
136: "on empty document");
1.3 parser 137:
1.5 parser 138: try {
1.6 parser 139: XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec)));
140: XalanOutputStreamPrintWriter writer(stream);
1.7 parser 141: FormatterToXML formatterListener(writer,
142: XalanDOMString(), // version
143: true , // doIndent
144: 4, // indent
145: XalanDOMString(encoding, strlen(encoding)) // encoding
146: );
1.6 parser 147: FormatterTreeWalker treeWalker(formatterListener);
148: treeWalker.traverse(document); // Walk the document and produce the XML...
149: } catch(const XSLException& e) {
150: _throw(pool, &method_name, e);
151: }
152: }
153:
154: static void _string(Request& r, const String& method_name, MethodParams *params) {
155: Pool& pool=r.pool();
1.10 ! parser 156: VDom& vDom=*static_cast<VDom *>(r.self);
1.6 parser 157:
1.7 parser 158: // encoding
159: const char *encoding=params->as_string(0, "encoding must not be code").cstr();
160:
1.10 ! parser 161: XalanDocument *document=vDom.get_document();
! 162: if(!document)
1.6 parser 163: PTHROW(0, 0,
164: &method_name,
165: "on empty document");
166:
167: try {
1.9 parser 168: String parserString=*new(pool) String(pool);
169: ParserStringOutputStream stream(parserString);
1.6 parser 170: XalanOutputStreamPrintWriter writer(stream);
1.7 parser 171: FormatterToXML formatterListener(writer,
172: XalanDOMString(), // version
173: true , // doIndent
174: 4, // indent
175: XalanDOMString(encoding, strlen(encoding)), // encoding
176: XalanDOMString(), // mediaType
177: XalanDOMString(), // doctypeSystem
178: XalanDOMString(), // doctypePublic
179: false // xmlDecl
180: );
1.6 parser 181: FormatterTreeWalker treeWalker(formatterListener);
182: treeWalker.traverse(document); // Walk the document and produce the XML...
183:
184: // write out result
1.9 parser 185: r.write_no_lang(parserString);
1.5 parser 186: } catch(const XSLException& e) {
187: _throw(pool, &method_name, e);
188: }
1.3 parser 189: }
190:
1.9 parser 191:
192: static void _file(Request& r, const String& method_name, MethodParams *params) {
193: Pool& pool=r.pool();
1.10 ! parser 194: VDom& vDom=*static_cast<VDom *>(r.self);
1.9 parser 195:
196: // encoding
197: const char *encoding=params->as_string(0, "encoding must not be code").cstr();
198:
1.10 ! parser 199: XalanDocument *document=vDom.get_document();
! 200: if(!document)
1.9 parser 201: PTHROW(0, 0,
202: &method_name,
203: "on empty document");
204:
205: try {
206: String& parserString=*new(pool) String(pool);
207: ParserStringOutputStream stream(parserString);
208: XalanOutputStreamPrintWriter writer(stream);
209: FormatterToXML formatterListener(writer,
210: XalanDOMString(), // version
211: true , // doIndent
212: 4, // indent
213: XalanDOMString(encoding, strlen(encoding)) // encoding
214: );
215: FormatterTreeWalker treeWalker(formatterListener);
216: treeWalker.traverse(document); // Walk the document and produce the XML...
217:
218: // write out result
219: VFile& vfile=*new(pool) VFile(pool);
220: const char *cstr=parserString.cstr();
221: vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*filename*/, new(pool) String(pool, "text/xml"));
222: r.write_no_lang(vfile);
223: } catch(const XSLException& e) {
224: _throw(pool, &method_name, e);
225: }
226: }
227:
228:
1.10 ! parser 229: static void _xslt(Request& r, const String& method_name, MethodParams *params) {
! 230: Pool& pool=r.pool();
! 231: VDom& vDom=*static_cast<VDom *>(r.self);
! 232:
! 233: // source
! 234: XalanDocument *source_document=vDom.get_document();
! 235: if(!source_document)
! 236: PTHROW(0, 0,
! 237: &method_name,
! 238: "on empty document");
! 239:
! 240: // stylesheet
! 241: const String& stylesheet_filename=params->as_string(0, "file name must not be code");
! 242: const char *stylesheet_filespec=r.absolute(stylesheet_filename).cstr(String::UL_FILE_NAME);
! 243:
! 244: // target
! 245: XercesDOMSupport domSupport;
! 246: XercesParserLiaison parserLiaison(domSupport);
! 247: XalanDocument* target=parserLiaison.createDocument();
! 248: XSLTResultTarget domResultTarget(target);
! 249:
! 250: // transform
! 251: int error=vDom.get_transformer().transform(
! 252: source_document, stylesheet_filespec, domResultTarget);
! 253: if(error)
! 254: PTHROW(0, 0,
! 255: &stylesheet_filename,
! 256: vDom.get_transformer().getLastError());
! 257:
! 258: // write out result
! 259: r.write_no_lang(*new(pool) VDom(pool, target));
! 260: }
! 261:
1.2 parser 262: // constructor
263:
264: MDom::MDom(Pool& apool) : Methoded(apool) {
1.4 parser 265: set_name(*NEW String(pool(), DOM_CLASS_NAME));
1.2 parser 266:
1.3 parser 267: // ^dom::load[some.xml]
1.2 parser 268: add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
1.3 parser 269:
1.9 parser 270: // ^dom.save[encoding;some.xml]
1.8 parser 271: add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2);
1.2 parser 272:
1.9 parser 273: // ^dom.string[encoding] <doc/>
1.7 parser 274: add_native_method("string", Method::CT_DYNAMIC, _string, 1, 1);
1.9 parser 275:
276: // ^dom.file[encoding] file with "<doc/>"
277: add_native_method("file", Method::CT_DYNAMIC, _file, 1, 1);
1.10 ! parser 278:
! 279: // ^dom.xslt[stylesheet filename]
! 280: /// ^dom.xslt[stylesheet filename;params hash]
! 281: add_native_method("xslt", Method::CT_DYNAMIC, _xslt, 1, 1);
1.6 parser 282:
1.2 parser 283: }
284: // global variable
285:
286: Methoded *Dom_class;
287:
288: // creator
289:
290: Methoded *MDom_create(Pool& pool) {
291: // Use the static initializers to initialize the Xalan-C++ and Xerces-C++ platforms.
292: // You must initialize Xerces-C++ once per process
293: XMLPlatformUtils::Initialize();
294: XalanTransformer::initialize();
295:
296: return Dom_class=new(pool) MDom(pool);
297: }
E-mail: