/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #ifndef __mozIClassRegistry_h #define __mozIClassRegistry_h #include "nsIComponentManager.h" /*---------------------------- mozIClassRegistry ------------------------------- | This interface provides access to a mapping from mnemonic interface names | | to shared libraries where implementations of those interfaces can be located.| | | | This interface is designed to provide two things: | | 1. A means of less static binding between clients and the code that | | implements the XPCOM interfaces those clients use. This accomplished | | by the mapping from interface names to nsCID (and the shared libraries | | that implement those classes). | | 2. A means of dynamically changing the mapping from interface name to | | implementation. The canonical example of this is to switch to a | | "native" widget set versus an "XP" (implemented using gfx) set. | | | | The first goal is achieved by storing (in a "Netscape Registry" file, see | | nsReg.h) information that maps interface/class "names" to information about | | where to load implementations of those interfaces. That information | | includes the interface ID, class ID (of the implementation class), and the | | name of the shared library that contains the implementation. | | | | The class registry object will register those classes with the "repository" | | (see nsComponentManager.h) the first time a request is made to create an | | instance. Subsequent requests will simply be forwarded to the repository | | after the appropriate interface and class IDs are determined. | | | | The second goal is accomplished by permitting the mnemonic interface | | "names" to be "overloaded", that is, mapped to distinct implementations | | by separate class registry objects. Further, class registries can be | | cascaded: they can be chained together so that when a name is not | | recognized by one registry, it can pass the request to the next registry in | | the chain. Users can control resolution by making the request of a | | registry further up/down the chain. | | | | For example, consider the case of "native" vs. "gfx" widgets. This might | | be structured by a class registry arrangment like this: | | | | nativeWidgetRegistry baseWidgetRegistry | | +----------+ +----------+ | | | ----+---------------->| | | | +----------+ +----------+ | | |toolbar| -+-----+ |toolbar| -+-----+ | | +----------+ | +----------+ | | | |button | -+-----+ |button | -+-----+ | | +----------+ | +----------+ | | | V V | | +-----------------+ +-----------------+ | | | native.dll | | base.dll | | | +-----------------+ +-----------------+ | | | | If a specialized implementation of widgets is present (e.g., native.dll) | | then a corresponding class registry object is created and added to the | | head of the registry chain. Object creation requests (normal ones) are | | resolved to the native implementation. If such a library is not present, | | then the resolution is to the base implementation. If objects of the | | base implementation are required, then creation requests can be directed | | directly to the baseWidgetRegistry object, rather than the head of the | | registry chain. | | | | It is intended that there be a single instance of this interface, accessed | | via the Service Manager (see nsServiceManager.h). | ------------------------------------------------------------------------------*/ struct mozIClassRegistry : public ISupports { /*------------------------------ CreateInstance ---------------------------- | Create an instance of the requested class/interface. The interface | | ID is required to specify how the result will be treated. The class | | named by aName must support this interface. The result is placed in | | ncomment aResult (NULL if the request fails). "start" specifies the | | registry at which the search for an implementation of the named | | interface should start. It defaults to 0 (indicating to start at the | | head of the registry chain). | --------------------------------------------------------------------------*/ NS_IMETHOD CreateInstance( const char *anInterfaceName, const nsIID &aIID, void* *aResult, const char *start = 0 ) = 0; /*--------------------------- CreateEnumerator ----------------------------- | Creates an nsIEnumerator interface object that can be used to examine | | the contents of the registry. "pattern" specifies either "*" or the | | name of a specific interface that you want to query. "result" will | | be set to point to a new object (which will be freed on the last call | | to its Release() member). See nsIEnumerator.h for details on how to | | use the returned interface pointer. | --------------------------------------------------------------------------*/ NS_IMETHOD CreateEnumerator( const char *pattern, nsIEnumerator* *result ) = 0; }; // mozIClassRegistry /*-------------------------- mozIClassRegistryEntry ---------------------------- | Objects of this class represent the individual elements that comprise a | | mozIClassRegistry interface. You obtain such objects by applying the | | CreateEnumerator member function to the class registry and then applying | | the CurrentItem member function to the resulting nsIEnumerator interface. | | | | Each entry can be queried for the following information: | | o sub-registry name | | o interface name | | o Class ID | | o IIDs implemented | | | | The information obtained from the entry (specifically, the const char* | | strings) remains valid for the life of the entry (i.e., until you | | Release() it). | | | | Here is an example of code that uses this interface to dump the contents | | of a mozIClassRegistry: | | | | mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); | | nsIEnumerator *enum; | | reg->CreateEnumerator( "*", &enum ); | | for ( enum->First(); !enum->IsDone(); enum->Next(); ) { | | mozIClassRegistryEntry *entry; | | enum->CurrentItem( &entry ); | | const char *subreg; | | const char *name; | | nsCID cid; | | int numIIDs; | | entry->GetSubRegistryName( &subreg ); | | entry->GetInterfaceName( &name ); | | entry->GetClassID( &cid ); | | entry->GetNumIIDs( &numIIDs ); | | cout << subreg << "/" << name << " = " << cid.ToString() << endl; | | for ( int i = 0; i < numIIDs; i++ ) { | | nsIID iid; | | entry->GetInterfaceID( i, &iid ); | | cout << "/tIID[" << i << "] = " << iid.ToString() << endl; | | } | | entry->Release(); | | } | | enum->Release(); | ------------------------------------------------------------------------------*/ struct mozIClassRegistryEntry : public nsISupports { NS_IMETHOD GetSubRegistryName( const char **result ) = 0; NS_IMETHOD GetInterfaceName( const char **result ) = 0; NS_IMETHOD GetClassID( nsCID *result ) = 0; NS_IMETHOD GetNumIIDs( int *result ) = 0; NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0; }; // mozIClassRegistryEntry // {5D41A440-8E37-11d2-8059-00600811A9C3} #define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } } // {D1B54831-AC07-11d2-805E-00600811A9C3} #define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } } #endif