Annotation of parser3/src/include/pa_stylesheet_connection.h, revision 1.38
1.1 parser 1: /** @file
1.7 parser 2: Parser: Stylesheet connection decl.
1.1 parser 3:
1.38 ! paf 4: Copyright (c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)
1.26 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 parser 6: */
7:
8: #ifndef PA_STYLESHEET_CONNECTION_H
9: #define PA_STYLESHEET_CONNECTION_H
1.29 paf 10:
1.38 ! paf 11: static const char * const IDENT_STYLESHEET_CONNECTION_H="$Date: 2003/11/28 10:27:00 $";
1.1 parser 12:
1.22 paf 13: #include "libxslt/xslt.h"
1.18 paf 14: #include "libxslt/xsltInternals.h"
15:
1.33 paf 16:
1.34 paf 17: #include "pa_xml_exception.h"
1.1 parser 18: #include "pa_common.h"
1.33 paf 19: #include "pa_globals.h"
1.9 parser 20:
1.1 parser 21: // defines
22:
23: #define STYLESHEET_FILENAME_STAMP_SUFFIX ".stamp"
24:
25: /** Connection with stylesheet:
26: remembers time and can figure out that it needs recompilation
27: */
1.33 paf 28: class Stylesheet_connection: public PA_Object {
1.1 parser 29:
1.19 paf 30: friend class Stylesheet_connection_ptr;
31:
1.33 paf 32: private:
33:
1.37 paf 34: String::Body ffile_spec;
35: bool uncachable;
1.33 paf 36: xsltStylesheet *fstylesheet;
37: time_t time_used;
38: time_t prev_disk_time;
39:
1.1 parser 40: public:
41:
1.37 paf 42: Stylesheet_connection(String::Body afile_spec):
1.1 parser 43: ffile_spec(afile_spec),
1.36 paf 44: fstylesheet(0),
45: time_used(0),
1.1 parser 46: prev_disk_time(0),
1.37 paf 47: used(0)
48: {
49: uncachable=ffile_spec.pos("://")!=CORD_NOT_FOUND;
50: }
1.1 parser 51:
1.37 paf 52: String::Body file_spec() { return ffile_spec; }
1.1 parser 53:
54: bool expired(time_t older_dies) {
1.37 paf 55: return uncachable || !used && time_used<older_dies;
1.1 parser 56: }
1.15 paf 57: time_t get_time_used() { return time_used; }
1.1 parser 58:
59: void disconnect() {
1.18 paf 60: xsltFreeStylesheet(fstylesheet); fstylesheet=0;
1.1 parser 61: }
62:
63: bool connected() { return fstylesheet!=0; }
64:
1.37 paf 65: xsltStylesheet *stylesheet() {
66: time_t new_disk_time=0;
67: if(uncachable || (new_disk_time=get_new_disk_time()))
1.1 parser 68: load(new_disk_time);
1.18 paf 69: return fstylesheet;
1.1 parser 70: }
71:
72: private:
73:
1.19 paf 74: /// return to cache
1.33 paf 75: void close();
1.19 paf 76:
77: private:
78:
1.1 parser 79: time_t get_new_disk_time() {
80: time_t now_disk_time=get_disk_time();
81: return now_disk_time>prev_disk_time?now_disk_time:0;
82: }
83:
84: void load(time_t new_disk_time) {
1.31 paf 85: int saved=xmlDoValidityCheckingDefaultValue;//
86: xmlDoValidityCheckingDefaultValue=0;//
1.37 paf 87: xsltStylesheet *nstylesheet=xsltParseStylesheetFile(BAD_CAST ffile_spec.cstr());
1.31 paf 88: xmlDoValidityCheckingDefaultValue = saved;//
1.28 paf 89: if(xmlHaveGenericErrors()) {
1.20 paf 90: GdomeException exc=0;
1.37 paf 91: throw XmlException(new String(ffile_spec, String::L_TAINTED), exc);
1.28 paf 92: }
93: if(!nstylesheet)
94: throw Exception("file.missing",
1.37 paf 95: new String(ffile_spec, String::L_TAINTED),
1.28 paf 96: "stylesheet failed to load");
1.1 parser 97:
1.18 paf 98: xsltFreeStylesheet(fstylesheet);
99: fstylesheet=nstylesheet;
1.1 parser 100: prev_disk_time=new_disk_time;
101: }
102:
103: time_t get_disk_time() {
104: size_t size;
105: time_t atime, mtime, ctime;
1.37 paf 106: String stamp_file_spec(ffile_spec, String::L_AS_IS);
1.1 parser 107: stamp_file_spec << STYLESHEET_FILENAME_STAMP_SUFFIX;
1.3 parser 108: // {file_spec}.stamp modification time OR {file_spec}
1.37 paf 109: const String& stat_file_spec=file_readable(stamp_file_spec)?stamp_file_spec:*new String(ffile_spec, String::L_AS_IS);
1.14 parser 110: file_stat(stat_file_spec,
1.1 parser 111: size,
112: atime, mtime, ctime,
1.14 parser 113: true/*exception on error*/);
1.1 parser 114: return mtime;
115: }
116:
1.19 paf 117: private: // connection usage methods
118:
1.33 paf 119: int used;
1.19 paf 120: void use() {
121: time_used=time(0); // they started to use at this time
122: used++;
123: }
124: void unuse() {
125: used--;
126: if(!used)
127: close();
128: }
129:
130: };
131:
132: /// Auto-object used to track Stylesheet_connection usage
133: class Stylesheet_connection_ptr {
134: Stylesheet_connection *fconnection;
135: public:
136: explicit Stylesheet_connection_ptr(Stylesheet_connection *aconnection) :
137: fconnection(aconnection) {
138: fconnection->use();
139: }
140: ~Stylesheet_connection_ptr() {
141: fconnection->unuse();
142: }
143: Stylesheet_connection* operator->() {
144: return fconnection;
145: }
1.33 paf 146: /* Stylesheet_connection& operator*() {
147: return *fconnection;
148: }*/
1.19 paf 149:
150: // copying
151: Stylesheet_connection_ptr(const Stylesheet_connection_ptr& src) : fconnection(src.fconnection) {
152: fconnection->use();
153: }
154: Stylesheet_connection_ptr& operator =(const Stylesheet_connection_ptr& src) {
155: // may do without this=src check
156: fconnection->unuse();
157: fconnection=src.fconnection;
158: fconnection->use();
159:
160: return *this;
161: }
1.1 parser 162: };
163:
164: #endif
E-mail: