xsltcache.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 package require xslt 3.2
00017 package require uri
00018
00019 package provide xslt::cache 3.2
00020
00021 namespace xslt::cache {
00022 namespace export transform transformdoc flush
00023 namespace export parse_depend
00024 namespace export
00025
00026 variable sources
00027 array sources = {}
00028 variable stylesheets
00029 array stylesheets = {}
00030 variable results
00031 array results = {}
00032 }
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 ret xslt::cache::transform (type src , type ssheet , type args) {
00047 variable sources
00048 variable stylesheets
00049 variable results
00050
00051 # Separate parameters from options
00052 set parameters {}
00053 set options {}
00054 foreach {key value} $args {
00055 switch -glob -- $key {
00056 -* {
00057 lappend options $key $value
00058 }
00059 default {
00060 lappend parameters $key $value
00061 }
00062 }
00063 }
00064
00065 # Normalize the parameter list
00066 array set paramArray $parameters
00067 set parameters {}
00068 foreach name [lsort [array names paramArray]] {
00069 lappend parameters $name $paramArray($name)
00070 }
00071
00072 set hash $src.$ssheet.$parameters
00073
00074 array set opts {
00075 -xmlinclude 1
00076 }
00077 array set opts $options
00078
00079 set readSource [ReadXML $src -xmlinclude $opts(-xmlinclude)]
00080
00081 set readStylesheet 1
00082 if {[info exists stylesheets($ssheet)]} {
00083 if {[file mtime $ssheet] < $stylesheets($ssheet,time)} {
00084 set readStylesheet 0
00085 }
00086 }
00087 if {$readStylesheet} {
00088 catch {rename $stylesheets($ssheet) {}}
00089 ReadXML $ssheet -xmlinclude $opts(-xmlinclude)
00090
00091 set stylesheets($ssheet) [xslt::compile $sources($ssheet)]
00092 set stylesheets($ssheet,time) [clock seconds]
00093 }
00094
00095 if {$readSource || $readStylesheet || ![info exists results($hash)]} {
00096
00097 set results($hash) [eval [list $stylesheets($ssheet)] transform [list $sources($src)] $parameters]
00098 set results($hash,time) [clock seconds]
00099 }
00100
00101 return $results($hash)
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 ret xslt::cache::loadstylesheet (type src , type args) {
00116 variable sources
00117 variable stylesheets
00118
00119 array set options {
00120 -keepsource 0
00121 -xmlinclude 0
00122 }
00123 array set options $args
00124
00125 eval ReadXML [list $src] [array get options -xmlinclude]
00126
00127 set stylesheets($src) [xslt::compile $sources($src)]
00128 set stylesheets($src,time) [clock seconds]
00129
00130 if {!$options(-keepsource)} {
00131 flush $src {}
00132 }
00133
00134 # TODO: set command trace so that if the stylesheet is deleted
00135 # the cache is invalidated
00136
00137 return $stylesheets($src)
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 ret xslt::cache::ReadXML (type src , type args) {
00153 variable sources
00154 array set opts {
00155 -xmlinclude 1
00156 }
00157 array set opts $args
00158
00159 set readSource 1
00160 if {[info exists sources($src)]} {
00161 if {[file mtime $src] < $sources($src,time)} {
00162 set readSource 0
00163 }
00164 }
00165 if {$readSource} {
00166 catch {dom::destroy $sources($src)}
00167 set ch [open $src]
00168 set sources($src) [dom::parse [read $ch] -baseuri file:
00169 close $ch
00170 if {$opts(-xmlinclude)} {
00171 dom::xinclude $sources($src)
00172 }
00173 set sources($src,time) [clock seconds]
00174 }
00175
00176 return $readSource
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 ret xslt::cache::transformdoc (type src , type ssheet , type args) {
00192 variable sources
00193 variable stylesheets
00194
00195 # Separate parameters from options
00196 set parameters {}
00197 set options {}
00198 foreach {key value} $args {
00199 switch -glob -- $key {
00200 -* {
00201 lappend options $key $value
00202 }
00203 default {
00204 lappend parameters $key $value
00205 }
00206 }
00207 }
00208
00209 # Normalize the parameter list
00210 array set paramArray $parameters
00211 set parameters {}
00212 foreach name [lsort [array names paramArray]] {
00213 lappend parameters $name $paramArray($name)
00214 }
00215
00216 array set opts {
00217 -xmlinclude 1
00218 }
00219 array set opts $options
00220
00221 set readStylesheet 1
00222 if {[info exists stylesheets($ssheet)]} {
00223 if {[file mtime $ssheet] < $stylesheets($ssheet,time)} {
00224 set readStylesheet 0
00225 }
00226 }
00227 if {$readStylesheet} {
00228 catch {rename $stylesheets($ssheet) {}}
00229 ReadXML $ssheet -xmlinclude $opts(-xmlinclude)
00230
00231 set stylesheets($ssheet) [xslt::compile $sources($ssheet)]
00232 set stylesheets($ssheet,time) [clock seconds]
00233 }
00234
00235 set result [eval [list $stylesheets($ssheet)] transform [list $src] $parameters]
00236
00237 return $result
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 ret xslt::cache::parse_depend (type uri , type depVar) {
00253 upvar #0 $depVar dep
00254
00255 set dep [dom::create]
00256 dom::document createElement $dep dependencies
00257
00258 array set uriParsed [uri::split $uri]
00259
00260 switch -- $uriParsed(scheme) {
00261 file {
00262 set ch [open $uriParsed(path)]
00263 set doc [dom::parse [read $ch] -baseuri $uri -externalentitycommand [namespace code [list ParseDepend_Entity $depVar]]]
00264 close $ch
00265
00266 ParseDepend_XInclude $doc $depVar
00267 ParseDepend_XSLT $doc $depVar
00268 }
00269 http {
00270 return -code error "URI scheme \"http\" not yet implemented"
00271 }
00272 dom {
00273 set doc $uriParsed(dom)
00274
00275 # Can't determine external entities, but can find XInclude
00276 # and XSL stylesheet includes/imports.
00277 ParseDepend_XInclude $uriParsed(dom) $depVar
00278 ParseDepend_XSLT $uriParsed(dom) $depVar
00279 }
00280 default {
00281 return -code error "URI scheme \"$uriParsed(scheme)\" not supported"
00282 }
00283 }
00284
00285 return $doc
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 ret xslt::cache::ParseDepend_Entity (type depVar , type pubId , type sysId) {
00301 upvar #0 $depVar dep
00302
00303 dom::document createNode $dep /dependencies/external-entities/entity
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 ret xslt::cache::flush (type src , type ssheet , type args) {
00323 variable sources
00324 variable stylesheets
00325 variable results
00326
00327 # Normalize parameter list
00328 array set paramArray $args
00329 set parameters {}
00330 foreach name [lsort [array names paramArray]] {
00331 lappend parameters $name $paramArray($name)
00332 }
00333
00334 set hash $src.$ssheet.$parameters
00335
00336 switch -glob [string length $src],[string length $ssheet],[llength $args] {
00337 0,0,* {
00338 # Special case: flush all
00339 unset sources
00340 array set sources {}
00341 unset stylesheets
00342 array set stylesheets {}
00343 unset results
00344 array set results {}
00345 }
00346
00347 0,*,0 {
00348 # Flush all entries for the given stylesheet
00349 catch {rename $stylesheets($ssheet) {}}
00350 catch {unset stylesheets($ssheet)}
00351 catch {unset stylesheets($ssheet,time)}
00352
00353 foreach entry [array names results *.$ssheet.*] {
00354 catch {dom::destroy $results($entry)}
00355 catch {unset results($entry)}
00356 catch {unset results($entry,time)}
00357 }
00358 }
00359
00360 *,0,0 {
00361 # Flush all entries for the given source document
00362 catch {dom::destroy $sources($src)}
00363 catch {unset sources($src)}
00364 catch {unset sources($src,time)}
00365 foreach entry [array names results $src.*] {
00366 catch {dom::destroy $results($entry)}
00367 catch {unset results($entry)}
00368 catch {unset results($entry,time)}
00369 }
00370 }
00371
00372 default {
00373 # Flush specific entry
00374 catch {dom::destroy $results($hash)}
00375 catch {unset results($hash)}
00376 catch {unset results($hash,time)}
00377 }
00378 }
00379 }
00380