Fix case and return value in nsIModule.idl.

Add deleteCategoryEntry and deleteCategory to nsICategoryManager.
Update nsCategoryManager.js to use new nsIModule case, and talk to the registry.
r=brendan
This commit is contained in:
shaver%netscape.com 1999-10-15 20:51:38 +00:00
Родитель 1233fa6fe9
Коммит ee850bb6c5
3 изменённых файлов: 235 добавлений и 80 удалений

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

@ -18,123 +18,263 @@
function CategoryManager() {
this.categories = { };
this.loadRegistryData(this);
}
function NYI () { throw Components.results.NS_ERROR_NOT_IMPLEMENTED; }
function NYI() { throw Components.results.NS_ERROR_NOT_IMPLEMENTED; }
var proto = CategoryManager.prototype;
var nsICategoryManager = Components.interfaces.nsICategoryManager;
var categoriesKey; // registry key for category data
var registry; // registry handle
proto.getCategoryEntry = function (category, entry) {
var cat = this.categories[category];
if (!cat)
return null;
return null;
if ("override" in cat)
return cat.override.getCategoryEntry(category, entry);
return cat.override.getCategoryEntry(category, entry);
var table = cat.table;
if (entry in table)
return table[entry];
if ("fallback" in cat) {
dump("\n--fallback: " + cat.fallback + "\n");
return cat.fallback.getCategoryEntry(category, entry);
}
return table[entry];
if ("fallback" in cat)
return cat.fallback.getCategoryEntry(category, entry);
return null;
};
proto.getCategoryEntryRaw = function (category, entry) {
var table;
var cat = this.categories[category];
if (!cat ||
(!entry in (table = cat.table)))
return null;
if (!(cat && entry in (table = cat.table)))
return null;
if (entry in table)
return table[entry];
return table[entry];
if ("fallback" in cat)
return cat.fallback.getCategoryEntry(category, entry);
return cat.fallback.getCategoryEntry(category, entry);
return null;
}
proto.addCategoryEntry = function (category, entry, value, persist, replace) {
if (!(category in this.categories)) {
dump("aCE: creating category \"" + category + "\"\n");
this.categories[category] = { name:category, table:{ } };
function addEntryToRegistry(category, entry, value)
{
var categorySubtree;
try {
categorySubtree = registry.getSubtreeRaw(categoriesKey, category);
} catch (e :
e instanceof Components.interfaces.nsIXPCException &&
e.result === 0x80510003 /* XXX NS_ERROR_REG_NOT_FOUND */) {
categorySubtree = registry.addSubtreeRaw(categoriesKey, category);
}
registry.setString(categorySubtree, entry, value);
}
proto.addCategoryEntry = function (category, entry, value, persist, replace) {
if (!(category in this.categories))
this.categories[category] = { name:category, table:{ } };
var table = this.categories[category].table;
var oldValue;
if (entry in table) {
if (!replace)
throw Components.results.NS_ERROR_INVALID_ARG;
oldValue = table[entry];
if (!replace)
throw Components.results.NS_ERROR_INVALID_ARG;
oldValue = table[entry];
} else {
oldValue = null;
oldValue = null;
}
table[entry] = value;
if (persist)
// need registry
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
addEntryToRegistry(category, entry, value);
return oldValue;
}
proto.enumerateCategory = NYI;
function deleteEntryFromRegistry(category, entry)
{
dump("(not) deleting " + category + "[" + entry + "] from reg\n");
try {
var categorySubtree = registry.getSubtreeRaw(categoriesKey, category);
/* registry.deleteValue(categorySubtree, entry); */
} catch (e :
e instanceof Components.interfaces.nsIXPCException &&
e.result === 0x80510003 /* XXX NS_ERROR_REG_NOT_FOUND */) {
return false;
}
return true;
}
proto.deleteCategoryEntry = function (category, entry, persist) {
if (!(category in this.categories))
return null;
var table = this.categories[category].table;
var old = table[entry];
delete table[entry];
if (persist)
deleteEntryFromRegistry(category, entry);
return old;
};
function deleteCategoryFromRegistry(category) {
try {
registry.removeSubtreeRaw(categoriesKey, category);
} catch (e :
e instanceof Components.interfaces.nsIXPCException &&
e.result === 0x80510003 /* XXX NS_ERROR_REG_NOT_FOUND */) {
return false;
}
return true;
}
proto.deleteCategory = function (category, persist) {
delete this.categories[category];
/*
* Don't check for delete success, because persist means to remove from
* registry, even if someone has already done a non-persistent removal
* before.
*/
if (persist)
deleteCategoryFromRegistry(category);
};
function CategoryEnumerator(category) {
this.category = category;
};
proto.enumerateCategory = function (category) {
return new CategoryEnumerator(this.categories[category] || { });
}
proto.getCategoryContents = NYI;
proto.registerCategoryHandler = function(category, handler, mode) {
dump("nCM: handler.getCategoryEntry: " + handler.getCategoryEntry + "\n");
dump("typeof handler: " + typeof handler + "\n");
/*
dump('rCH: "' + category + '".' +
(mode == nsICategoryManager.fallback ? "fallback" :
(mode == nsICategoryManager.override ? "override" :
mode)) + " = " + handler + "\n");
*/
if (!(category in this.categories)) {
dump("rCH: creating category \"" + category + "\"\n");
this.categories[category] = { table:{ } };
}
if (!(category in this.categories))
this.categories[category] = { table:{ } };
var old;
var category = this.categories[category];
if (mode == nsICategoryManager.override) {
old = category.override || null;
category.override = handler;
} else if (mode == nsICategoryManager.fallback) {
old = category.fallback || null;
category.fallback = handler;
if (mode == nsICategoryManager.OVERRIDE) {
old = category.override || null;
category.override = handler;
} else if (mode == nsICategoryManager.FALLBACK) {
old = category.fallback || null;
category.fallback = handler;
} else {
dump("\nregisterCategoryHandler: illegal mode " + mode + "\n\n");
throw Components.results.NS_ERROR_INVALID_ARG;
}
/* XXX shaver: store CID in the registry, repopulate at startup? */
return old;
};
proto.unregisterCategoryHandler = NYI;
var module = {
RegisterSelf:function (compMgr, fileSpec, location, type) {
compMgr.registerComponentWithType(this.myCID,
"Category Manager",
"mozilla.categorymanager.1",
fileSpec, location, true, true,
type);
},
GetClassObject:function (compMgr, cid, iid) {
if (!cid.equals(this.myCID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
proto.loadRegistryData = function() {
var nsIRegistry = Components.interfaces.nsIRegistry;
registry = Components.classes["component://netscape/registry"].
createInstance(nsIRegistry);
registry.openWellKnownRegistry(nsIRegistry.ApplicationComponentRegistry);
try {
categoriesKey =
registry.getSubtree(nsIRegistry.Common,
"Software/Mozilla/XPCOM/Categories");
} catch (e :
e instanceof Components.interfaces.nsIXPCException &&
e.result === 0x80510003 /* XXX NS_ERROR_REG_NOT_FOUND */) {
dump("creating Categories registry point\n");
categoriesKey =
registry.addSubtree(nsIRegistry.Common,
"Software/Mozilla/XPCOM/Categories");
return;
}
return this.myFactory;
var en = registry.enumerateSubtrees(categoriesKey);
/*
* Waterson's right: the nsIEnumerator interface is basically
* complete crap. There is no way to do anything, really, without
* gobs of exceptions and other nonsense, because apparently boolean
* out parameters are rocket science.
*
* And don't get me started about COMFALSE. (I'm sure this seemed like
* a good idea at the time, but it really sucks right now.)
*
* Do not look directly at the following code.
*/
try { en.first(); } catch (e) { return; }
while (en.isDone(), Components.lastResult != Components.results.NS_OK) {
try {
node = en.currentItem();
node = node.QueryInterface(Components.interfaces.nsIRegistryNode);
} catch (e : e instanceof Components.interfaces.nsIXPCException) {
try { en.next(); } catch (e) { }
continue;
}
var category = node.name;
var catenum = registry.enumerateValues(node.key);
try {
catenum.first();
} catch (e) {
continue;
}
while(catenum.isDone(),
Components.lastResult != Components.results.NS_OK) {
var entry;
try {
entry = catenum.currentItem();
entry = entry.QueryInterface(Components.interfaces.nsIRegistryValue);
} catch (e : e instanceof Components.interfaces.nsIXPCException) {
dump("not a value?\n");
try { catenum.next(); } catch (e) { }
continue;
}
try {
var value = registry.getString(node.key, entry.name);
this.addCategoryEntry(category, entry.name, value);
} catch (e) {
dump ("no " + entry.name + " in " + category + "?\n");
}
try { catenum.next(); } catch (e) { }
}
try { en.next(); } catch (e) { }
}
}
var module = {
registerSelf: function (compMgr, fileSpec, location, type) {
compMgr.registerComponentWithType(this.myCID,
"Category Manager",
"mozilla.categorymanager.1",
fileSpec, location, true, true,
type);
},
myCID:Components.ID("{16d222a6-1dd2-11b2-b693-f38b02c021b2}"),
myFactory:{
CreateInstance:function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!(iid.equals(nsICategoryManager) ||
iid.equals(Components.interfaces.nsISupports)))
throw Components.results.NS_ERROR_INVALID_ARG;
return new CategoryManager();
}
getClassObject: function (compMgr, cid, iid) {
if (!cid.equals(this.myCID))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!iid.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return this.myFactory;
},
canUnload: function () {
dump("unloading category manager\n");
try { registry.close(); } catch (e) { }
},
myCID: Components.ID("{16d222a6-1dd2-11b2-b693-f38b02c021b2}"),
myFactory: {
CreateInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!(iid.equals(nsICategoryManager) ||
iid.equals(Components.interfaces.nsISupports))) {
throw Components.results.NS_ERROR_INVALID_ARG;
}
return new CategoryManager();
}
}
};
function NSGetModule(compMgr, fileSpec) { return module; }

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

@ -44,17 +44,34 @@ interface nsICategoryManager : nsISupports
* @param aValue The value for the entry ("moz.httprulez.1")
* @param aPersist Should we persist between invocations?
* @param aReplace Should we replace an existing entry?
* @return previous entry, if any
* @return Previous entry, if any
*/
string addCategoryEntry(in string aCategory, in string aEntry,
in string aValue, in boolean aPersist,
in boolean aReplace);
/**
* Delete an entry from the category.
* @param aCategory The name of the category ("protocol")
* @param aEntry The entry to be added ("http")
* @param aPersist Delete entry from registry, if present?
* @return Previous entry, null if none.
*/
string deleteCategoryEntry(in string aCategory, in string aEntry,
in boolean aPersist);
/**
* Delete a category and all entries.
* @param aCategory The category to be deleted.
* @param aPersist Delete the category from the registry?
*/
void deleteCategory(in string aCategory);
/**
* Enumerate the entries in a category.
* @param aCategory The category to be enumerated.
*/
nsIEnumerator enumerateCategory(in string aCategory);
nsISimpleEnumerator enumerateCategory(in string aCategory);
/**
* Get all the category contents.
@ -64,10 +81,8 @@ interface nsICategoryManager : nsISupports
[array, size_is(count)] out string values,
[retval] out long count);
const long override = 0;
const long fallback = 1;
const long checkFirst = 0;
const long checkLast = 1;
const long OVERRIDE = 0;
const long FALLBACK = 1;
/*
* Register a category handler for override or fallback when

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

@ -29,25 +29,25 @@ interface nsIModule : nsISupports
// create new objects.
// SingletonFactory can be queried off the Class Object. Services can be created
// using the singletonfactory.
void GetClassObject(in nsIComponentManager aCompMgr, in nsCIDRef aClass,
void getClassObject(in nsIComponentManager aCompMgr, in nsCIDRef aClass,
in nsIIDRef aIID,
[retval, iid_is(aIID)] out nsQIResult result);
// Component registration
void RegisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
void registerSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
in string registryLocation, in string componentType);
void UnregisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
void unregisterSelf(in nsIComponentManager aCompMgr, in nsIFileSpec location,
in string registryLocation);
// Module load management
// okToUnload: indicates to the caller if the module can be unloaded.
// @return indicates to the caller if the module can be unloaded.
// Returning PR_TRUE isn't a guarantee that the module will be
// unloaded. It constitues only willingness of the module to be
// unloaded.
// Returning PR_FALSE guaratees that the module wont be unloaded.
//
void CanUnload(in nsIComponentManager aCompMgr, out boolean okToUnload);
boolean canUnload(in nsIComponentManager aCompMgr);
};
%{C++