fix JS component loader by reimplementing nsGenericModule (r=dveditz,slamm;a=leaf)

This commit is contained in:
shaver%netscape.com 1999-12-13 22:33:11 +00:00
Родитель ae2f6de4f7
Коммит ab1040199d
1 изменённых файлов: 219 добавлений и 1 удалений

Просмотреть файл

@ -733,4 +733,222 @@ static nsModuleComponentInfo components[] = {
mozJSComponentLoaderProgID, mozJSComponentLoaderConstructor }
};
NS_IMPL_NSGETMODULE("mozJSComponentLoader", components)
/*
* I would really like to just subclass nsGenericModule here, but I can't
* because nsGenericFactory.h isn't exported. If that ever changes, we
* only need custom behaviour in the RegisterSelf case, so a simple overriding
* of that method would be sufficient, and much smaller.
*
* Instead, we have nutso copy-and-paste here.
*/
#include "nsHashtable.h"
class mozJSModule : public nsIModule
{
public:
mozJSModule(const char *moduleName, PRUint32 componentCount,
nsModuleComponentInfo *components);
virtual ~mozJSModule();
NS_DECL_ISUPPORTS
NS_DECL_NSIMODULE
protected:
nsresult Initialize();
void Shutdown();
PRBool mInitialized;
const char* mModuleName;
PRUint32 mComponentCount;
nsModuleComponentInfo* mComponents;
nsSupportsHashtable mFactories;
};
mozJSModule::mozJSModule(const char* moduleName, PRUint32 componentCount,
nsModuleComponentInfo* aComponents)
: mInitialized(PR_FALSE),
mModuleName(moduleName),
mComponentCount(componentCount),
mComponents(aComponents),
mFactories(8, PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
mozJSModule::~mozJSModule()
{
Shutdown();
}
NS_IMPL_ISUPPORTS1(mozJSModule, nsIModule)
// Perform our one-time intialization for this module
nsresult
mozJSModule::Initialize()
{
if (mInitialized) {
return NS_OK;
}
mInitialized = PR_TRUE;
return NS_OK;
}
// Shutdown this module, releasing all of the module resources
void
mozJSModule::Shutdown()
{
// Release the factory objects
mFactories.Reset();
}
// Create a factory object for creating instances of aClass.
NS_IMETHODIMP
mozJSModule::GetClassObject(nsIComponentManager *aCompMgr,
const nsCID& aClass,
const nsIID& aIID,
void** r_classObj)
{
nsresult rv;
// Defensive programming: Initialize *r_classObj in case of error below
if (!r_classObj) {
return NS_ERROR_INVALID_POINTER;
}
*r_classObj = NULL;
// Do one-time-only initialization if necessary
if (!mInitialized) {
rv = Initialize();
if (NS_FAILED(rv)) {
// Initialization failed! yikes!
return rv;
}
}
// Choose the appropriate factory, based on the desired instance
// class type (aClass).
nsIDKey key(aClass);
nsCOMPtr<nsIGenericFactory> fact = getter_AddRefs(NS_REINTERPRET_CAST(nsIGenericFactory *, mFactories.Get(&key)));
if (fact == nsnull) {
nsModuleComponentInfo* desc = mComponents;
for (PRUint32 i = 0; i < mComponentCount; i++) {
if (desc->mCID.Equals(aClass)) {
rv = NS_NewGenericFactory(getter_AddRefs(fact), desc->mConstructor);
if (NS_FAILED(rv)) return rv;
(void)mFactories.Put(&key, fact);
goto found;
}
desc++;
}
// not found in descriptions
#ifdef DEBUG
char* cs = aClass.ToString();
printf("+++ nsGenericModule %s: unable to create factory for %s\n", mModuleName, cs);
nsCRT::free(cs);
#endif
// XXX put in stop-gap so that we don't search for this one again
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
found:
rv = fact->QueryInterface(aIID, r_classObj);
return rv;
}
NS_IMETHODIMP
mozJSModule::RegisterSelf(nsIComponentManager *aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation,
const char* componentType)
{
nsresult rv = NS_OK;
#ifdef DEBUG
printf("*** Registering %s components (all right -- an almost-generic module!)\n", mModuleName);
#endif
nsModuleComponentInfo* cp = mComponents;
for (PRUint32 i = 0; i < mComponentCount; i++) {
rv = aCompMgr->RegisterComponentSpec(cp->mCID, cp->mDescription,
cp->mProgID, aPath, PR_TRUE,
PR_TRUE);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsGenericModule %s: unable to register %s component => %x\n",
mModuleName, cp->mDescription, rv);
#endif
break;
}
cp++;
}
return aCompMgr->RegisterComponentLoader(jsComponentTypeName,
mozJSComponentLoaderProgID,
PR_TRUE);
}
NS_IMETHODIMP
mozJSModule::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation)
{
#ifdef DEBUG
printf("*** Unregistering %s components (all right -- an almost-generic module!)\n", mModuleName);
#endif
nsModuleComponentInfo* cp = mComponents;
for (PRUint32 i = 0; i < mComponentCount; i++) {
nsresult rv = aCompMgr->UnregisterComponentSpec(cp->mCID, aPath);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsGenericModule %s: unable to unregister %s component => %x\n",
mModuleName, cp->mDescription, rv);
#endif
}
cp++;
}
return NS_OK;
}
NS_IMETHODIMP
mozJSModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
if (!okToUnload) {
return NS_ERROR_INVALID_POINTER;
}
*okToUnload = PR_FALSE;
return NS_ERROR_FAILURE;
}
NS_EXPORT nsresult
NS_NewJSModule(const char* moduleName,
PRUint32 componentCount,
nsModuleComponentInfo* aComponents,
nsIModule* *result)
{
nsresult rv = NS_OK;
NS_ASSERTION(result, "Null argument");
// Create and initialize the module instance
mozJSModule *m = new mozJSModule(moduleName, componentCount, aComponents);
if (!m) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Increase refcnt and store away nsIModule interface to m in return_cobj
rv = m->QueryInterface(NS_GET_IID(nsIModule), (void**)result);
if (NS_FAILED(rv)) {
delete m;
m = nsnull;
}
return rv;
}
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *compMgr,
nsIFileSpec *location,
nsIModule** result)
{
return NS_NewJSModule("mozJSComponentLoader",
sizeof(components) / sizeof(components[0]),
components, result);
}