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