/*!
  @header FTDictionaryServiceForGraphImpl
  @abstract Module of FT
 
  @availability OS X, GNUstep
  @copyright 2004, 2005, 2006 Free Software Foundation, Inc.
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA

  <pre>
  -------------------------------------------------------------------------
  Modification history

  16.07.06 ola     initial version
  23.08.06 ola     license changed
  -------------------------------------------------------------------------
  </pre>
*/

#if !defined(__FTDictionaryServiceForGraphImpl_H)
#define __FTDictionaryServiceForGraphImpl_H

#include <Foundation/Foundation.h>
#include <BDB/BDB.h>
#include <FT/FTObject.h>
#include <FT/FTGraph.h>
#include <FT/FTGraphImpl.h>
#include <FT/FTService.h>
#include <FT/FTDictionaryService.h>

@class FTDictionaryServiceLoader;


/*!
 * @class FTDictionaryServiceForGraphImpl
 * @abstract Don't know wether i like the name. Anyway this class implements
 *   the dictionary service for a particular graph. All nodes offering the
 *   service FTDictionaryService somehow refer to this graph.
 */
@interface FTDictionaryServiceForGraphImpl : FTObject {
  @private 
    BDBDatabase *database;
    BOOL databaseIsOpen;
    
    NSLock *writeLock;
    
    FTDictionaryServiceLoader *serviceLoader;
}

- initForGraph: (id <FTGraph>) aGraph 
  serviceLoader: (FTDictionaryServiceLoader *) aServiceLoader;
- (void) dealloc;


/*!
 * @method addDatabaseEntry
 * @abstract adds an entry to the database
 * @param anentry entry to add
 * @param aKey key associated to the entry
 * @result self
 */
- addDatabaseEntry: (BDBDatabaseEntry *) anEntry 
  forDatabaseKey: (BDBDatabaseEntry *) aKey;
  

/*!
 * @method addObject
 * @abstract adds data for a given node. Usually called by transaction steps.
 * @param anObject object to add
 * @param aKey key to use
 * @param aNode node to add the data to
 * @result self
 */
- addObject: (id <NSCoding>) anObject forKey: (id <NSCoding>) aKey
  forNode: (id <FTNode>) aNode;
  

/*!
 * @method allKeysOfNode
 * @param aNode node to evaluate
 * @result return all data object keys for the particular node
 */
- (id <ECIterator>) allKeysOfNode: (id <FTNode>) aNode;


/*!
 * @method close
 * @abstract closes any databases thus ending work with the corresponding
 *   instance
 */
- (void) close;


/*!
 * @method createDatabaseEntryKeyForNodeId
 * @abstract creates a database key consisting of the node's id and the given
 *   key
 * @param aNodeId id of node
 * @param aKey
 * @result database key consisting of the node's id and the given
 *   key
 */
- (BDBDatabaseEntry *) createDatabaseEntryKeyForNodeId: (id <FTId>) aNodeId
  forKey: (id <NSCoding>) aKey;
  

/*!
 * @method databaseEntryForKey
 * @abstract Looks up for an entry wihin the database which is associated 
 *   with the given key.
 * @param aDBKey key to look for
 * @result associated entry or nil, if not found
 * @throws FTInternalDatamanagementException
 */
- (BDBDatabaseEntry *) databaseEntryForKey: (BDBDatabaseEntry *) aDBKey;


/*!
 * @emthod isOpen
 * result YES if the service is available for the given graph
 */
- (BOOL) isOpen;


/*!
 * @method objectForKey
 * @abstract used to fetch the object associated to the given key for the
 *   specified node
 * @param aKey key to look for
 * @param aNode related node
 * @result object or nil if not found
 */
- objectForKey: (id <NSCoding>) aKey ofNode: (id <FTNode>) aNode;


/*!
 * @method openDatabase
 * @abstract Internal method used to open or create the database
 * @param aGraph graph for which the service has to be offered to.
 * @param databaseName name of database to be used within the data
 *   directory of the given graph
 * @result self
 */
- openDatabaseForGraph: (FTGraphImpl *) aGraph
  usingDatabaseName: (NSString *) aDatabaseName;


/*!
 * @method removeDatabaseEntryForKey
 * @abstract removes the database entry associated to the given key
 * @param key key of entry to be removed
 * @result self
 */
- removeDatabaseEntryForKey: (BDBDatabaseEntry *) key;


/*!
 * @method removeObjectForKey
 * @abstract removes an entry from the dictionary
 * @param aKey key associated to the object to be removed
 * @param aNode related node
 * @result self
 */
- removeObjectForKey: (id <NSCoding>) aKey ofNode: (id <FTNode>) aNode;


/*!
 * @method serviceForNode
 * @result service related to the given node
 */
- (id <FTDictionaryService>) serviceForNode: (id <FTNode>) aNode;


/*!
 * @method serviceLoader
 * @result underlying service loader
 */
- (id <FTServiceLoader>) serviceLoader;
@end


/*!
 * @class _FTDictionaryServiceKeysOfNode
 * @abstract Internal method used to organize the storage of keys for a given
 *   node.
 */
@interface _FTDictionaryServiceKeysOfNode : FTObject {
  @private
    id <FTNode> node;
    FTDictionaryServiceForGraphImpl *dictionaryForGraph;
}

- initForNode: (id <FTNode>) aNode 
  dictionaryServiceForGraph: (FTDictionaryServiceForGraphImpl *) aDictService;
- (void) dealloc;

- (id <ECIterator>) allKeys;
- addKey: (id <NSCoding>) aKey;
- (BDBDatabaseEntry *) dbKeyForAllkeys;
- (NSMutableSet *) fetchKeys;
- removeKey: (id <NSCoding>) aKey;
- storeKeys: (NSMutableSet *) allKeys;
@end

#endif
