|
|
| version 1.4, 2001/09/25 09:36:51 | version 1.22, 2002/01/21 16:44:48 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: stylesheet fstylesheet decl. | Parser: Stylesheet connection decl. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) |
| Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru) | |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | |
| $Id$ | $Id$ |
| */ | */ |
| Line 11 | Line 10 |
| #ifndef PA_STYLESHEET_CONNECTION_H | #ifndef PA_STYLESHEET_CONNECTION_H |
| #define PA_STYLESHEET_CONNECTION_H | #define PA_STYLESHEET_CONNECTION_H |
| #include "pa_config_includes.h" | #include "libxslt/xslt.h" |
| #include "libxslt/xsltInternals.h" | |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_xslt_stylesheet_manager.h" | #include "pa_stylesheet_manager.h" |
| #include "pa_exception.h" | #include "pa_exception.h" |
| #include "pa_common.h" | #include "pa_common.h" |
| #include <XalanTransformer/XalanTransformer.hpp> | |
| // defines | // defines |
| #define STYLESHEET_FILENAME_STAMP_SUFFIX ".stamp" | #define STYLESHEET_FILENAME_STAMP_SUFFIX ".stamp" |
| Line 28 | Line 27 |
| */ | */ |
| class Stylesheet_connection : public Pooled { | class Stylesheet_connection : public Pooled { |
| friend class Stylesheet_connection_ptr; | |
| public: | public: |
| Stylesheet_connection(Pool& pool, const String& afile_spec) : Pooled(pool), | Stylesheet_connection(Pool& pool, const String& afile_spec) : Pooled(pool), |
| ftransformer(new XalanTransformer), | |
| ffile_spec(afile_spec), | ffile_spec(afile_spec), |
| time_used(0), | |
| prev_disk_time(0), | prev_disk_time(0), |
| fservices_pool(0), | fservices_pool(0), |
| fstylesheet(0) { | fstylesheet(0), |
| time_used(0), used(0) { | |
| } | } |
| const String& file_spec() { return ffile_spec; } | const String& file_spec() { return ffile_spec; } |
| void set_services(Pool *aservices_pool) { | void set_services(Pool *aservices_pool) { |
| time_used=time(0); // they started to use at this time | |
| fservices_pool=aservices_pool; | fservices_pool=aservices_pool; |
| } | } |
| bool expired(time_t older_dies) { | bool expired(time_t older_dies) { |
| return time_used<older_dies; | return !used && time_used<older_dies; |
| } | |
| void close() { | |
| XSLT_stylesheet_manager->close_connection(ffile_spec, *this); | |
| } | } |
| time_t get_time_used() { return time_used; } | |
| void disconnect() { | void disconnect() { |
| /*ignore error*/ftransformer->destroyStylesheet(fstylesheet); fstylesheet=0; | xsltFreeStylesheet(fstylesheet); fstylesheet=0; |
| // connection effectively useless now, free up some memory | |
| delete ftransformer; | |
| } | } |
| bool connected() { return fstylesheet!=0; } | bool connected() { return fstylesheet!=0; } |
| const XalanCompiledStylesheet& stylesheet() { | xsltStylesheet *stylesheet(bool nocache) { |
| if(time_t new_disk_time=get_new_disk_time()) | time_t new_disk_time=get_new_disk_time(); |
| if(nocache || new_disk_time) | |
| load(new_disk_time); | load(new_disk_time); |
| return *fstylesheet; | return fstylesheet; |
| } | |
| private: | |
| /// return to cache | |
| void close() { | |
| stylesheet_manager->close_connection(ffile_spec, *this); | |
| } | } |
| private: | private: |
| Line 79 private: | Line 79 private: |
| void load(time_t new_disk_time) { | void load(time_t new_disk_time) { |
| Pool& pool=*fservices_pool; | Pool& pool=*fservices_pool; |
| int error=ftransformer->compileStylesheet(ffile_spec.cstr(String::UL_FILE_SPEC), fstylesheet); | xsltStylesheet *nstylesheet; |
| if(error) | nstylesheet=xsltParseStylesheetFile(BAD_CAST ffile_spec.cstr(String::UL_FILE_SPEC)); |
| PTHROW(0, 0, | if(!nstylesheet || xmlHaveGenericErrors()) { |
| GdomeException exc=0; | |
| throw Exception(0, 0, | |
| &ffile_spec, | &ffile_spec, |
| ftransformer->getLastError()); | exc); |
| } | |
| xsltFreeStylesheet(fstylesheet); | |
| fstylesheet=nstylesheet; | |
| prev_disk_time=new_disk_time; | prev_disk_time=new_disk_time; |
| } | } |
| Line 95 private: | Line 100 private: |
| stamp_file_spec << STYLESHEET_FILENAME_STAMP_SUFFIX; | stamp_file_spec << STYLESHEET_FILENAME_STAMP_SUFFIX; |
| // {file_spec}.stamp modification time OR {file_spec} | // {file_spec}.stamp modification time OR {file_spec} |
| const String& stat_file_spec=file_readable(stamp_file_spec)?stamp_file_spec:ffile_spec; | const String& stat_file_spec=file_readable(stamp_file_spec)?stamp_file_spec:ffile_spec; |
| if(!file_stat(stat_file_spec, | file_stat(stat_file_spec, |
| size, | size, |
| atime, mtime, ctime, | atime, mtime, ctime, |
| false/*no exception on global pool[stat_file_spec], please*/)) | true/*exception on error*/); |
| mtime=1; //no file=pseudo non-zero time, see get_new_disk_time | |
| return mtime; | return mtime; |
| } | } |
| private: // connection usage methods | |
| void use() { | |
| time_used=time(0); // they started to use at this time | |
| used++; | |
| } | |
| void unuse() { | |
| used--; | |
| if(!used) | |
| close(); | |
| } | |
| private: // connection usage data | |
| int used; | |
| private: | private: |
| const String& ffile_spec; | const String& ffile_spec; |
| const XalanCompiledStylesheet *fstylesheet; | xsltStylesheet *fstylesheet; |
| time_t time_used; | time_t time_used; |
| time_t prev_disk_time; | time_t prev_disk_time; |
| private: | private: |
| XalanTransformer *ftransformer; | |
| Pool *fservices_pool; | 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: | |
| explicit Stylesheet_connection_ptr(Stylesheet_connection *aconnection) : | |
| fconnection(aconnection) { | |
| fconnection->use(); | |
| } | |
| ~Stylesheet_connection_ptr() { | |
| fconnection->unuse(); | |
| } | |
| Stylesheet_connection* operator->() { | |
| return fconnection; | |
| } | |
| // copying | |
| Stylesheet_connection_ptr(const Stylesheet_connection_ptr& src) : fconnection(src.fconnection) { | |
| fconnection->use(); | |
| } | |
| Stylesheet_connection_ptr& operator =(const Stylesheet_connection_ptr& src) { | |
| // may do without this=src check | |
| fconnection->unuse(); | |
| fconnection=src.fconnection; | |
| fconnection->use(); | |
| return *this; | |
| } | |
| }; | }; |
| #endif | #endif |