File:  [parser3project] / parser3 / src / include / pa_stylesheet_connection.h
Revision 1.32.2.5: download - view: text, annotated - select for diffs - revision graph
Fri Mar 7 16:05:10 2003 UTC (23 years, 4 months ago) by paf
Diff to: branchpoint 1.32: preferred, unified
xml: test 108 transform with params [bugs fixed]

/** @file
	Parser: Stylesheet connection decl.

	Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
	Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
*/

#ifndef PA_STYLESHEET_CONNECTION_H
#define PA_STYLESHEET_CONNECTION_H

static const char* IDENT_STYLESHEET_CONNECTION_H="$Date: 2003/03/07 16:05:10 $";

#include "libxslt/xslt.h"
#include "libxslt/xsltInternals.h"

#include "pa_pool.h"
#include "pa_stylesheet_manager.h"
#include "pa_exception.h"
#include "pa_common.h"
#include "pa_globals.h"

// defines

#define STYLESHEET_FILENAME_STAMP_SUFFIX ".stamp"

/**	Connection with stylesheet: 
	remembers time and can figure out that it needs recompilation
*/
class Stylesheet_connection: public PA_Object {
private:

	StringPtr ffile_spec;
	xsltStylesheet *fstylesheet;
	time_t time_used;
	time_t prev_disk_time;

public:

	Stylesheet_connection(StringPtr afile_spec):
		ffile_spec(afile_spec),
		prev_disk_time(0),
		fstylesheet(0),
		time_used(0) {}
	
	StringPtr file_spec() { return ffile_spec; }

	bool expired(time_t older_dies) {
		return references()==1/*!used*/ && time_used<older_dies;
	}
	time_t get_time_used() { return time_used; }

	void disconnect() { 
		xsltFreeStylesheet(fstylesheet);  fstylesheet=0; 
	}

	bool connected() { return fstylesheet!=0; }

	xsltStylesheet *stylesheet(bool nocache) { 
		time_t new_disk_time=get_new_disk_time();
		if(nocache || new_disk_time)
			load(new_disk_time);
		return fstylesheet; 
	}

private:

	/// return to cache
	void close() {
		stylesheet_manager.close_connection(ffile_spec, *this);
	}

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) {
		int saved=xmlDoValidityCheckingDefaultValue;//
		xmlDoValidityCheckingDefaultValue=0;//
		xsltStylesheet *nstylesheet=
			xsltParseStylesheetFile(BAD_CAST ffile_spec->cstr(String::UL_FILE_SPEC).get());
		xmlDoValidityCheckingDefaultValue = saved;//
		if(xmlHaveGenericErrors()) {
			GdomeException exc=0;
			throw Exception(ffile_spec, exc);
		}
		if(!nstylesheet)
			throw Exception("file.missing",
				ffile_spec,
				"stylesheet failed to load");

		xsltFreeStylesheet(fstylesheet);  
		fstylesheet=nstylesheet;
		prev_disk_time=new_disk_time;
	}

	time_t get_disk_time() {
		size_t size;
		time_t atime, mtime, ctime;
		StringPtr stamp_file_spec(new String(*ffile_spec));
		*stamp_file_spec << STYLESHEET_FILENAME_STAMP_SUFFIX;
		// {file_spec}.stamp modification time OR {file_spec}
		StringPtr 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 touch() {
		time_used=time(0); // they started to use at this time
	}

};

DECLARE_OBJECT_PTR(Stylesheet_connection);

#endif

E-mail: