Annotation of parser3/src/classes/dom.C, revision 1.11
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.11 ! parser 8: static const char *RCSId="$Id: dom.C,v 1.10 2001/09/10 13:13:55 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.10 parser 219: static void _xslt(Request& r, const String& method_name, MethodParams *params) {
220: Pool& pool=r.pool();
221: VDom& vDom=*static_cast<VDom *>(r.self);
222:
223: // source
1.11 ! parser 224: XalanParsedSource &parsed_source=vDom.get_parsed_source(pool, &method_name);
1.10 parser 225:
226: // stylesheet
227: const String& stylesheet_filename=params->as_string(0, "file name must not be code");
228: const char *stylesheet_filespec=r.absolute(stylesheet_filename).cstr(String::UL_FILE_NAME);
229:
230: // target
1.11 ! parser 231: // XercesDOMSupport domSupport;
! 232: // XercesParserLiaison parserLiaison(domSupport);
! 233: // XalanDocument* target=parserLiaison.createDocument();
! 234: XalanDocument* target=vDom.get_parser_liaison().createDocument();
1.10 parser 235: XSLTResultTarget domResultTarget(target);
236:
237: // transform
1.11 ! parser 238: int error=vDom.get_transformer().transform(parsed_source, stylesheet_filespec, domResultTarget);
1.10 parser 239: if(error)
240: PTHROW(0, 0,
241: &stylesheet_filename,
242: vDom.get_transformer().getLastError());
243:
244: // write out result
1.11 ! parser 245: VDom& result=*new(pool) VDom(pool);
! 246: result.set_document(*target);
! 247: r.write_no_lang(result);
1.10 parser 248: }
249:
1.2 parser 250: // constructor
251:
252: MDom::MDom(Pool& apool) : Methoded(apool) {
1.4 parser 253: set_name(*NEW String(pool(), DOM_CLASS_NAME));
1.2 parser 254:
1.3 parser 255: // ^dom::load[some.xml]
1.2 parser 256: add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1);
1.3 parser 257:
1.9 parser 258: // ^dom.save[encoding;some.xml]
1.8 parser 259: add_native_method("save", Method::CT_DYNAMIC, _save, 2, 2);
1.2 parser 260:
1.9 parser 261: // ^dom.string[encoding] <doc/>
1.7 parser 262: add_native_method("string", Method::CT_DYNAMIC, _string, 1, 1);
1.9 parser 263:
264: // ^dom.file[encoding] file with "<doc/>"
265: add_native_method("file", Method::CT_DYNAMIC, _file, 1, 1);
1.10 parser 266:
267: // ^dom.xslt[stylesheet filename]
268: /// ^dom.xslt[stylesheet filename;params hash]
269: add_native_method("xslt", Method::CT_DYNAMIC, _xslt, 1, 1);
1.6 parser 270:
1.2 parser 271: }
272: // global variable
273:
274: Methoded *Dom_class;
275:
276: // creator
277:
278: Methoded *MDom_create(Pool& pool) {
279: // Use the static initializers to initialize the Xalan-C++ and Xerces-C++ platforms.
280: // You must initialize Xerces-C++ once per process
281: XMLPlatformUtils::Initialize();
282: XalanTransformer::initialize();
283:
284: return Dom_class=new(pool) MDom(pool);
285: }
E-mail: