--- parser3/src/classes/Attic/dom.C 2001/09/11 08:39:04 1.14 +++ parser3/src/classes/Attic/dom.C 2001/09/14 15:41:59 1.20 @@ -5,7 +5,7 @@ Author: Alexander Petrosyan (http://design.ru/paf) */ -static const char *RCSId="$Id: dom.C,v 1.14 2001/09/11 08:39:04 parser Exp $"; +static const char *RCSId="$Id: dom.C,v 1.20 2001/09/14 15:41:59 parser Exp $"; #if _MSC_VER # pragma warning(disable:4291) // disable warning @@ -16,13 +16,15 @@ static const char *RCSId="$Id: dom.C,v 1 #include "pa_request.h" #include "pa_vdom.h" #include "pa_vfile.h" +#include "pa_xslt_stylesheet_manager.h" +#include "pa_stylesheet_connection.h" +#include #include #include #include #include #include -//#include #include #include #include @@ -30,7 +32,6 @@ static const char *RCSId="$Id: dom.C,v 1 #include #include #include -//#include // defines @@ -60,24 +61,44 @@ public: // Methoded // methods +static void _set(Request& r, const String& method_name, MethodParams *params) { + Pool& pool=r.pool(); + VDom& vDom=*static_cast(r.self); + + Value& vxml=params->as_junction(0, "xml must be code"); + Temp_lang temp_lang(r, String::UL_XML); + const String& xml=r.process(vxml).as_string(); + + std::istrstream stream(xml.cstr()); + XalanParsedSource* parsedSource; + int error=vDom.get_transformer().parseSource(&stream, parsedSource); + + if(error) + PTHROW(0, 0, + &method_name, + vDom.get_transformer().getLastError()); + + // replace any previous parsed source + vDom.set_parsed_source(*parsedSource); +} + static void _load(Request& r, const String& method_name, MethodParams *params) { Pool& pool=r.pool(); VDom& vDom=*static_cast(r.self); // filespec - const String& filename=params->as_string(0, "file name must not be code"); - const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME); + const String& file_name=params->as_string(0, "file name must not be code"); + const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC); - XSLTInputSource inputSource(filespec); XalanParsedSource* parsedSource; - int error=vDom.get_transformer().parseSource(inputSource, parsedSource); + int error=vDom.get_transformer().parseSource(filespec, parsedSource); if(error) PTHROW(0, 0, - &filename, + &file_name, vDom.get_transformer().getLastError()); - // replace any previous node value + // replace any previous parsed source vDom.set_parsed_source(*parsedSource); } @@ -106,10 +127,10 @@ static void _throw(Pool& pool, const Str ); } -class ParserStringOutputStream: public XalanOutputStream { +class ParserStringXalanOutputStream: public XalanOutputStream { public: - explicit ParserStringOutputStream(String& astring) : fstring(astring) {} + explicit ParserStringXalanOutputStream(String& astring) : fstring(astring) {} protected: // XalanOutputStream @@ -128,9 +149,11 @@ private: }; -FormatterListener *create_optioned_listener(Pool& pool, - const String& method_name, MethodParams *params, int index, - Writer& writer) { +void create_optioned_listener( + const char *& content_type, const char *& charset, FormatterListener *& listener, + Pool& pool, + const String& method_name, MethodParams *params, int index, Writer& writer) { + charset=0; const String *method=0; XalanDOMString xalan_encoding; @@ -138,30 +161,33 @@ FormatterListener *create_optioned_liste if(voptions.is_defined()) { if(Hash *options=voptions.get_hash()) { // $.method[xml|html|text] - method=&static_cast(options->get(*new(pool) - String(pool, DOM_OUTPUT_METHOD_OPTION_NAME)))->as_string(); + if(Value *vmethod=static_cast(options->get(*new(pool) + String(pool, DOM_OUTPUT_METHOD_OPTION_NAME)))) + method=&vmethod->as_string(); // $.encoding[windows-1251|...] if(Value *vencoding=static_cast(options->get(*new(pool) String(pool, DOM_OUTPUT_ENCODING_OPTION_NAME)))) { - const char *cstr=vencoding->as_string().cstr(); - xalan_encoding.append(cstr, strlen(cstr)); + charset=vencoding->as_string().cstr(); + xalan_encoding.append(charset, strlen(charset)); } } else PTHROW(0, 0, &method_name, - "params must be hash"); + "options must be hash"); } - if(!method/*default='xml'*/ || *method == DOM_OUTPUT_METHOD_OPTION_VALUE_XML) - return new FormatterToXML(writer, + if(!method/*default='xml'*/ || *method == DOM_OUTPUT_METHOD_OPTION_VALUE_XML) { + content_type="text/xml"; + listener=new FormatterToXML(writer, XalanDOMString(), // version true, // doIndent DOM_OUTPUT_DEFAULT_INDENT, // indent xalan_encoding // encoding ); - else if(*method == DOM_OUTPUT_METHOD_OPTION_VALUE_HTML) - return new FormatterToHTML(writer, + } else if(*method == DOM_OUTPUT_METHOD_OPTION_VALUE_HTML) { + content_type="text/html"; + listener=new FormatterToHTML(writer, xalan_encoding, // encoding XalanDOMString(), // mediaType XalanDOMString(), // doctypeSystem; String to be printed at the top of the document @@ -169,11 +195,12 @@ FormatterListener *create_optioned_liste true, // doIndent DOM_OUTPUT_DEFAULT_INDENT // indent ); - else if(*method == DOM_OUTPUT_METHOD_OPTION_VALUE_TEXT) - return new FormatterToText(writer, + } else if(*method == DOM_OUTPUT_METHOD_OPTION_VALUE_TEXT) { + content_type="text/plain"; + listener=new FormatterToText(writer, xalan_encoding // encoding ); - else + } else PTHROW(0, 0, method, DOM_OUTPUT_METHOD_OPTION_NAME " option is invalid; valid methods are: " @@ -182,7 +209,6 @@ FormatterListener *create_optioned_liste "'" DOM_OUTPUT_METHOD_OPTION_VALUE_TEXT "'"); // never reached - return 0; // calm, compiler } static void _save(Request& r, const String& method_name, MethodParams *params) { @@ -190,8 +216,8 @@ static void _save(Request& r, const Stri VDom& vDom=*static_cast(r.self); // filespec - const String& filename=params->as_string(1, "file name must not be code"); - const char *filespec=r.absolute(filename).cstr(String::UL_FILE_NAME); + const String& file_name=params->as_string(1, "file name must not be code"); + const char *filespec=r.absolute(file_name).cstr(String::UL_FILE_SPEC); // document XalanDocument& document=vDom.get_document(pool, &method_name); @@ -199,9 +225,11 @@ static void _save(Request& r, const Stri try { XalanFileOutputStream stream(XalanDOMString(filespec, strlen(filespec))); XalanOutputStreamPrintWriter writer(stream); - FormatterListener& formatterListener=*create_optioned_listener(pool, method_name, params, 0, - writer); - FormatterTreeWalker treeWalker(formatterListener); + const char *content_type, *charset; + FormatterListener *formatterListener; + create_optioned_listener(content_type, charset, formatterListener, + pool, method_name, params, 0, writer); + FormatterTreeWalker treeWalker(*formatterListener); treeWalker.traverse(&document); // Walk the document and produce the XML... } catch(const XSLException& e) { _throw(pool, &method_name, e); @@ -217,11 +245,13 @@ static void _string(Request& r, const St try { String parserString=*new(pool) String(pool); - ParserStringOutputStream stream(parserString); + ParserStringXalanOutputStream stream(parserString); XalanOutputStreamPrintWriter writer(stream); - FormatterListener& formatterListener=*create_optioned_listener(pool, method_name, params, 0, - writer); - FormatterTreeWalker treeWalker(formatterListener); + const char *content_type, *charset; + FormatterListener *formatterListener; + create_optioned_listener(content_type, charset, formatterListener, + pool, method_name, params, 0, writer); + FormatterTreeWalker treeWalker(*formatterListener); treeWalker.traverse(&document); // Walk the document and produce the XML... // write out result @@ -241,17 +271,29 @@ static void _file(Request& r, const Stri try { String& parserString=*new(pool) String(pool); - ParserStringOutputStream stream(parserString); + ParserStringXalanOutputStream stream(parserString); XalanOutputStreamPrintWriter writer(stream); - FormatterListener& formatterListener=*create_optioned_listener(pool, method_name, params, 0, - writer); - FormatterTreeWalker treeWalker(formatterListener); + const char *content_type, *charset; + FormatterListener *formatterListener; + create_optioned_listener(content_type, charset, formatterListener, + pool, method_name, params, 0, writer); + FormatterTreeWalker treeWalker(*formatterListener); treeWalker.traverse(&document); // Walk the document and produce the XML... // write out result VFile& vfile=*new(pool) VFile(pool); const char *cstr=parserString.cstr(); - vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*filename*/, new(pool) String(pool, "text/xml")); + String *scontent_type=new(pool) String(pool, content_type); + Value *vcontent_type; + if(charset) { + VHash *vhcontent_type=new(pool) VHash(pool); + vhcontent_type->hash().put(*value_name, new(pool) VString(*scontent_type)); + String *scharset=new(pool) String(pool, charset); + vhcontent_type->hash().put(*new(pool) String(pool, "charset"), new(pool) VString(*scharset)); + vcontent_type=vhcontent_type; + } else + vcontent_type=new(pool) VString(*scontent_type); + vfile.set(false/*tainted*/, cstr, strlen(cstr), 0/*file_name*/, vcontent_type); r.write_no_lang(vfile); } catch(const XSLException& e) { _throw(pool, &method_name, e); @@ -260,7 +302,7 @@ static void _file(Request& r, const Stri static void add_xslt_param(const Hash::Key& aattribute, Hash::Val *ameaning, - void *info) { + void *info) { XalanTransformer& transformer=*static_cast(info); const char *attribute_cstr=aattribute.cstr(); const char *meaning_cstr=static_cast(ameaning)->as_string().cstr(); @@ -275,32 +317,38 @@ static void _xslt(Request& r, const Stri // params if(params->size()>1) { - Value& vparams=params->as_no_junction(1, "params must not be code"); + Value& vparams=params->as_no_junction(1, "transform parameters parameter must not be code"); if(vparams.is_defined()) if(Hash *params=vparams.get_hash()) params->for_each(add_xslt_param, &vDom.get_transformer()); else PTHROW(0, 0, &method_name, - "params must be hash"); + "transform parameters parameter must be hash"); } // source XalanParsedSource &parsed_source=vDom.get_parsed_source(pool, &method_name); // stylesheet - const String& stylesheet_filename=params->as_string(0, "file name must not be code"); - const char *stylesheet_filespec=r.absolute(stylesheet_filename).cstr(String::UL_FILE_NAME); + const String& stylesheet_file_name=params->as_string(0, "file name must not be code"); + const String& stylesheet_filespec=r.absolute(stylesheet_file_name); + //_asm int 3; + Stylesheet_connection& connection=XSLT_stylesheet_manager->get_connection(stylesheet_filespec); // target XalanDocument* target=vDom.get_parser_liaison().createDocument(); XSLTResultTarget domResultTarget(target); // transform - int error=vDom.get_transformer().transform(parsed_source, stylesheet_filespec, domResultTarget); + int error=vDom.get_transformer().transform( + parsed_source, + &connection.stylesheet(), + domResultTarget); + connection.close(); if(error) PTHROW(0, 0, - &stylesheet_filename, + &stylesheet_file_name, vDom.get_transformer().getLastError()); // write out result @@ -314,6 +362,9 @@ static void _xslt(Request& r, const Stri MDom::MDom(Pool& apool) : Methoded(apool) { set_name(*NEW String(pool(), DOM_CLASS_NAME)); + // ^dom::set[xml] + add_native_method("set", Method::CT_DYNAMIC, _set, 1, 1); + // ^dom::load[some.xml] add_native_method("load", Method::CT_DYNAMIC, _load, 1, 1); @@ -326,8 +377,8 @@ MDom::MDom(Pool& apool) : Methoded(apool // ^dom.file[options hash] file with "" add_native_method("file", Method::CT_DYNAMIC, _file, 1, 1); - // ^dom.xslt[stylesheet filename] - // ^dom.xslt[stylesheet filename;params hash] + // ^dom.xslt[stylesheet file_name] + // ^dom.xslt[stylesheet file_name;params hash] add_native_method("xslt", Method::CT_DYNAMIC, _xslt, 1, 2); }