/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: registry.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/28 03:06:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SFX_REGISTRY_HXX
#define _SFX_REGISTRY_HXX


#ifndef _TIMER_HXX //autogen
#include <vcl/timer.hxx>
#endif
#ifndef _SVSTOR_HXX //autogen
#include <so3/svstor.hxx>
#endif
namespace binfilter {

//=========================================================================

class SfxRegistryIterator;
class SfxRegistryContent;
class SfxRegistryBCList_Impl;
class SfxRegistryList_Impl;
class SfxRegistryIndex_Impl;
class SfxRegistryProps_Impl;

//=========================================================================

class SfxRegistry: public SfxBroadcaster

/*	[Beschreibung]

	Instanzen dieser Klasse sind quasi Handles auf Registry-Storages.
	Ein Registry-Storage ist eine Multi-User-, Multi-Prozess- und
	Multi-Plattform- f"ahige Datenbank, die hierarchisch geordnete
	Stamp/Properties-Tupels verwaltet.

	Jede "Anderung und jeder Eintrag erh"alt eine f"ur die Lebenszeit des
	Registry-Files (nicht nur f"ur die Laufzeit des Programms) eindeutige
	Kennung (TimeStamp). Jede "Anderung wird zus"atzlich in einen
	Logfile-SubStream geschrieben, maximal jedoch die letzten 'x'
	(noch zu spezifizieren).

	Das Lesen und Schreiben erfolgt mit dem <SfxRegistryIterator>,
	der gleichzeitig eine Transaktionssteuerung vornehmen.

	Periodisch (einstellbar) wird der Registry-Storage "uberpr"uft, ob
	neue Daten vorliegen. F"ur "Anderungen in bestimmten, angemeldeten
	Contents wird ein Broadcast mit einem <SfxRegistryHint> ausgel"ost.
	Dies geschieht au\serdem beim Anlegen eines Iterators.


	[File-Format}

	Registry-Storage:
	- TimeStamp-StubStream: zuletzt verwendeter TimeStamp (initial 0)
	- Logfile-SubStream:
		- Log-Header
			- lfd.Nr. des Log-Eintrags
		- Log-Body: Stream von Records variabler L"ange der Form:
			- Action: Insert, Append, Set, Remove
			- Lock-Kennung (TimeStamp f"ur den Owner, Datum+Uhrzeit)
			- TimeStamp des betroffenen Contents
			- Content-Properties
	- Index-SubStream: Stream von Records fester L"ange der Form:
		- TimeStamp des Contents (Sortierkriterium)
		- TimeStamp des Parents
	- Contents-SubStream: Stream von Records variabler L"ange der Form:
		- TimeStamp des Contents
		- Lock-Kennung (TimeStamp f"ur den Owner, Datum+Uhrzeit)
		- Content-Properties
	- je ein Contents-SubStorage f"ur jeden Container-Content
		(die Namen der Storages sind die TimeStamps)
		- Contents-SubStream: Stream von Records variabler L"ange der Form:
			- Lock-Kennung (TimeStamp f"ur den Owner, Datum+Uhrzeit)
			- TimeStamp des Contents
			- Content-Properties
		- je ein Contents-SubStorage f"ur jeden Container-Content
			(die Namen der Storages sind die TimeStamps)
			...


	[Anmerkung]

	Die Implementation ist geeignet, bis zu etwa hundert Container zu je
	bis etwa hundert Contents "uber maximal etwa vier Hierarchieebenen
	zu verwalten. Bei durchschnittlich 12 Containern und drei Ebenen
	sind dies beispielsweise etwa 1500 Datens"atze.
*/

{
	String					_aFileName;			// Dateiname des Registry-Stor.
	SvStorageRef			_xStor;				// falls offen
	SvStorageStreamRef		_xStampStream;		// Stream, mit dem TimeStamp
	SvStorageStreamRef		_xLogStream;  		// Stream, mit dem Logfile
	SvStorageStreamRef		_xIndexStream;		// Stream, mit dem Index
	SfxRegistryBCList_Impl* _pBCList;			// zu observierende TimeStamps
	SfxRegistryList_Impl*	_pRootList;			// Root-Content-List
	SfxRegistryIndex_Impl*	_pIndex;			// sortierte Stamps
	Timer					_aAutoUpdateTimer;  // zeitgesteuertes Logfile lesen
	ULONG					_nKnownLog;     	// Logfile abgearbeitet bis hier
	ULONG					_nLastStamp;		// zuletzt verwendeter TimeStamp
	USHORT					_nReservations;		// Storage-Reservierungen
	BOOL					_bStampModified;	// _xStampStream neu schreiben

public:
							SfxRegistry( const String &rFileName );
							~SfxRegistry();

							// Time-Stamps
	ULONG					LastStamp( USHORT nTimeOutMilliSecs = 1000L );
	ULONG  					NewStamp( USHORT nTimeOutMilliSecs = 1000L );

							// Timeout
	void					SetAutoUpdateTimeout( ULONG nMilliSecs = 30*1000L );
	ULONG					GetAutoUpdateTimeout() const;

							// Notification-Registry
	void					StartListening( ULONG nStamp, SfxListener &rListener );
	void					EndListening( ULONG nStamp, SfxListener &rListener );

							// Transaction
	SfxRegistryIterator*	CreateIterator( USHORT nTimeOutMilliSecs = 1000L );
	void					Disconnect();
	BOOL					Commit();
	BOOL					Rollback();

#if _SOLAR__PRIVATE
	DECL_LINK				(AutoUpdate_Impl, void*);

	SvStorage*              ReserveStorage_Impl( USHORT nTimeOutMilliSecs );
	SvStorage*				GetStorage_Impl() const { return _xStor; }
	void                    ReleaseStorage_Impl();

	SfxRegistryList_Impl*	GetRootList_Impl();
	SfxRegistryIndex_Impl*  GetIndex_Impl();
	SfxRegistryContent* 	GotoStamp_Impl( ULONG nStamp );

	SvStream*				LoadLog_Impl( BOOL bNotify = TRUE );
	BOOL					Log_Impl( SfxRegistryContent &rCont );
#endif

#ifdef DBG_UTIL
	static void				Test_Impl();
#endif
};

//-------------------------------------------------------------------------

enum SfxRegistryAction

/*	[Beschreibung]

	Diese Werte dienen der Kennzeichnung von Benachrichtigungen, wenn von
	au\sen Daten ge"andert wurden, sowie der Kennzeichnung der Inhalten,
	bevor sie gespeichert werden.
*/

{
	SFX_REGISTRY_NO_ACTION,		// ung"ultige(r) Datensatz/Benachrichtigung
	SFX_REGISTRY_INSERT_ACTION,	// Datensatz wurde neu angelegt
	SFX_REGISTRY_CHANGE_ACTION,	// Datensatz wurde ver"andert
	SFX_REGISTRY_REMOVE_ACTION	// Datensatz wurde gel"oscht
};

//-------------------------------------------------------------------------

class SfxRegistryIterator

/*	[Beschreibung]

	Intanzen dieser Klasse werden mit <SfxRegistry::CreateIterator()>
	erzeugt. Nur "uber sie kann lesend und schreibend auf die Daten im
	<SfxRegistry> zugegriffen werden.

	Es k"onnen gleichzeitig mehrere Instanzen existieren, jedoch nur
	innerhalb eines Prozesses. Diese sharen sich dann die gecacheten Daten,
	so da\s sich auch jede "Anderung sofort in jeder Iterator-Instanz
	auswirkt.
*/

{
friend class SfxRegistry;

	SfxRegistry*			_pReg;			// zugeh"orige <SfxRegistry>
	SfxRegistryList_Impl*	_pCurList;		// Interator-Contents
	SvStorageRef			_xStor;			// Root-Storage aus dem gelesen wird

protected:
							SfxRegistryIterator( SfxRegistry *pRegistry );

public:
							~SfxRegistryIterator();

	SfxRegistry*			GetRegistry() const { return _pReg; }

							// Iterator
	SfxRegistryContent* 	First();
	SfxRegistryContent* 	Next();
	SfxRegistryContent* 	Prev();
	SfxRegistryContent* 	Last();

							// Indizierung
	USHORT					Count() const;
	SfxRegistryContent* 	Seek( ULONG nPos );

							// Direktzugriff
	SfxRegistryContent* 	GotoStamp( ULONG nStamp );

							// Hierarchie
	BOOL					Enter();
	BOOL					Leave();

							// Locking
	BOOL					Lock( ULONG nMilliSecs = 5*60*1000L );
	BOOL					UnLock();

							// Content-Update
	BOOL					Remove();
	SfxRegistryContent* 	Insert( ULONG nPos = LIST_APPEND );
};

//-------------------------------------------------------------------------

class SfxRegistryContent: SfxHint

/*	[Beschreibung]

	Instanzen dieser Klasse dienen als Cache f"ur die Inhalte der
	<SfxRegistry> im Hauptspeicher. Sie werden ausschlie\slich "uber
	<SfxRegistryIterator> erzeugt und ver"andert.
*/

{
friend class SfxRegistry;
friend class SfxRegistryIterator;
friend class SfxRegistryList_Impl;

	SfxRegistryList_Impl*		_pParent;		// in der Liste befindet er sich
	ULONG						_nId;			// sein eindeutiger TimeStamp
	SfxRegistryProps_Impl*		_pProps;		// Liste von Properties
	SfxRegistryList_Impl*		_pList;			// ggf. der eigene Inhalt
	BOOL						_bHasContents;	// ob eigener Inhalt verg"ugbar
	SfxRegistryAction			_eAction;		// "Anderungs-Vermerk

#if _SOLAR__PRIVATE
private:
								SfxRegistryContent( SfxRegistryList_Impl *pParent );
								SfxRegistryContent( SfxRegistryList_Impl *pParent,
													ULONG nId );
								~SfxRegistryContent();

	friend SvStream& 			operator <<( SvStream &rStream,
											 const SfxRegistryContent &rRec );
	friend SvStream& 			operator >>( SvStream &rStream,
											 SfxRegistryContent &rRec );

	SfxRegistryList_Impl*		GetList_Impl( BOOL bForceLoad = TRUE );
	SfxRegistryList_Impl*		GetParent_Impl() const { return _pParent; }
	void                    	SetParent_Impl( SfxRegistryList_Impl* pPar )
								{ _pParent = pPar; }

	void						SetAction_Impl( SfxRegistryAction eAction )
								{ _eAction = eAction; }
	void						SetContents_Impl( BOOL bHas ) { _bHasContents = bHas; }
#endif

public:
								TYPEINFO();

	BOOL						HasContents() const { return _bHasContents; }
	ULONG						GetStamp() const { return _nId; }
	ULONG						GetParentStamp() const;
	SfxRegistryAction			GetAction() const { return _eAction; }

	void						SetProperty( const String &rProp, USHORT nIndex );
	const String*				GetProperty( USHORT nIndex ) const;

	String				        GetTitle() const { return *GetProperty(0); }
	String				        GetData() const { return *GetProperty(1); }
};

}//end of namespace binfilter
#endif



