Source: sysadm/AssocFactory.h
|
|
|
|
//
// AssocFactory.h
//
// Factory class for Association objects.
//
//
// 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.8 $"
#ifndef _SYSADM_ASSOC_FACTORY_H
#define _SYSADM_ASSOC_FACTORY_H
#include <sysadm/Association.h>
BEGIN_NAMESPACE(sysadm);
/**
* AssocFactory is the factory class for Association objects.
* AssocFactory methods are used by the Association Service to fulfill
* requests from remote clients. They can also be used by any
* server-side components that require information from an
* Association. Association subclasses will use the macros defined here.
*
* To make information about an Association between any Item of type
* "parentCategory" and Item(s) of type "childCategory" available to
* the rest of the system the following steps are required:
*
* 1. Information about the Category(s) "parentCategory" and "childCategory"
* should be available as detailed in CategoryFactory.h.
* 2. Implement a subclass of Association called
* <parentCategory>AssocWith<childCategory>.
* 2a. The subclass must have a constructor with the signature
* (Category& parentCategory, const String& parentSelector,
* Category&). Typically, this calls the corresponding
* Association constructor or an Association subclass
* constructor. "parentSelector" is the name of the parent Item
* of type "parentCategory" for which related Item(s) from
* "childCategory" are to be determined.
* 2b. Use the convenience macro SaASSOC_REF_DECL in the header
* file to provide declaration for the routines used by the
* Association Service for obtaining Association instances.
* 2c. In most cases, only one instance of a particular subclass of
* Association should exist for a given "parentCategory",
* "parentSelector", "childCategory" combination in an address
* space. To enforce this, subclasses should protect their
* constructors and use the convenience macro SaASSOC_FRIEND_DEF
* in the class declaration in the header file.
* 2d. Use the convenience macro SaASSOC_REF_DEF in the c++
* file to provide the definition for the routines used by the
* Association Service for obtaining Association instances. This in
* turn will use the constructor described in 2a.
* 2. Create a library called <parentCategory>AssocWith<childCategory>.so.
* 3. Install it in /usr/sysadm/association/
*
* The above steps will allow clients to obtain the Association instance
* to determine the relationship between any Item of type
* "parentCategory" and Item(s) of type "childCategory".
* Association.h describes the different methods supported by Association.
*/
class AssocFactory {
public:
/**
* Static get method. Creates an Association instance for the
* specified parent Category, parent Item and child Category, if
* it does not exist. Returns a reference counted Association instance.
*
* The method fails if the Association instance cannot be created.
* On failure, returns NULL and errorString is initialized with
* the localized error string. This can happen if the library
* corresponding to the parent/child Category or Association
* cannot be loaded or if any library does not define the symbols
* required. See Association.h for details on the steps required
* to plug-in an Association.
*/
static Association*
getAssociation(const String& parentCategoryName,
const String& parentSelector,
const String& childCategoryName,
String& errorString);
/**
* Static release method. Decrements reference count for
* Association instance. Deletes the instance, if there are no
* references to it.
*
* If no error is encountered in uninitializing the internal data
* structures used for creating the Association, returns true.
* Otherwise, returns false and errorString is initialized with
* the localized error string. This can happen if any library
* loaded for creation of the Association instance cannot be unloaded.
*/
static bool releaseAssociation(Association* assoc, String& errorString);
/**
* Used internally for logging.
*/
static const char* NAME;
private:
typedef Association* (*GET_ASSOC)(Category&,
const String&,
Category&);
// Pointer to the object and a reference count.
struct AssocElem {
Association* _assoc;
int _refCount;
AssocElem(Association* assoc, int refCount) :
_assoc(assoc), _refCount(refCount) {
}
};
struct DictElem {
GET_ASSOC _getAssociation;
Category& _parentCategory;
Category& _childCategory;
void* _dso;
DictionaryOf<AssocElem> _assocElems;
DictElem(Category& parentCategory, Category& childCategory,
void* dso, GET_ASSOC getAssociation)
: _parentCategory(parentCategory),
_childCategory(childCategory),
_dso(dso), _getAssociation(getAssociation) {
}
};
static DictionaryOf<DictElem> _assocs;
};
END_NAMESPACE(sysadm);
/**
* SaASSOC_REF_DECL should be used in header files declaring classes
* which are accessed via AssocFactory. For example:
*
* SaASSOC_REF_DECL(ClustersAssocWithMachine);
* class ClustersAssocWithMachine : public Association {
* ...
* };
*/
#define SaASSOC_REF_DECL(className) \
extern "C" sysadm::Association* \
get##className(sysadm::Category& parentCategory, \
const sysadm::String& parentSelector, \
sysadm::Category& childCategory);
/**
* SaASSOC_FRIEND_DEF should be used in header files
* within the definition of classes which
* are accessed via AssocFactory. For example:
*
* class ClustersAssocWithMachine : public Category {
* ...
* protected:
* SaASSOC_FRIEND_DEF(ClustersAssocWithMachine);
* ...
* };
*/
#define SaASSOC_FRIEND_DEF(className) \
friend sysadm::Association* \
get##className(sysadm::Category& parentCategory, \
const sysadm::String& parentSelector, \
sysadm::Category& childCategory); \
friend class AssocFactory;
/**
* SaASSOC_REF_DEF should be used in c++ files defining classes which
* are accessed via AssocFactory. For example:
*
* #include "ClustersAssocWithMachine.h"
* ...
* SaASSOC_REF_DEF(ClustersAssocWithMachine);
* ...
* ClustersAssocWithMachine::ClustersAssocWithMachine(
* Category& parentCategory, const String& parentSelector,
* Category& childCategory) {
* ...
* };
*/
#define SaASSOC_REF_DEF(className) \
extern "C" sysadm::Association* \
get##className(sysadm::Category& parentCategory, \
const sysadm::String& parentSelector, \
sysadm::Category& childCategory) \
{ \
return new className(parentCategory, parentSelector, childCategory); \
}
#endif // _SYSADM_ASSOC_FACTORY_H
Generated by: rusty@irem on Mon Sep 18 18:07:52 2000, using kdoc 2.0a36. |