Back to index

lightning-sunbird  0.9+nobinonly
nsComponentManager.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef nsComponentManager_h__
00039 #define nsComponentManager_h__
00040 
00041 #include "nsXPCOM.h"
00042 
00043 #include "nsIComponentLoader.h"
00044 #include "xpcom-private.h"
00045 #include "nsNativeComponentLoader.h"
00046 #include "nsIComponentManager.h"
00047 #include "nsIComponentRegistrar.h"
00048 #include "nsIComponentManagerObsolete.h"
00049 #include "nsIComponentLoaderManager.h"
00050 #include "nsCategoryManager.h"
00051 #include "nsIServiceManager.h"
00052 #include "nsIFactory.h"
00053 #include "nsIInterfaceRequestor.h"
00054 #include "nsIInterfaceRequestorUtils.h"
00055 #include "pldhash.h"
00056 #include "prtime.h"
00057 #include "prmon.h"
00058 #include "nsCOMPtr.h"
00059 #include "nsWeakReference.h"
00060 #include "nsXPIDLString.h"
00061 #include "nsIFile.h"
00062 #include "plarena.h"
00063 
00064 class nsFactoryEntry;
00065 class nsDll;
00066 class nsIServiceManager;
00067 
00068 #define NS_COMPONENTMANAGER_CID                      \
00069 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */         \
00070     0x91775d60,                                      \
00071     0xd5dc,                                          \
00072     0x11d2,                                          \
00073     {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
00074 }
00075 
00076 /* keys for registry use */
00077 extern const char xpcomKeyName[];
00078 extern const char xpcomComponentsKeyName[];
00079 extern const char lastModValueName[];
00080 extern const char fileSizeValueName[];
00081 extern const char nativeComponentType[];
00082 extern const char staticComponentType[];
00083 
00084 // Predefined loader types. Do not change the numbers.
00085 // NATIVE should be 0 as it is being used as the first array index.
00086 #define NS_COMPONENT_TYPE_NATIVE 0
00087 #define NS_COMPONENT_TYPE_FACTORY_ONLY -1
00088 // this define means that the factory entry only has a ContractID 
00089 // to service mapping and has no cid mapping.
00090 #define NS_COMPONENT_TYPE_SERVICE_ONLY -2
00091 
00092 
00093 #ifdef DEBUG
00094 #define XPCOM_CHECK_PENDING_CIDS
00095 #endif
00096 
00097 
00098 // Array of Loaders and their type strings
00099 struct nsLoaderdata {
00100     nsIComponentLoader *loader;
00101     const char *type;
00102 };
00103 
00104 class nsComponentManagerImpl
00105     : public nsIComponentManager,
00106       public nsIServiceManager,
00107       public nsIComponentRegistrar,
00108       public nsSupportsWeakReference,
00109       public nsIInterfaceRequestor,
00110       public nsIComponentLoaderManager,
00111       public nsIServiceManagerObsolete,
00112       public nsIComponentManagerObsolete
00113 {
00114 public:
00115     NS_DECL_ISUPPORTS
00116     NS_DECL_NSIINTERFACEREQUESTOR
00117     // Since the nsIComponentManagerObsolete and nsIComponentManager share some of the 
00118     // same interface function names, we have to manually define the functions here.
00119     // The only function that is in nsIComponentManagerObsolete and is in nsIComponentManager
00120     // is GetClassObjectContractID.  
00121     //
00122     // nsIComponentManager function not in nsIComponentManagerObsolete:
00123     NS_IMETHOD GetClassObjectByContractID(const char *aContractID,
00124                                           const nsIID &aIID,
00125                                           void **_retval);
00126 
00127 
00128     NS_DECL_NSICOMPONENTMANAGEROBSOLETE
00129 
00130     // Since the nsIComponentManagerObsolete and nsIComponentRegistrar share some of the
00131     // same interface function names, we have to manually define the functions here.
00132     // the only function that is shared is UnregisterFactory
00133     NS_IMETHOD AutoRegister(nsIFile *aSpec); 
00134     NS_IMETHOD AutoUnregister(nsIFile *aSpec); 
00135     NS_IMETHOD RegisterFactory(const nsCID & aClass, const char *aClassName, const char *aContractID, nsIFactory *aFactory); 
00136     //  NS_IMETHOD UnregisterFactory(const nsCID & aClass, nsIFactory *aFactory); 
00137     NS_IMETHOD RegisterFactoryLocation(const nsCID & aClass, const char *aClassName, const char *aContractID, nsIFile *aFile, const char *loaderStr, const char *aType); 
00138     NS_IMETHOD UnregisterFactoryLocation(const nsCID & aClass, nsIFile *aFile); 
00139     NS_IMETHOD IsCIDRegistered(const nsCID & aClass, PRBool *_retval); 
00140     NS_IMETHOD IsContractIDRegistered(const char *aClass, PRBool *_retval); 
00141     NS_IMETHOD EnumerateCIDs(nsISimpleEnumerator **_retval); 
00142     NS_IMETHOD EnumerateContractIDs(nsISimpleEnumerator **_retval); 
00143     NS_IMETHOD CIDToContractID(const nsCID & aClass, char **_retval); 
00144     NS_IMETHOD ContractIDToCID(const char *aContractID, nsCID * *_retval); 
00145     
00146     NS_DECL_NSISERVICEMANAGER
00147     NS_DECL_NSISERVICEMANAGEROBSOLETE
00148     NS_DECL_NSICOMPONENTLOADERMANAGER
00149 
00150     // nsComponentManagerImpl methods:
00151     nsComponentManagerImpl();
00152 
00153     static nsComponentManagerImpl* gComponentManager;
00154     nsresult Init(nsStaticModuleInfo const *aStaticModules,
00155                   PRUint32 aStaticModuleCount);
00156 
00157     nsresult WritePersistentRegistry();
00158     nsresult ReadPersistentRegistry();
00159 
00160     nsresult Shutdown(void);
00161 
00162     nsresult FreeServices();
00163 
00164     nsresult
00165     NS_GetService(const char *aContractID, const nsIID& aIID, PRBool aDontCreate, nsISupports** result);
00166 
00167     nsresult RegisterComponentCommon(const nsCID &aClass,
00168                                      const char *aClassName,
00169                                      const char *aContractID,
00170                                      PRUint32 aContractIDLen,
00171                                      const char *aRegistryName,
00172                                      PRUint32 aRegistryNameLen,
00173                                      PRBool aReplace, PRBool aPersist,
00174                                      const char *aType);
00175     nsresult GetLoaderForType(int aType, 
00176                               nsIComponentLoader **aLoader);
00177     nsresult FindFactory(const char *contractID, PRUint32 aContractIDLen, nsIFactory **aFactory) ;
00178     nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
00179 
00180     nsFactoryEntry *GetFactoryEntry(const char *aContractID,
00181                                     PRUint32 aContractIDLen);
00182     nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
00183 
00184     nsresult SyncComponentsInDir(PRInt32 when, nsIFile *dirSpec);
00185     nsresult SelfRegisterDll(nsDll *dll);
00186     nsresult SelfUnregisterDll(nsDll *dll);
00187     nsresult HashContractID(const char *acontractID, PRUint32 aContractIDLen,
00188                             nsFactoryEntry *fe_ptr);
00189 
00190     void DeleteContractIDEntriesByCID(const nsCID* aClass, const char*registryName);
00191     void DeleteContractIDEntriesByCID(const nsCID* aClass, nsIFactory* factory);
00192 
00193     nsresult UnloadLibraries(nsIServiceManager *servmgr, PRInt32 when);
00194     
00195     // Convert a loader type string into an index into the loader data
00196     // array. Empty loader types are converted to NATIVE. Returns -1 if
00197     // loader type cannot be determined.
00198     int GetLoaderType(const char *typeStr);
00199 
00200     // Add a loader type if not already known. Out the typeIndex
00201     // if the loader type is either added or already there;
00202     // returns NS_OK or an error on failure.
00203     nsresult AddLoaderType(const char *typeStr, int *typeIndex);
00204 
00205     int GetLoaderCount() { return mNLoaderData + 1; }
00206 
00207     // registers only the files in spec's location by loaders other than the
00208     // native loader.  This is an optimization method only.
00209     nsresult AutoRegisterNonNativeComponents(nsIFile* spec);
00210 
00211     nsresult AutoRegisterImpl(PRInt32 when, nsIFile *inDirSpec, PRBool fileIsCompDir=PR_TRUE);
00212     nsresult RemoveEntries(nsIFile* file);
00213 
00214     PLDHashTable        mFactories;
00215     PLDHashTable        mContractIDs;
00216     PRMonitor*          mMon;
00217 
00218     nsNativeComponentLoader *mNativeComponentLoader;
00219     nsIComponentLoader  *mStaticComponentLoader;
00220     nsCOMPtr<nsIFile>   mComponentsDir;
00221     PRInt32             mComponentsOffset;
00222 
00223     nsCOMPtr<nsIFile>   mGREComponentsDir;
00224     PRInt32             mGREComponentsOffset;
00225 
00226     nsCOMPtr<nsIFile>   mRegistryFile;
00227 
00228     // Shutdown
00229     #define NS_SHUTDOWN_NEVERHAPPENED 0
00230     #define NS_SHUTDOWN_INPROGRESS 1
00231     #define NS_SHUTDOWN_COMPLETE 2
00232     PRUint32 mShuttingDown;
00233 
00234     nsLoaderdata *mLoaderData;
00235     int mNLoaderData;
00236     int mMaxNLoaderData;
00237 
00238     PRBool              mRegistryDirty;
00239     nsHashtable         mAutoRegEntries;
00240     nsCOMPtr<nsCategoryManager>  mCategoryManager;
00241 
00242     PLArenaPool   mArena;
00243 
00244 #ifdef XPCOM_CHECK_PENDING_CIDS
00245     nsresult AddPendingCID(const nsCID &aClass);
00246     void RemovePendingCID(const nsCID &aClass);
00247 
00248     nsVoidArray         mPendingCIDs;
00249 #endif
00250 
00251 private:
00252     ~nsComponentManagerImpl();
00253 };
00254 
00255 
00256 #define NS_MAX_FILENAME_LEN 1024
00257 
00258 #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
00259 
00261 
00275 class nsFactoryEntry {
00276 public:
00277     nsFactoryEntry(const nsCID &aClass,
00278                    const char *location, PRUint32 locationlen, int aType, class nsFactoryEntry* parent = nsnull);
00279     nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory, class nsFactoryEntry* parent = nsnull);
00280     ~nsFactoryEntry();
00281 
00282     nsresult ReInit(const nsCID &aClass, const char *location, int aType);
00283 
00284     nsresult GetFactory(nsIFactory **aFactory, 
00285                         nsComponentManagerImpl * mgr) {
00286         if (mFactory) {
00287             *aFactory = mFactory.get();
00288             NS_ADDREF(*aFactory);
00289             return NS_OK;
00290         }
00291 
00292         if (mTypeIndex < 0)
00293             return NS_ERROR_FAILURE;
00294 
00295         nsresult rv;
00296         nsCOMPtr<nsIComponentLoader> loader;
00297         rv = mgr->GetLoaderForType(mTypeIndex, getter_AddRefs(loader));
00298         if(NS_FAILED(rv))
00299             return rv;
00300 
00301         rv = loader->GetFactory(mCid, mLocation, mgr->mLoaderData[mTypeIndex].type, aFactory);
00302         if (NS_FAILED(rv))
00303             return rv;
00304 
00305         NS_ASSERTION(*aFactory, "Loader says it succeeded; got null factory!");
00306         mFactory = do_QueryInterface(*aFactory);
00307         if (!mFactory)
00308             return NS_ERROR_NO_INTERFACE;
00309 
00310         return NS_OK;
00311     }
00312 
00313     nsCID mCid;
00314     nsCOMPtr<nsIFactory> mFactory;
00315     // This is an index into the mLoaderData array that holds the type string and the loader 
00316     int mTypeIndex;
00317     nsCOMPtr<nsISupports> mServiceObject;
00318     char* mLocation;
00319     class nsFactoryEntry* mParent;
00320 };
00321 
00323 
00324 struct nsFactoryTableEntry : public PLDHashEntryHdr {
00325     nsFactoryEntry *mFactoryEntry;    
00326 };
00327 
00328 struct nsContractIDTableEntry : public PLDHashEntryHdr {
00329     char           *mContractID;
00330     PRUint32        mContractIDLen;
00331     nsFactoryEntry *mFactoryEntry;    
00332 };
00333 
00334 
00335 class AutoRegEntry
00336 {
00337 public:
00338     AutoRegEntry(const nsACString& name, PRInt64* modDate);
00339     ~AutoRegEntry();
00340 
00341     const nsDependentCString GetName()
00342       { return nsDependentCString(mName, mNameLen); }
00343     PRInt64 GetDate() {return mModDate;}
00344     void    SetDate(PRInt64 *date) { mModDate = *date;}
00345     PRBool  Modified(PRInt64 *date);
00346 
00347     // this is the optional field line in the compreg.dat.
00348     // it must not contain any comma's and it must be null terminated.
00349     char*   GetOptionalData() {return mData;};
00350     void    SetOptionalData(const char* data);
00351 
00352 private:
00353     char*   mName;
00354     PRUint32 mNameLen;
00355     char*   mData;
00356     PRInt64 mModDate;
00357 };
00358 #endif // nsComponentManager_h__
00359