Source: sysadm/Category.h


Annotated List
Files
Globals
Hierarchy
Index
//
// Category.h
//
//	Base class for deriving classes to represent categories of
//	monitored items.
//
//
//  Copyright (c) 1998, 2000 Silicon Graphics, Inc.  All Rights Reserved.
//  
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of version 2.1 of the GNU Lesser General Public
//  License as published by the Free Software Foundation.
//  
//  This program is distributed in the hope that it would be useful, but
//  WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//  
//  Further, this software is distributed without any warranty that it is
//  free of the rightful claim of any third person regarding infringement
//  or the like.  Any license provided herein, whether implied or
//  otherwise, applies only to this software file.  Patent licenses, if
//  any, provided herein do not apply to combinations of this program
//  with other software, or any other product whatsoever.
//  
//  You should have received a copy of the GNU Lesser General Public
//  License along with this program; if not, write the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
//  USA.
//  
//  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
//  Mountain View, CA 94043, or http://www.sgi.com/
//  
//  For further information regarding this notice, see:
//  http://oss.sgi.com/projects/GenInfo/NoticeExplan/
//

#ident "$Revision: 1.43 $"
#ifndef _SYSADM_CATEGORY_H
#define _SYSADM_CATEGORY_H

#include <sysadm/OrderedCollectionOf.h>
#include <sysadm/Item.h>
#include <sysadm/CategoryListener.h>
#include <sysadm/NotificationFilter.h>
#include <sysadm/CategoryErrorListener.h>

BEGIN_NAMESPACE(sysadm);

typedef OrderedCollectionOf<Item> ItemList;

// Opaque object reference handle for CategoryListener
class CategoryListenerHandle;

// Opaque object reference handle for CategoryErrorListener
class CategoryErrorListenerHandle;

/**
*  An instance of a subclass of Category represents a dynamic collection of
*  Item(s) of a specific type.  For example, the collection of user
*  account Item(s) can be represented by a Category instance.  A
*  Category is also  a subclass of AttrBundle and can have a set of Attributes
*  that apply to all Item(s) of that type.
* 
*  A typical Category subclass determines the set of Item(s) (of a specific
*  type) that exist in a system, when information about these Item(s) is
*  requested by a client, and calls Category base class methods to communicate
*  this information.  The subclass monitors the system for any future
*  addition, removal of Items as well as changes to the Item(s) and
*  informs the Category base class if this happens.
* 
*  Clients of a Category instance can register for notifications
*  about the set of Item(s) in that Category instance and for notifications
*  about any future changes.
* 
* 
*  Category subclasses must override the startMonitor() method to do
*  whatever is necessary to discover existing Item(s) and monitor
*  Item(s) of the specific type.  Information about all Item(s) that
*  exist at the time startMonitor() is called (hereby referred to as
*  "startup" time) is communicated to the Category base class via
*  addItem() calls. 
*  The end of the Item(s) that exist when startMonitor() is called is
*  communicated to the Category base class via an endExists() call.
*  Any future addition, removal of Items as well as changes to the
*  Item(s) is  communicated to the Category base class via addItem(),
*  removeItem() and changeItem() calls.  Information about Category
*  attributes is communicated by the subclass via
*  AttrBundle::setAttr().  Subclasses should inform the base class of
*  all Category Attributes that exist at startup before the
*  endExists() call.
* 
*  Clients interested in information about a Category instance can
*  create a subclass of CategoryListener and register for
*  notifications by passing a CategoryListener instance  to
*  adoptCategoryListener().  The specific Items of interest are
*  indicated by the NotificationFilter paramater.  The
*  NotificationFilter also specifies whether  the CategoryListener
*  instance is interested in notifications about the Category
*  attributes.  A CategoryListener instance can be added to
*  only one Category instance at a time. Call orphanCategoryListener() or 
*  removeCategoryListener() to unregister interest in notification.
*  
*  When Category base class receives notifications from its subclasses
*  (via addItem(), removeItem(), changeItem() endExists()) it notifies
*  registered CategoryListener instances about an Item detected 
*  at startup that are later added via CategoryListener::itemAdded()
*  calls, Item changes via CategoryListener::itemChanged() calls, and Item 
*  removal via CategoryListener::itemRemoved().  When
*  Category::addCategoryListener() is called, Category sends the listener
*  its current list of Item(s) via itemAdded() calls.  End of notification
*  of the current state is signalled by a
*  CategoryListener::endExists() call, if the Category itself has
*  received this notification from its subclasses.  Else,
*  CategoryListener::endExists() will be called when Category
*  receives this notification from its subclasses.
* 
* 
*  Category also supports methods beginBlockChanges() and
*  endBlockChanges() that can be called by subclasses to indicate the
*  start and end of a block of notifications.  Category base class
*  passes the notifications to identically named methods on registered
*  CategoryListener instances.  Clients can also receive error
*  notifications using the CategoryErrorListener interface and
*  registering via the addErrorListener method of Category. 
* 
* 
*  See CategoryFactory.h for details on the steps required to plug-in
*  a Category.
*/
class Category : public AttrBundle {

  public:
    /**
    *  The term "adopt<Type>" is used in the name of methods to indicate that
    *  the memory pointed to by the argument of <Type> in that method
    *  will be "adopted" by Category.  i.e memory ownership
    *  is transferred to Category.  The caller may regain ownership by
    *  calling the corresponding "orphan<Type>" method, if Category
    *  supports the method.
    *
    *  Called by clients to add "listener" to the list of objects
    *  which will receive types of notifications specified by
    *  "filter".  Category makes a copy of "filter" and any changes to
    *  "filter" after this call is made has no effect on the filter
    *  that Category associates with "listener".  A CategoryListener
    *  instance can be added to only one Category instance at a time.  Category
    *  asserts on incorrect usage.
    *  To stop notifications, use orphanCategoryListener() or
    *  removeCategoryListener() with the handle returned by this call.
    *  Category owns the memory pointed to by the return value. 
    */
    virtual CategoryListenerHandle*
        adoptCategoryListener(CategoryListener* listener,
			      const NotificationFilter& filter);
    
    /**
    *  Called by clients to remove the listener referred to by
    *  "listenerHandle" from the list of listeners which will get
    *  notified of any changes to this Category instance. 
    *  The listener is removed from the list and the ownership of the
    *  memory pointed to by the listener is transferred to the caller.
    */
    virtual CategoryListener*
        orphanCategoryListener(CategoryListenerHandle* listenerHandle);
    
    /**
    *  Called by clients to remove the listener referred to by
    *  "listenerHandle" from the list of listeners which will get
    *  notified of any changes to this Category instance.
    *  The listener is removed from the list and from memory.
    * 
    *  Do not add/remove a CategoryErrorListener from the 
    *  categoryError() method (or any methods called during the
    *  categoryError() call) of another CategoryErrorListener.
    *  Addition/removal of CategoryErrorListener in the
    *  middle of error notification is currently not handled.
    */
    virtual void removeCategoryListener(CategoryListenerHandle*
					listenerHandle);

    /**
    *  Called by clients to add "listener" to the list of objects
    *  which will get notified of errors detected by subclasses.  
    *  To stop notifications, use orphanErrorListener() or
    *  removeErrorListener() with the handle returned by this call.
    */
    virtual CategoryErrorListenerHandle*
        adoptErrorListener(CategoryErrorListener* listener);

    /**
    *  Called by clients to remove the listener referred to by
    *  "listenerHandle" from the list of listeners which will get
    *  notified of any errors. 
    *  The listener is removed from the list and the ownership of the
    *  memory pointed to by the listener is transferred to the caller.
    */
    virtual CategoryErrorListener*
        orphanErrorListener(CategoryErrorListenerHandle* listenerHandle);
    
    /**
    *  Called by clients to remove the listener referred to by
    *  "listenerHandle" from the list of listeners which will get
    *  notified of any errors.
    *  The listener is removed from the list and from memory.
    */
    virtual void removeErrorListener(CategoryErrorListenerHandle*
				     listenerHandle);

    /**
    *  For logging.
    */
    static const char* NAME;
  
  protected:
    
    /**
    *  Constructor.
    *  "selector" is the string representing the type of the Item that
    *  this Category monitors. For example, the Category instance
    *  representing user accounts could have selector:
    *  "UserAccountCategory".  Used in log messages.
    *  This is typically the same as the name of the subclass and the
    *  name of the library which should be a unique name for a
    *  Category subclass in the system. 
    */
    Category(const String& selector);

    /**
    *  Destructor.
    */
    virtual ~Category();

    /**
    *  Called by Category base class when the first
    *  CategoryListener is added.  Subclasses should do whatever is
    *  necessary to start monitoring the Item(s) of the specific type.
    *  None of addItem(), changeItem(), orphanItem(), removeItem() or
    *  replaceItemList() should be called prior to the call
    *  to startMonitor().  Category asserts on incorrect usage.
    */
    virtual void startMonitor() = 0;
 
    /**
    *  Called by subclasses when an Item is discovered at startup or
    *  when an Item is added.  The end of the list of Item(s) that
    *  exist at startup is indicated by subclasses calling
    *  endExists(). All addItem() calls after the endExist() refer to
    *  newly added Item(s).
    *  The Category base class adds a copy of "item" to its list and notifies
    *  interested listeners of the addition.
    */
    virtual void addItem(const Item& item);
    
    /**
    *  Called by subclasses when an Item changes.
    *  The Category base class replaces the Item with the
    *  same selector as "item" in its list (as returned by
    *  Item::getSelector()) with a copy of "item" and notifies
    *  interested listeners of the change.
    */
    virtual void changeItem(const Item& item);

    /**
    *  Called by subclasses when an Item is removed.
    *  The Category base class removes the Item named by "selector"
    *  from its list and notifies interested listeners of the removal.
    *  A pointer to the deleted Item is returned and ownership of the
    *  memory pointed to by the return value is transferred to the
    *  subclass.
    */
    virtual Item* orphanItem(const String& selector);

    /**
    *  Called by subclasses when an Item is removed.
    *  The Category base class removes the Item named by "selector"
    *  from its list and from memory and notifies interested listeners
    *  of the removal.
    */
    virtual void removeItem(const String& selector);

    /**
    *  Called by subclasses when it wants to replace the current list
    *  of Item(s) by a new list.  The Category base class computes any
    *  changes between its previous list and the new "list", updates
    *  its list and notifies interested listeners of any changes.
    *  Category does not assume responsibility for the memory used by
    *  the Item(s) in "list"
    */
    virtual void replaceItemList(const ItemList& list);
    
    /**
    *  Called by subclasses to indicate the start of a block of
    *  notifications. The Category base class notifies interested listeners. 
    *  Some listeners may elect not to apply changes until a matching
    *  call to endBlockChanges() has been made.
    */
    virtual void beginBlockChanges();

    /**
    *  Called by subclasses to indicate the end of a block of
    *  notifications. The Category base class notifies interested
    *  listeners that a block of changes has been completed.
    */
    virtual void endBlockChanges();

    /**
    *  Called by subclasses after it has called addItem() for every
    *  Item that existed in the system when startMonitor() is called.
    *  All addItem() calls after the endExist() refer to newly added
    *  Item(s).  The Category base class notifies interested listeners
    *  that notifications on existing objects is complete.
    */
    virtual void endExists();

    /**
    *  Called by subclasses when an error is detected.  The Category
    *  base class notifies listeners that an error has occurred.
    */
    virtual void notifyError(const String& errorString);

    /**
    *  Get the current list of items.
    */
    virtual const ItemList* getItems();

    /**
    *  Checks if the Category has started monitoring the system
    */
    virtual bool isMonitoring();

    /**
    *  Checks if the Category is in the middle of a block changes notification.
    */
    virtual bool isInBlockChangesNotification();

    /**
    *  Checks if the Category has received an endExists() notification
    *  from subclasses.
    */
    virtual bool hasExistsEnded();
    
  private:

    // Intentionally undefined.	
    Category(const Category&);
    Category& operator=(const Category&);
    
    // Opaque implementation.
    friend class CategoryImpl;
    CategoryImpl* _impl;

    friend class CategoryFactory;
};
    
END_NAMESPACE(sysadm);
#endif  //  _SYSADM_CATEGORY_H

Generated by: rusty@irem on Mon Sep 18 18:07:52 2000, using kdoc 2.0a36.