--- parser3/src/include/pa_stylesheet_connection.h 2001/11/05 11:46:25 1.16 +++ parser3/src/include/pa_stylesheet_connection.h 2024/11/04 03:53:25 1.50 @@ -1,140 +1,121 @@ /** @file Parser: Stylesheet connection decl. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://paf.design.ru) - - $Id: pa_stylesheet_connection.h,v 1.16 2001/11/05 11:46:25 paf Exp $ + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #ifndef PA_STYLESHEET_CONNECTION_H #define PA_STYLESHEET_CONNECTION_H -#include "pa_config_includes.h" -#include "pa_pool.h" -#include "pa_stylesheet_manager.h" -#include "pa_exception.h" -#include "pa_common.h" +#define IDENT_PA_STYLESHEET_CONNECTION_H "$Id: pa_stylesheet_connection.h,v 1.50 2024/11/04 03:53:25 moko Exp $" -#include "XalanTransformer2.hpp" +#include "libxslt/xslt.h" +#include "libxslt/xsltInternals.h" -// defines -#define STYLESHEET_FILENAME_STAMP_SUFFIX ".stamp" +#include "pa_xml_exception.h" +#include "pa_common.h" +#include "pa_globals.h" +#include "pa_xml_io.h" + +// defines -/** Connection with stylesheet: +/** Connection with stylesheet: remembers time and can figure out that it needs recompilation */ -class Stylesheet_connection : public Pooled { +class Stylesheet_connection: public PA_Object { -public: + friend class Stylesheet_connection_ptr; - Stylesheet_connection(Pool& pool, const String& afile_spec) : Pooled(pool), - ftransformer(new XalanTransformer2), +private: + String::Body ffile_spec; + xsltStylesheet *fstylesheet; + HashStringBool* dependencies; + time_t time_used; + time_t prev_disk_time; + +public: + + Stylesheet_connection(String::Body afile_spec): ffile_spec(afile_spec), + fstylesheet(0), + dependencies(0), time_used(0), prev_disk_time(0), - fservices_pool(0), - fstylesheet(0) { - } - - const String& file_spec() { return ffile_spec; } + used(0) + {} - void set_services(Pool *aservices_pool) { - time_used=time(0); // they started to use at this time - fservices_pool=aservices_pool; + String::Body file_spec() { return ffile_spec; } + + bool uncachable() { + return !dependencies /*means they were external*/; } + bool expired(time_t older_dies) { - return time_usedclose_connection(ffile_spec, *this); - } - - void disconnect() { - /*ignore error*/ftransformer->destroyStylesheet(fstylesheet); fstylesheet=0; - - // connection effectively useless now, free up some memory - delete ftransformer; + void disconnect() { + fstylesheet=0; } bool connected() { return fstylesheet!=0; } - const XalanCompiledStylesheet& stylesheet(bool nocache) { - time_t new_disk_time=get_new_disk_time(); - if(nocache || new_disk_time) + xsltStylesheet *stylesheet() { + time_t new_disk_time=0; + if(uncachable() || (new_disk_time=get_new_disk_time())) load(new_disk_time); - return *fstylesheet; + return fstylesheet; } private: + /// return to cache + void close(); + +private: + time_t get_new_disk_time() { time_t now_disk_time=get_disk_time(); return now_disk_time>prev_disk_time?now_disk_time:0; } - void load(time_t new_disk_time) { - Pool& pool=*fservices_pool; - - try{ - const XalanCompiledStylesheet *nstylesheet; - ftransformer->compileStylesheet2(ffile_spec.cstr(String::UL_FILE_SPEC), nstylesheet); - ftransformer->destroyStylesheet(fstylesheet); - fstylesheet=nstylesheet; - } - catch (XSLException& e) { - Exception::provide_source(pool, &ffile_spec, e); - } - catch (SAXParseException& e) { - Exception::provide_source(pool, &ffile_spec, e); - } - catch (SAXException& e) { - Exception::provide_source(pool, &ffile_spec, e); - } - catch (XMLException& e) { - Exception::provide_source(pool, &ffile_spec, e); - } - catch(const XalanDOMException& e) { - Exception::provide_source(pool, &ffile_spec, e); - } - - prev_disk_time=new_disk_time; - } - - time_t get_disk_time() { - size_t size; - time_t atime, mtime, ctime; - String stamp_file_spec(ffile_spec); - stamp_file_spec << STYLESHEET_FILENAME_STAMP_SUFFIX; - // {file_spec}.stamp modification time OR {file_spec} - const String& stat_file_spec=file_readable(stamp_file_spec)?stamp_file_spec:ffile_spec; - file_stat(stat_file_spec, - size, - atime, mtime, ctime, - true/*exception on error*/); - return mtime; - } + void load(time_t new_disk_time); + time_t get_disk_time(); -private: +private: // connection usage methods - const String& ffile_spec; - const XalanCompiledStylesheet *fstylesheet; - time_t time_used; - time_t prev_disk_time; + int used; -private: + void use() { + time_used=time(0); // they started to use at this time + used++; + } - XalanTransformer2 *ftransformer; + void unuse() { + used--; + if(!used) + close(); + } - Pool *fservices_pool; +}; -private: - void *malloc(size_t size) { return fservices_pool->malloc(size); } - void *calloc(size_t size) { return fservices_pool->calloc(size); } +/// Auto-object used to track Stylesheet_connection usage +class Stylesheet_connection_ptr { + Stylesheet_connection *fconnection; +public: + Stylesheet_connection_ptr(Stylesheet_connection *aconnection) : fconnection(aconnection) { + fconnection->use(); + } + ~Stylesheet_connection_ptr() { + fconnection->unuse(); + } + Stylesheet_connection* operator->() { + return fconnection; + } }; #endif