Mozilla/mozilla/java/xpcom/urp/src/loader/urpComponentLoader.cpp
timeless%mac.com 535b6f20f2 Bugzilla Bug 107823 change nsIFile
to use 'Modified' instead of 'Modification'
r=akkana sr=brendan


git-svn-id: svn://10.0.0.236/trunk@108891 18797224-902f-48f8-a5cc-f745e15eee43
2001-11-26 08:05:05 +00:00

459 lines
16 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Sun Microsystems,
* Inc. Portions created by Sun are
* Copyright (C) 1999 Sun Microsystems, Inc. All
* Rights Reserved.
*
* Contributor(s):
* Sergey Lunegov <lsv@sparc.spb.su>
*/
/*
A bunch of stuff was copied from mozJSComponentLoader.cpp
*/
#include <fstream.h>
#include "nsICategoryManager.h"
#include "urpComponentLoader.h"
#include "urpComponentFactory.h"
#include "nsCOMPtr.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsXPIDLString.h"
#include "nsCRT.h"
#include "../urpLog.h"
const char urpComponentTypeName[] = URPCOMPONENTTYPENAME;
/* XXX export properly from libxpcom, for now this will let Mac build */
#ifdef RHAPSODY
extern const char fileSizeValueName[]; // = "FileSize";
extern const char lastModValueName[]; // = "LastModTimeStamp";
extern const char xpcomKeyName[]; // = "Software/Mozilla/XPCOM";
#else
const char fileSizeValueName[] = "FileSize";
const char lastModValueName[] = "LastModTimeStamp";
const char xpcomKeyName[] = "software/mozilla/XPCOM/components";
#endif
NS_IMPL_THREADSAFE_ISUPPORTS(urpComponentLoader,NS_GET_IID(nsIComponentLoader));
urpComponentLoader::urpComponentLoader()
: mCompMgr(NULL),
mXPCOMKey(0)
{
NS_INIT_REFCNT();
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::urpComponentLoader \n"));
}
urpComponentLoader::~urpComponentLoader() { //nb
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::~urpComponentLoader \n"));
}
/**
* Get the factory for a given component.
*/
/* nsIFactory getFactory (in nsIIDRef aCID, in string aLocation, in string aType); */
NS_IMETHODIMP urpComponentLoader::GetFactory(const nsIID & aCID, const char *aLocation, const char *aType, nsIFactory **_retval) {
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::GetFactory \n"));
if (!_retval)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG
char *cidString = aCID.ToString();
fprintf(stderr, "--urpComponentLoader::GetFactory(%s,%s,%s)\n", cidString, aLocation, aType);
delete [] cidString;
#endif
// nsIFactory *f = new urpComponentFactory(aLocation, aCID, proxy);
nsIFactory *f = new urpComponentFactory(aLocation, aCID);
NS_ADDREF(f);
*_retval = f;
return NS_OK;
}
/**
* Initialize the loader.
*
* We use nsISupports here because nsIRegistry isn't IDLized yet.
*/
/* void init (in nsIComponentManager aCompMgr, in nsISupports aRegistry); */
NS_IMETHODIMP urpComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) {
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::Init \n"));
nsresult rv;
mCompMgr = aCompMgr;
mRegistry = do_QueryInterface(aReg, &rv);
if (NS_SUCCEEDED(rv)) {
rv = mRegistry->GetSubtree(nsIRegistry::Common, xpcomKeyName,
&mXPCOMKey);
if (NS_FAILED(rv))
/* if we can't get the XPCOM key, just skip all registry ops */
mRegistry = nsnull;
}
return NS_OK;
}
/**
* Called when a component of the appropriate type is registered,
* to give the component loader an opportunity to do things like
* annotate the registry and such.
*/
/* void onRegister (in nsIIDRef aCID, in string aType, in string aClassName, in string aContractID, in string aLocation, in boolean aReplace, in boolean aPersist); */
NS_IMETHODIMP urpComponentLoader::OnRegister(const nsIID & aCID, const char *aType, const char *aClassName, const char *aContractID, const char *aLocation, PRBool aReplace, PRBool aPersist) { //nb
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::OnRegister \n"));
return NS_OK;
}
/**
* AutoRegister components in the given directory.
*/
NS_IMETHODIMP urpComponentLoader::AutoRegisterComponents(PRInt32 aWhen, nsIFile *aDirectory) {
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::AutoRegisterComponents \n"));
return RegisterComponentsInDir(aWhen,aDirectory);
}
NS_IMETHODIMP urpComponentLoader::AutoUnregisterComponent(PRInt32 when,
nsIFile *component,
PRBool *unregistered) {
//nb need to impelement
return NS_OK;
}
nsresult urpComponentLoader::RegisterComponentsInDir(PRInt32 when, nsIFile *dir)
{
nsresult rv;
PRBool isDir;
if (NS_FAILED(rv = dir->IsDirectory(&isDir)))
return rv;
if (!isDir)
return NS_ERROR_INVALID_ARG;
// Create a directory iterator
nsCOMPtr<nsISimpleEnumerator> dirIterator;
rv = dir->GetDirectoryEntries(getter_AddRefs(dirIterator));
if (NS_FAILED(rv)) return rv;
// whip through the directory to register every file
nsIFile *dirEntry = NULL;
PRBool more = PR_FALSE;
rv = dirIterator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
while (more == PR_TRUE)
{
rv = dirIterator->GetNext((nsISupports**)&dirEntry);
if (NS_SUCCEEDED(rv))
{
rv = dirEntry->IsDirectory(&isDir);
if (NS_SUCCEEDED(rv))
{
if (isDir == PR_TRUE)
{
// This is a directory. Grovel for components into the directory.
rv = RegisterComponentsInDir(when, dirEntry);
}
else
{
PRBool registered;
// This is a file. Try to register it.
rv = AutoRegisterComponent(when, dirEntry, &registered);
}
}
NS_RELEASE(dirEntry);
}
rv = dirIterator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
}
return NS_OK;
}
/**
* AutoRegister the given component.
*
* Returns true if the component was registered, false if it couldn't
* attempt to register the component (wrong type) and ``throws'' an
* NS_FAILED code if there was an error during registration.
*/
/* boolean autoRegisterComponent (in long aWhen, in nsIFile aComponent); */
/* copied from mozJSComponentLoader.cpp */
NS_IMETHODIMP urpComponentLoader::AutoRegisterComponent(PRInt32 when, nsIFile *component, PRBool *registered) {
//printf("--urpComponentLoader::AutoRegisterComponent \n");
nsresult rv;
if (!registered)
return NS_ERROR_NULL_POINTER;
const char javaExtension[] = ".urp.info";
int javaExtensionLen = 9;
nsXPIDLCString leafName;
*registered = PR_FALSE;
/* we only do files */
PRBool isFile = PR_FALSE;
if (NS_FAILED(rv = component->IsFile(&isFile)) || !isFile)
return rv;
if (NS_FAILED(rv = component->GetLeafName(getter_Copies(leafName))))
return rv;
int len = PL_strlen(leafName);
/* if it's not javaExtension return now */
if (len < javaExtensionLen || // too short
PL_strcasecmp(leafName + len - javaExtensionLen, javaExtension))
return NS_OK;
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader: registering urpComponent component %s\n",(const char *)leafName));
rv = AttemptRegistration(component, PR_FALSE);
if (NS_SUCCEEDED(rv))
PR_LOG(log, PR_LOG_DEBUG, ("registered module %s\n", (const char *)leafName));
else if (rv == NS_ERROR_FACTORY_REGISTER_AGAIN)
PR_LOG(log, PR_LOG_DEBUG, ("deferred module %s\n", (const char *)leafName));
else
PR_LOG(log, PR_LOG_DEBUG, ("failed to register %s\n", (const char *)leafName));
*registered = (PRBool) NS_SUCCEEDED(rv);
return NS_OK;
}
nsresult urpComponentLoader::AttemptRegistration(nsIFile *component,
PRBool deferred) {
nsXPIDLCString registryLocation;
nsresult rv;
nsIModule *module;
rv = mCompMgr->RegistryLocationForSpec(component,
getter_Copies(registryLocation));
nsXPIDLCString str;
component->GetPath(getter_Copies(str));
const char* location = nsCRT::strdup(str);
ifstream in(location);
char cidStr[500], contractid[1000], desc[1000];
in.getline(cidStr,1000);
in.getline(contractid,1000);
in.getline(desc,1000);
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("%s %s %s", cidStr, contractid, desc));
nsCID cid;
cid.Parse((const char *)cidStr);
mCompMgr->RegisterComponentWithType(cid, desc, contractid, component, registryLocation, PR_TRUE, PR_TRUE, urpComponentTypeName);
if (NS_FAILED(rv))
return rv;
/* no need to check registry data on deferred reg */
SetRegistryInfo(registryLocation, component);
return rv;
}
nsresult urpComponentLoader::SetRegistryInfo(const char *registryLocation,
nsIFile *component)
{
if (!mRegistry.get())
return NS_OK; // silent failure
nsresult rv;
nsRegistryKey key;
rv = mRegistry->AddSubtreeRaw(mXPCOMKey, registryLocation, &key);
if (NS_FAILED(rv))
return rv;
PRInt64 modDate;
if (NS_FAILED(rv = component->GetLastModifiedTime(&modDate)) ||
NS_FAILED(rv = mRegistry->SetLongLong(key, lastModValueName, &modDate)))
return rv;
PRInt64 fileSize;
if (NS_FAILED(rv = component->GetFileSize(&fileSize)) ||
NS_FAILED(rv = mRegistry->SetLongLong(key, fileSizeValueName, &fileSize)))
return rv;
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("SetRegistryInfo(%s) => (%d,%d)\n", registryLocation,
(int)modDate, (int)fileSize));
return NS_OK;
}
PRBool urpComponentLoader::HasChanged(const char *registryLocation, nsIFile *component) {
/* if we don't have a registry handle, force registration of component */
if (!mRegistry)
return PR_TRUE;
nsRegistryKey key;
if (NS_FAILED(mRegistry->GetSubtreeRaw(mXPCOMKey, registryLocation, &key)))
return PR_TRUE;
/* check modification date */
PRInt64 regTime, lastTime;
if (NS_FAILED(mRegistry->GetLongLong(key, lastModValueName, &regTime)))
return PR_TRUE;
if (NS_FAILED(component->GetLastModifiedTime(&lastTime)) || LL_NE(lastTime, regTime))
return PR_TRUE;
/* check file size */
PRInt64 regSize;
if (NS_FAILED(mRegistry->GetLongLong(key, fileSizeValueName, &regSize)))
return PR_TRUE;
PRInt64 size;
if (NS_FAILED(component->GetFileSize(&size)) || LL_NE(size,regSize) )
return PR_TRUE;
return PR_FALSE;
}
/**
* Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.
* Return registered-any-components?
*/
/* boolean registerDeferredComponents (in long aWhen); */
NS_IMETHODIMP urpComponentLoader::RegisterDeferredComponents(PRInt32 aWhen, PRBool *aRegistered) {
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::RegisterDeferredComponents \n"));
nsresult rv;
*aRegistered = PR_FALSE;
PRUint32 count;
rv = mDeferredComponents.Count(&count);
printf("mJCL: registering deferred (%d)\n", count);
if (NS_FAILED(rv) || !count)
return NS_OK;
for (PRUint32 i = 0; i < count; i++) {
nsCOMPtr<nsISupports> supports;
nsCOMPtr<nsIFile> component;
rv = mDeferredComponents.GetElementAt(i, getter_AddRefs(supports));
if (NS_FAILED(rv))
continue;
component = do_QueryInterface(supports, &rv);
if (NS_FAILED(rv))
continue;
rv = AttemptRegistration(component, PR_TRUE /* deferred */);
if (rv != NS_ERROR_FACTORY_REGISTER_AGAIN) {
if (NS_SUCCEEDED(rv))
*aRegistered = PR_TRUE;
mDeferredComponents.RemoveElementAt(i);
}
}
rv = mDeferredComponents.Count(&count);
if (NS_SUCCEEDED(rv)) {
if (*aRegistered)
printf("mJCL: registered deferred, %d left\n", count);
else
printf("mJCL: didn't register any components, %d left\n", count);
}
/* are there any fatal errors? */
return NS_OK;
}
/**
* Unload all components that are willing.
*/
/* void unloadAll (in long aWhen); */
NS_IMETHODIMP urpComponentLoader::UnloadAll(PRInt32 aWhen) { //nb
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("--urpComponentLoader::UnloadAll \n"));
return NS_OK;
}
//---------------------------------------------------------------------------------------------------
/* XXX this should all be data-driven, via NS_IMPL_GETMODULE_WITH_CATEGORIES */
static NS_METHOD
RegisterRemoteLoader(nsIComponentManager *aCompMgr, nsIFile *aPath,
const char *registryLocation, const char *componentType, const nsModuleComponentInfo *info)
{
PRLogModuleInfo *log = urpLog::GetLog();
nsresult rv;
nsCOMPtr<nsICategoryManager> catman =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
PR_LOG(log, PR_LOG_DEBUG, ("--URPLoader got registered\n"));
if (NS_FAILED(rv)) return rv;
nsXPIDLCString previous;
rv = catman->AddCategoryEntry("component-loader", urpComponentTypeName,
URP_COMPONENTLOADER_ContractID,
PR_TRUE, PR_TRUE, getter_Copies(previous));
if(NS_FAILED(rv))
PR_LOG(log, PR_LOG_DEBUG, ("Adding of remote-comp-loader is failed\n"));
else
PR_LOG(log, PR_LOG_DEBUG, ("Adding of remote-comp-loader is succeseded\n"));
nsXPIDLCString urpLoader;
rv = catman->GetCategoryEntry("component-loader", urpComponentTypeName,
getter_Copies(urpLoader));
if (NS_FAILED(rv))
PR_LOG(log, PR_LOG_DEBUG, ("didn't got category entry\n"));
else
PR_LOG(log, PR_LOG_DEBUG, ("got category entry\n"));
return rv;
}
static NS_METHOD
UnregisterRemoteLoader(nsIComponentManager *aCompMgr, nsIFile *aPath,
const char *registryLocation, const nsModuleComponentInfo *info)
{
nsresult rv;
nsCOMPtr<nsICategoryManager> catman =
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsXPIDLCString urpLoader;
PRLogModuleInfo *log = urpLog::GetLog();
PR_LOG(log, PR_LOG_DEBUG, ("URP component loader is being unregistered\n"));
rv = catman->GetCategoryEntry("component-loader", urpComponentTypeName,
getter_Copies(urpLoader));
if (NS_FAILED(rv)) return rv;
// only unregister if we're the current JS component loader
if (!strcmp(urpLoader, URP_COMPONENTLOADER_ContractID)) {
return catman->DeleteCategoryEntry("component-loader",
urpComponentTypeName, PR_TRUE,
getter_Copies(urpLoader));
}
return NS_OK;
}
NS_GENERIC_FACTORY_CONSTRUCTOR(urpComponentLoader);
static nsModuleComponentInfo components[] = {
{ "URP component loader", URP_COMPONENTLOADER_CID,
URP_COMPONENTLOADER_ContractID,
urpComponentLoaderConstructor,
RegisterRemoteLoader, UnregisterRemoteLoader }
};
NS_IMPL_NSGETMODULE("URP component loader", components);