зеркало из https://github.com/mozilla/pjs.git
Fix for bug 83360 (improve LDAP datasource usefulness with XUL templates). r=dmose. Not part of the build.
This commit is contained in:
Родитель
8e3d01a5a8
Коммит
4cd94f04f3
|
@ -50,6 +50,17 @@ const NS_RDF_NO_VALUE = NS_ERROR_RDF_BASE + 2;
|
|||
const NS_RDF_ASSERTION_ACCEPTED = Components.results.NS_OK;
|
||||
const NS_RDF_ASSERTION_REJECTED = NS_ERROR_RDF_BASE + 3;
|
||||
|
||||
// Scope constants
|
||||
//
|
||||
const SCOPE_BASE = Components.interfaces.nsILDAPURL.SCOPE_BASE;
|
||||
const SCOPE_ONELEVEL = Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL;
|
||||
const SCOPE_SUBTREE = Components.interfaces.nsILDAPURL.SCOPE_SUBTREE;
|
||||
|
||||
// Types of delegates
|
||||
const MESSAGE = 1;
|
||||
const FLAT_LIST = 2;
|
||||
const RECURSIVE_LIST = 3;
|
||||
|
||||
// ArrayEnumerator courtesy of Brendan Eich <brendan@mozilla.org>
|
||||
//
|
||||
function ArrayEnumerator(array) {
|
||||
|
@ -119,7 +130,10 @@ nsLDAPDataSource.prototype = {
|
|||
// make it hard for the datasource and/or component to be GCed?
|
||||
//
|
||||
kRDF_instanceOf: {},
|
||||
kNC_DN: {},
|
||||
kNC_child: {},
|
||||
kNC_recursiveChild: {},
|
||||
|
||||
mRdfSvc: {},
|
||||
|
||||
// since we implement multiple interfaces, we have to provide QI
|
||||
|
@ -134,6 +148,26 @@ nsLDAPDataSource.prototype = {
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIRDFRemoteDataSource
|
||||
*/
|
||||
|
||||
/**
|
||||
* This value is <code>true</code> when the datasource has
|
||||
* fully loaded itself.
|
||||
*/
|
||||
get loaded() {
|
||||
debug("getter for loaded called\n");
|
||||
// We're never fully loaded
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify the URI for the data source: this is the prefix
|
||||
* that will be used to register the data source in the
|
||||
* data source registry.
|
||||
* @param aURI the URI to load
|
||||
*/
|
||||
Init: function(aURI)
|
||||
{
|
||||
if (DEBUG) {
|
||||
|
@ -160,15 +194,43 @@ nsLDAPDataSource.prototype = {
|
|||
|
||||
// get some RDF Resources that we'll need
|
||||
//
|
||||
this.kRDF_instanceOf = this.mRdfSvc.GetResource( RDF_NAMESPACE_URI +
|
||||
this.kRDF_instanceOf = this.mRdfSvc.GetResource(RDF_NAMESPACE_URI +
|
||||
"instanceOf");
|
||||
this.kNC_child = this.mRdfSvc.GetResource( NC_NAMESPACE_URI + "child");
|
||||
this.kNC_Folder = this.mRdfSvc.GetResource( NC_NAMESPACE_URI +
|
||||
"Folder");
|
||||
this.kNC_DN = this.mRdfSvc.GetResource(NC_NAMESPACE_URI + "DN");
|
||||
this.kNC_child = this.mRdfSvc.GetResource(NC_NAMESPACE_URI + "child");
|
||||
this.kNC_recursiveChild = this.mRdfSvc.GetResource(NC_NAMESPACE_URI +
|
||||
"recursiveChild");
|
||||
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh the remote datasource, re-loading its contents
|
||||
* from the URI.
|
||||
*
|
||||
* @param aBlocking If <code>true</code>, the call will block
|
||||
* until the datasource has completely reloaded.
|
||||
*/
|
||||
Refresh: function(aBlocking)
|
||||
{
|
||||
if (DEBUG) {
|
||||
dump("Refresh() called with args: \n\t" + aBlocking + "\n\n");
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request that a data source write it's contents out to
|
||||
* permanent storage, if applicable.
|
||||
*/
|
||||
Flush: function()
|
||||
{
|
||||
if (DEBUG) {
|
||||
dump("Flush() called\n\n");
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIRDFDataSource
|
||||
*/
|
||||
|
@ -216,7 +278,7 @@ nsLDAPDataSource.prototype = {
|
|||
|
||||
/**
|
||||
* Find a child of that is related to the source by the given arc
|
||||
* arc and truth value
|
||||
* and truth value
|
||||
*
|
||||
* @return NS_RDF_NO_VALUE if there is no target accessable from the
|
||||
* source via the specified property.
|
||||
|
@ -231,31 +293,68 @@ nsLDAPDataSource.prototype = {
|
|||
"\n\t" + aProperty.Value + "\n\t" + aTruthValue + "\n\n");
|
||||
}
|
||||
|
||||
// We don't handle negative assertions.
|
||||
// XXX Should we? Can we?
|
||||
if (!aTruthValue) {
|
||||
Components.returnCode = NS_RDF_NO_VALUE;
|
||||
return null;
|
||||
}
|
||||
|
||||
var delegate;
|
||||
var enumerator;
|
||||
|
||||
if (aProperty.EqualsNode(this.kNC_child)) {
|
||||
if (aProperty.EqualsNode(this.kNC_child)
|
||||
|| aProperty.EqualsNode(this.kNC_recursiveChild)) {
|
||||
// Find a child or recursiveChild. Get the messagelist delegate
|
||||
// (flat for child, recursive for recursiveChild) for aSource and
|
||||
// return the first element of the list, if available.
|
||||
var listType = (aProperty.EqualsNode(this.kNC_child) ?
|
||||
"flat.messagelist.ldap" :
|
||||
"recursive.messagelist.ldap");
|
||||
try {
|
||||
delegate = aSource.GetDelegate("messagelist.ldap",
|
||||
delegate = aSource.GetDelegate(listType,
|
||||
Components.interfaces.nsISupportsArray);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
if (delegate.Count() == 1) {
|
||||
return delegate.QueryElementAt(0,
|
||||
try {
|
||||
var target = delegate.QueryElementAt(0,
|
||||
Components.interfaces.nsIRDFNode);
|
||||
return target;
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aProperty.EqualsNode(this.kNC_DN)) {
|
||||
// Find the DN arc. Get the message delegate for aSource
|
||||
// and return the resource for the dn property of the message,
|
||||
// if available.
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
return this.mRdfSvc.GetResource(delegate.dn);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Find a different arc. See if we're looking for an LDAP attribute
|
||||
// arc. If so, get the message delegate for aSource, if we find one
|
||||
// get the attribute array for the specified LDAP attribute and
|
||||
// return the first value if it isn't empty.
|
||||
var refStart = aProperty.Value.indexOf("#");
|
||||
if ( aProperty.Value.slice(0, refStart + 1) ==
|
||||
if (aProperty.Value.slice(0, refStart + 1) ==
|
||||
LDAPATTR_NAMESPACE_URI) {
|
||||
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
var attributeName = aProperty.Value.slice(refStart + 1);
|
||||
|
@ -267,6 +366,8 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found nothing.
|
||||
Components.returnCode = NS_RDF_NO_VALUE;
|
||||
return null;
|
||||
},
|
||||
|
@ -289,25 +390,59 @@ nsLDAPDataSource.prototype = {
|
|||
"\n\t" + aProperty.Value + "\n\t" + aTruthValue + "\n\n");
|
||||
}
|
||||
|
||||
// We don't handle negative assertions.
|
||||
// XXX Should we? Can we?
|
||||
if (!aTruthValue) {
|
||||
return new ArrayEnumerator(new Array());
|
||||
}
|
||||
|
||||
var delegate;
|
||||
|
||||
if (aProperty.EqualsNode(this.kNC_child)) {
|
||||
if (aProperty.EqualsNode(this.kNC_child)
|
||||
|| aProperty.EqualsNode(this.kNC_recursiveChild)) {
|
||||
// Find children or recursiveChildren. Get the messagelist delegate
|
||||
// (flat for child, recursive for recursiveChild) for aSource and
|
||||
// return an enumerator for the list, if available.
|
||||
var listType = (aProperty.EqualsNode(this.kNC_child) ?
|
||||
"flat.messagelist.ldap" :
|
||||
"recursive.messagelist.ldap");
|
||||
try {
|
||||
delegate = aSource.GetDelegate("messagelist.ldap",
|
||||
delegate = aSource.GetDelegate(listType,
|
||||
Components.interfaces.nsISupportsArray);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
return new nsISupportsArrayEnumerator(delegate);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else if (aProperty.EqualsNode(this.kNC_DN)) {
|
||||
// Find the DN arc. Get the message delegate for aSource
|
||||
// and return the resource for the dn property of the message,
|
||||
// if available.
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
return this.mRdfSvc.GetResource(delegate.dn);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Find a different arc. See if we're looking for an LDAP attribute
|
||||
// arc. If so, get the message delegate for aSource, if we find one
|
||||
// get the attribute array for the specified LDAP attribute and
|
||||
// an enumerator for the array.
|
||||
var refStart = aProperty.Value.indexOf("#");
|
||||
if ( aProperty.Value.slice(0, refStart + 1) ==
|
||||
if (aProperty.Value.slice(0, refStart + 1) ==
|
||||
LDAPATTR_NAMESPACE_URI) {
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
var attributeName = aProperty.Value.slice(refStart + 1);
|
||||
|
@ -317,6 +452,7 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Found nothing, return enumerator for empty array.
|
||||
return new ArrayEnumerator(new Array());
|
||||
},
|
||||
|
||||
|
@ -403,35 +539,43 @@ nsLDAPDataSource.prototype = {
|
|||
* in boolean aTruthValue);
|
||||
*/
|
||||
HasAssertion: function(aSource, aProperty, aTarget, aTruthValue) {
|
||||
// the datasource doesn't currently use any sort of containers
|
||||
//
|
||||
// The datasource doesn't currently use any sort of standard
|
||||
// RDF containers.
|
||||
if (aProperty.EqualsNode(this.kRDF_instanceOf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
dump("HasAssertion() called with args: \n\t" + aSource.Value +
|
||||
"\n\t" + aProperty.Value + "\n\t" + aTarget.Value + "\n\t" +
|
||||
aTruthValue + "\n\n");
|
||||
}
|
||||
|
||||
// We don't handle negative assertions.
|
||||
// XXX Should we? Can we?
|
||||
if (!aTruthValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var target = this.getSpecifiedNode(aTarget);
|
||||
|
||||
// spew debugging info
|
||||
//
|
||||
if (DEBUG) {
|
||||
dump("HasAssertion() called with args: \n\t" + aSource.Value +
|
||||
"\n\t" + aProperty.Value + "\n\t" + target.Value + "\n\t" +
|
||||
aTruthValue + "\n\n");
|
||||
}
|
||||
|
||||
var delegate;
|
||||
|
||||
if (aProperty.EqualsNode(this.kNC_child)) {
|
||||
if (aProperty.EqualsNode(this.kNC_child)
|
||||
|| aProperty.EqualsNode(this.kNC_recursiveChild)) {
|
||||
// Find out if aTarget is in the children or recursiveChildren of
|
||||
// aSource. Get the messagelist delegate (flat for child, recursive
|
||||
// for recursiveChild) for aSource.
|
||||
var listType = (aProperty.EqualsNode(this.kNC_child) ?
|
||||
"flat.messagelist.ldap" :
|
||||
"recursive.messagelist.ldap");
|
||||
try {
|
||||
delegate = aSource.GetDelegate("messagelist.ldap",
|
||||
delegate = aSource.GetDelegate(listType,
|
||||
Components.interfaces.nsISupportsArray);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
// We have a delegate message list, loop through it and return
|
||||
// true if the target is in the list.
|
||||
var enumerator = delegate.Enumerate();
|
||||
var done = false;
|
||||
try {
|
||||
|
@ -443,7 +587,7 @@ nsLDAPDataSource.prototype = {
|
|||
while(!done) {
|
||||
var resource = enumerator.currentItem().QueryInterface(
|
||||
Components.interfaces.nsIRDFResource);
|
||||
if (resource.Value == target.Value) {
|
||||
if (resource.Value == aTarget.Value) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
|
@ -455,14 +599,33 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (aProperty.EqualsNode(this.kNC_DN)) {
|
||||
// Find the DN arc. Get the message delegate for aSource
|
||||
// and return the resource for the dn property of the message,
|
||||
// if available.
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
return (delegate.dn == aTarget.Value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Find a different arc. See if we're looking for an LDAP attribute
|
||||
// arc. If so, get the message delegate for aSource, if we find one
|
||||
// get the attribute array for the specified LDAP attribute and
|
||||
// an enumerator for the array.
|
||||
var refStart = aProperty.Value.indexOf("#");
|
||||
if (aProperty.Value.slice(0, refStart + 1) ==
|
||||
LDAPATTR_NAMESPACE_URI) {
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
var attributeName = aProperty.Value.slice(refStart + 1);
|
||||
|
@ -471,7 +634,7 @@ nsLDAPDataSource.prototype = {
|
|||
var attributes = new ArrayEnumerator(attributeArray);
|
||||
while (attributes.hasMoreElements()) {
|
||||
var attribute = attributes.getNext();
|
||||
if (attribute.Value == target.Value) {
|
||||
if (attribute.Value == aTarget.Value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -496,21 +659,10 @@ nsLDAPDataSource.prototype = {
|
|||
dump("AddObserver() called\n\n");
|
||||
}
|
||||
|
||||
var eventQSvc = Components.
|
||||
classes["@mozilla.org/event-queue-service;1"].
|
||||
getService(Components.interfaces.nsIEventQueueService);
|
||||
var uiQueue = eventQSvc.
|
||||
getSpecialEventQueue(Components.interfaces.
|
||||
nsIEventQueueService.UI_THREAD_EVENT_QUEUE);
|
||||
var proxyMgr = Components.
|
||||
classes["@mozilla.org/xpcomproxy;1"].
|
||||
getService(Components.interfaces.nsIProxyObjectManager);
|
||||
|
||||
var observer = proxyMgr.getProxyForObject(uiQueue,
|
||||
Components.interfaces.nsIRDFObserver, aObserver, 5);
|
||||
// 5 == PROXY_ALWAYS | PROXY_SYNC
|
||||
|
||||
this.mObserverList.push(observer);
|
||||
// We need to proxy our observers on the main (UI) thread, because
|
||||
// the RDF code wants to run on the main thread.
|
||||
this.mObserverList.push(getProxyOnUIThread(aObserver,
|
||||
Components.interfaces.nsIRDFObserver));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -605,23 +757,48 @@ nsLDAPDataSource.prototype = {
|
|||
|
||||
var delegate;
|
||||
|
||||
if (aArc.EqualsNode(this.kNC_child)) {
|
||||
if (aArc.EqualsNode(this.kNC_child)
|
||||
|| aArc.EqualsNode(this.kNC_recursiveChild)) {
|
||||
// Find children or recursiveChildren. Get the messagelist delegate
|
||||
// (flat for child, recursive for recursiveChild) for aSource and
|
||||
// return true if we have one.
|
||||
var listType = (aArc.EqualsNode(this.kNC_child) ?
|
||||
"flat.messagelist.ldap" :
|
||||
"recursive.messagelist.ldap");
|
||||
try {
|
||||
delegate = aSource.GetDelegate("messagelist.ldap",
|
||||
delegate = aSource.GetDelegate(listType,
|
||||
Components.interfaces.nsISupportsArray);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (aArc.EqualsNode(this.kNC_DN)) {
|
||||
// Find the DN arc. Get the message delegate for aSource
|
||||
// and return true if we have a delegate and its dn
|
||||
// attribute is non-null.
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
return (delegate != null);
|
||||
}
|
||||
|
||||
// Find a different arc. See if we're looking for an LDAP attribute
|
||||
// arc. If so, get the message delegate for aSource, if we find one
|
||||
// get the attribute array for the specified LDAP attribute and
|
||||
// return true if it contains at least one value.
|
||||
var refStart = aArc.Value.indexOf("#");
|
||||
if (aArc.Value.slice(0, refStart + 1) == LDAPATTR_NAMESPACE_URI) {
|
||||
try {
|
||||
delegate = aSource.GetDelegate("message.ldap",
|
||||
Components.interfaces.nsILDAPMessage);
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (delegate != null) {
|
||||
var attributeName = aArc.Value.slice(refStart + 1);
|
||||
|
@ -632,21 +809,6 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* nsIRDFRemoteDataSource
|
||||
*/
|
||||
|
||||
// from nsIRDFRemoteDataSource. right now this is just a dump()
|
||||
// to see if it ever even gets used.
|
||||
//
|
||||
get loaded() {
|
||||
dump("getter for loaded called\n");
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -656,9 +818,8 @@ nsLDAPDataSource.prototype = {
|
|||
onAssert: function(aDataSource, aSource, aProperty, aTarget)
|
||||
{
|
||||
if (DEBUG) {
|
||||
var target = this.getSpecifiedNode(aTarget);
|
||||
dump("OnAssert() called with args: \n\t" + aSource.Value +
|
||||
"\n\t" + aProperty.Value + "\n\t" + target.Value + "\n\n");
|
||||
"\n\t" + aProperty.Value + "\n\t" + aTarget.Value + "\n\n");
|
||||
}
|
||||
|
||||
var iter = new ArrayEnumerator(this.mObserverList);
|
||||
|
@ -668,6 +829,35 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
onUnassert: function(aDataSource, aSource, aProperty, aTarget)
|
||||
{
|
||||
if (DEBUG) {
|
||||
dump("onUnassert() called with args: \n\t" + aSource.Value +
|
||||
"\n\t" + aProperty.Value + "\n\t" + aTarget.Value + "\n\n");
|
||||
}
|
||||
|
||||
var iter = new ArrayEnumerator(this.mObserverList);
|
||||
var nextObserver;
|
||||
while ((nextObserver = iter.getNext()) != null) {
|
||||
nextObserver.onUnassert(this, aSource, aProperty, aTarget);
|
||||
}
|
||||
},
|
||||
|
||||
onChange: function(aDataSource, aSource, aProperty, aOldTarget, aNewTarget)
|
||||
{
|
||||
if (DEBUG) {
|
||||
dump("onChange() called with args: \n\t" + aSource.Value +
|
||||
"\n\t" + aProperty.Value + "\n\t" + aOldTarget.Value +
|
||||
"\n\t" + aNewTarget.Value + "\n\n");
|
||||
}
|
||||
|
||||
var iter = new ArrayEnumerator(this.mObserverList);
|
||||
var nextObserver;
|
||||
while ((nextObserver = iter.getNext()) != null) {
|
||||
nextObserver.onChange(this, aSource, aProperty, aOldTarget, aNewTarget);
|
||||
}
|
||||
},
|
||||
|
||||
beginUpdateBatch: function()
|
||||
{
|
||||
if (DEBUG) {
|
||||
|
@ -694,53 +884,24 @@ nsLDAPDataSource.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
getSpecifiedNode: function(aNode) {
|
||||
// figure out what kind of nsIRDFNode aTarget is
|
||||
//
|
||||
var node;
|
||||
try {
|
||||
node = aNode.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (node == null) {
|
||||
try {
|
||||
node = aNode.QueryInterface(
|
||||
Components.interfaces.nsIRDFLiteral);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
if (node == null) {
|
||||
try {
|
||||
node = aNode.QueryInterface(Components.interfaces.nsIRDFDate);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
if (node == null) {
|
||||
try {
|
||||
node = aNode.QueryInterface(Components.interfaces.nsIRDFInt);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fills an array with the RDF nodes for the values of an attribute
|
||||
* out of a nsLDAPMessage.
|
||||
*/
|
||||
getAttributeArray: function(aMessage, aAttributeName) {
|
||||
var resultArray = new Array();
|
||||
var attributesCount = {};
|
||||
var attributes = aMessage.getAttributes(attributesCount);
|
||||
for (var i = 0; i < attributesCount.value; i++) {
|
||||
if (attributes[i] == aAttributeName) {
|
||||
var valuesCount = {};
|
||||
var values = aMessage.getValues(attributes[i], valuesCount);
|
||||
try {
|
||||
var values = aMessage.getValues(aAttributeName, valuesCount);
|
||||
for (var j = 0; j < valuesCount.value; j++) {
|
||||
var attributeValue = this.mRdfSvc.GetLiteral(values[j]);
|
||||
resultArray.push(attributeValue);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// Error or the attribute was not there.
|
||||
// XXX Do we need to do something about the real errors?
|
||||
// XXX Just returning empty array for now.
|
||||
}
|
||||
return resultArray;
|
||||
}
|
||||
|
@ -749,9 +910,11 @@ nsLDAPDataSource.prototype = {
|
|||
// the nsILDAPMessage associated with a given resource
|
||||
//
|
||||
const NS_LDAPMESSAGERDFDELEGATEFACTORY_CONTRACTID =
|
||||
'@mozilla.org/rdf/delegate-factory;1?key=message.ldap&scheme=ldap'
|
||||
const NS_LDAPMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID =
|
||||
'@mozilla.org/rdf/delegate-factory;1?key=messagelist.ldap&scheme=ldap'
|
||||
'@mozilla.org/rdf/delegate-factory;1?key='+"message.ldap"+'&scheme=ldap'
|
||||
const NS_LDAPFLATMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID =
|
||||
'@mozilla.org/rdf/delegate-factory;1?key=flat.messagelist.ldap&scheme=ldap'
|
||||
const NS_LDAPRECURSIVEMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID =
|
||||
'@mozilla.org/rdf/delegate-factory;1?key=recursive.messagelist.ldap&scheme=ldap'
|
||||
const NS_LDAPMESSAGERDFDELEGATEFACTORY_CID =
|
||||
Components.ID('{4b6fb566-1dd2-11b2-a1a9-889a3f852b0b}');
|
||||
|
||||
|
@ -760,8 +923,10 @@ function nsLDAPMessageRDFDelegateFactory() {}
|
|||
nsLDAPMessageRDFDelegateFactory.prototype =
|
||||
{
|
||||
mRdfSvc: {},
|
||||
mLDAPSvc: {},
|
||||
mLDAPDataSource: {},
|
||||
kNC_child: {},
|
||||
kNC_recursiveChild: {},
|
||||
|
||||
mConnection: {}, // connection to the LDAP server
|
||||
mOperation: {}, // current LDAP operation
|
||||
|
@ -780,13 +945,18 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
this.mRdfSvc = Components.
|
||||
classes["@mozilla.org/rdf/rdf-service;1"].
|
||||
getService(Components.interfaces.nsIRDFService);
|
||||
this.mLDAPSvc = Components.
|
||||
classes["@mozilla.org/network/ldap-service;1"].
|
||||
getService(Components.interfaces.nsILDAPService);
|
||||
this.mLDAPDataSource = this.mRdfSvc.GetDataSource("rdf:ldap").
|
||||
QueryInterface(Components.interfaces.nsIRDFObserver);
|
||||
|
||||
// get some RDF Resources that we'll need
|
||||
//
|
||||
this.kNC_child = this.mRdfSvc.GetResource( NC_NAMESPACE_URI +
|
||||
this.kNC_child = this.mRdfSvc.GetResource(NC_NAMESPACE_URI +
|
||||
"child");
|
||||
this.kNC_recursiveChild = this.mRdfSvc.GetResource(NC_NAMESPACE_URI +
|
||||
"recursiveChild");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -840,9 +1010,7 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
//
|
||||
if (aMessage.type != aMessage.RES_BIND) {
|
||||
dump("bind failed\n");
|
||||
if (aKey == "messagelist.ldap") {
|
||||
delete callerObject.mInProgressHash[queryURL.spec];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -859,8 +1027,9 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
// XXX err handling (also for url. accessors)
|
||||
// XXX constipate this
|
||||
// XXX real timeout
|
||||
searchOp.searchExt(url.dn, url.scope, url.filter, 0,
|
||||
new Array(), 0, -1);
|
||||
searchOp.searchExt(queryURL.dn, queryURL.scope,
|
||||
queryURL.filter, 0, new Array(),
|
||||
0, -1);
|
||||
}
|
||||
|
||||
getTargetsBoundCallback.prototype.onLDAPInit =
|
||||
|
@ -910,6 +1079,7 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
" of type " + aMessage.type + "\n\n");
|
||||
}
|
||||
|
||||
var listHash = caller.mMessagesListHash;
|
||||
if (aMessage.type == aMessage.RES_SEARCH_ENTRY) {
|
||||
if (DEBUG) {
|
||||
dump("getTargetsSearchCallback() called with " +
|
||||
|
@ -917,12 +1087,18 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
aOuter.Value + "\n\n");
|
||||
}
|
||||
|
||||
// XXX (pvdb) Should get this out of nsILDAPMessage
|
||||
var newURL = "ldap://" + url.host;
|
||||
newURL += (url.port == "" ? "" : ":" + url.port);
|
||||
newURL += ("/" + aMessage.dn + "??base");
|
||||
// Create a resource for the message we just got.
|
||||
// This is a single entry for which we'll cache the
|
||||
// nsILDAPMessage. If we got this as a result of a
|
||||
// "list" query we'll also add it to the result array.
|
||||
var newURL = Components.classes["@mozilla.org/network/ldap-url;1"]
|
||||
.createInstance(Components.interfaces.nsILDAPURL);
|
||||
newURL.spec = queryURL.spec;
|
||||
newURL.dn = aMessage.dn;
|
||||
newURL.scope = SCOPE_BASE;
|
||||
newURL.filter = "(objectClass=*)";
|
||||
var newResource =
|
||||
caller.mRdfSvc.GetResource(newURL);
|
||||
caller.mRdfSvc.GetResource(newURL.spec);
|
||||
|
||||
// Add the LDAP message for the new resource in our
|
||||
// messages hashlist. We do this before adding it to
|
||||
|
@ -932,29 +1108,11 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
// If we wouldn't do this here, we'd start another
|
||||
// query for this resource.
|
||||
var messageHash = caller.mMessagesHash;
|
||||
if (!messageHash.hasOwnProperty(newURL)) {
|
||||
messageHash[newURL] = aMessage;
|
||||
if (!messageHash.hasOwnProperty(newURL.spec)) {
|
||||
messageHash[newURL.spec] = aMessage;
|
||||
}
|
||||
|
||||
if (aKey == "messagelist.ldap") {
|
||||
// Add the LDAP message to the result array for
|
||||
// the query resource and onAssert the result
|
||||
// as a child of the query resource.
|
||||
var listHash = caller.mMessagesListHash;
|
||||
if (!listHash.hasOwnProperty(aOuter.Value)) {
|
||||
// No entry for the query resource in the
|
||||
// results hashlist, let's create one.
|
||||
listHash[aOuter.Value] = Components.classes
|
||||
["@mozilla.org/supports-array;1"].
|
||||
createInstance(
|
||||
Components.interfaces.nsISupportsArray);
|
||||
}
|
||||
listHash[aOuter.Value].AppendElement(
|
||||
newResource);
|
||||
caller.mLDAPDataSource.onAssert(
|
||||
caller.mLDAPDataSource, aOuter,
|
||||
caller.kNC_child, newResource);
|
||||
} else if (aKey == "message.ldap") {
|
||||
if (queryType == MESSAGE) {
|
||||
// XXX - we need to onAssert this resource. However,
|
||||
// we need to know somehow what the caller wanted
|
||||
// to use this delegate for, so that we can limit
|
||||
|
@ -963,9 +1121,54 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
// "questions" coming in while the LDAP server
|
||||
// hasn't responded yet.
|
||||
}
|
||||
else {
|
||||
// Add the LDAP message to the result array for
|
||||
// the query resource and onAssert the result
|
||||
// as a child of the query resource.
|
||||
var queryResource =
|
||||
caller.mRdfSvc.GetResource(queryURL.spec);
|
||||
if (!listHash.hasOwnProperty(queryURL.spec)) {
|
||||
// No entry for the query resource in the
|
||||
// results hashlist, let's create one.
|
||||
listHash[queryURL.spec] = Components.classes
|
||||
["@mozilla.org/supports-array;1"].
|
||||
createInstance(
|
||||
Components.interfaces.nsISupportsArray);
|
||||
}
|
||||
listHash[queryURL.spec].AppendElement(newResource);
|
||||
if (queryType == FLAT_LIST) {
|
||||
caller.mLDAPDataSource.onAssert(
|
||||
caller.mLDAPDataSource, aOuter,
|
||||
caller.kNC_child, newResource);
|
||||
}
|
||||
else if (queryType == RECURSIVE_LIST) {
|
||||
caller.mLDAPDataSource.onAssert(
|
||||
caller.mLDAPDataSource, queryResource,
|
||||
caller.kNC_child, newResource);
|
||||
caller.mLDAPDataSource.onAssert(
|
||||
caller.mLDAPDataSource, aOuter,
|
||||
caller.kNC_recursiveChild, newResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aMessage.type == aMessage.RES_SEARCH_RESULT) {
|
||||
delete caller.mInProgressHash[aOuter.Value];
|
||||
// We got all the results for the query.
|
||||
// If we were looking for a list, let's check if we
|
||||
// have an entry for the query resource in the result's
|
||||
// hashlist. If we don't, add an empty array to help
|
||||
// performance, otherwise we'll keep requerying for this
|
||||
// query resource.
|
||||
if (queryType == FLAT_LIST || queryType == RECURSIVE_LIST) {
|
||||
if (!listHash.hasOwnProperty(queryURL.spec)) {
|
||||
// No entry for the query resource in the
|
||||
// results hashlist, let's create an empty one.
|
||||
listHash[queryURL.spec] = Components.classes
|
||||
["@mozilla.org/supports-array;1"].
|
||||
createInstance(
|
||||
Components.interfaces.nsISupportsArray);
|
||||
}
|
||||
}
|
||||
delete caller.mInProgressHash[queryURL.spec];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -984,38 +1187,97 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
}
|
||||
|
||||
var caller = this;
|
||||
var queryURL;
|
||||
var queryType;
|
||||
|
||||
if (aKey == "messagelist.ldap") {
|
||||
if (this.mMessagesListHash.hasOwnProperty(aOuter.Value)) {
|
||||
return (this.mMessagesListHash[aOuter.Value].
|
||||
QueryInterface(aIID));
|
||||
if (aKey == "message.ldap") {
|
||||
queryType = MESSAGE;
|
||||
}
|
||||
} else if (aKey == "message.ldap") {
|
||||
else if (aKey == "flat.messagelist.ldap") {
|
||||
queryType = FLAT_LIST;
|
||||
}
|
||||
else if (aKey == "recursive.messagelist.ldap") {
|
||||
queryType = RECURSIVE_LIST;
|
||||
}
|
||||
|
||||
switch (queryType) {
|
||||
case MESSAGE:
|
||||
if (this.mMessagesHash.hasOwnProperty(aOuter.Value)) {
|
||||
return (this.mMessagesHash[aOuter.Value].QueryInterface(aIID));
|
||||
}
|
||||
break;
|
||||
case FLAT_LIST:
|
||||
if (this.mMessagesListHash.hasOwnProperty(aOuter.Value)) {
|
||||
return (this.mMessagesListHash[aOuter.Value].QueryInterface(aIID));
|
||||
}
|
||||
break;
|
||||
case RECURSIVE_LIST:
|
||||
queryURL = Components.classes["@mozilla.org/network/ldap-url;1"]
|
||||
.createInstance(Components.interfaces.nsILDAPURL);
|
||||
queryURL.spec = aOuter.Value;
|
||||
if (queryURL.scope == SCOPE_BASE) {
|
||||
// Retarget the URL, asking for recursive children on
|
||||
// a base URL should descend, so we do a one-level search.
|
||||
queryURL.scope = SCOPE_ONELEVEL;
|
||||
}
|
||||
if (this.mMessagesListHash.hasOwnProperty(queryURL.spec)) {
|
||||
return (this.mMessagesListHash[queryURL.spec].QueryInterface(aIID));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!((aKey == "messagelist.ldap") &&
|
||||
(this.mInProgressHash.hasOwnProperty(aOuter.Value)))) {
|
||||
this.Init();
|
||||
var url = Components.classes["@mozilla.org/network/ldap-url;1"]
|
||||
if (queryURL == null) {
|
||||
queryURL = Components.classes["@mozilla.org/network/ldap-url;1"]
|
||||
.createInstance(Components.interfaces.nsILDAPURL);
|
||||
url.spec = aOuter.Value;
|
||||
queryURL.spec = aOuter.Value;
|
||||
}
|
||||
|
||||
// make sure that this if this URL is for a messagelist, it
|
||||
// represents something other than a base search
|
||||
//
|
||||
if ((aKey == "messagelist.ldap") && (url.scope == url.SCOPE_BASE)) {
|
||||
if ((queryType == FLAT_LIST) && (queryURL.scope == SCOPE_BASE)) {
|
||||
if (DEBUG) {
|
||||
dump("Early return, asking for a list of children for an " +
|
||||
"URL with a BASE scope\n\n");
|
||||
}
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!this.mInProgressHash.hasOwnProperty(queryURL.spec)) {
|
||||
this.Init();
|
||||
|
||||
// XXX - not sure what this should be
|
||||
var key = queryURL.host + ":" + queryURL.port;
|
||||
|
||||
// Get the LDAP service and request a connection to the server from
|
||||
// the service
|
||||
var server;
|
||||
try {
|
||||
server = this.mLDAPSvc.getServer(key);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
if (!server) {
|
||||
// Create a server object and let the service know about it
|
||||
// XXX - not sure if I initialize enough here
|
||||
server = Components.classes
|
||||
["@mozilla.org/network/ldap-server;1"].
|
||||
createInstance(Components.interfaces.nsILDAPServer);
|
||||
server.key = key;
|
||||
server.url = queryURL;
|
||||
this.mLDAPSvc.addServer(server);
|
||||
}
|
||||
|
||||
// Mark this URL as being in progress, to avoid requerying for the
|
||||
// same URL
|
||||
this.mInProgressHash[queryURL.spec] = 1;
|
||||
|
||||
// get a connection object
|
||||
//
|
||||
var connection = Components.classes
|
||||
["@mozilla.org/network/ldap-connection;1"].
|
||||
createInstance(Components.interfaces.nsILDAPConnection);
|
||||
connection.init(url.host, url.port, null,
|
||||
connection.init(queryURL.host, queryURL.port, null,
|
||||
generateGetTargetsBoundCallback())
|
||||
|
||||
// XXXdmose - in this case, we almost certainly shouldn't be
|
||||
|
@ -1023,7 +1285,7 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
// something reasonable, since this is actually a success
|
||||
// condition
|
||||
//
|
||||
dump ("falling through!\n");
|
||||
debug("falling through!\n");
|
||||
}
|
||||
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
|
@ -1031,6 +1293,7 @@ nsLDAPMessageRDFDelegateFactory.prototype =
|
|||
|
||||
}
|
||||
|
||||
|
||||
// the nsILDAPURL associated with a given resource
|
||||
//
|
||||
const NS_LDAPURLRDFDELEGATEFACTORY_CONTRACTID =
|
||||
|
@ -1091,10 +1354,9 @@ var MessageDelegateFactory = null;
|
|||
var nsLDAPDataSourceModule = {
|
||||
|
||||
registerSelf: function (compMgr, fileSpec, location, type) {
|
||||
if (DEBUG) {
|
||||
dump("*** Registering LDAP datasource components" +
|
||||
debug("*** Registering LDAP datasource components" +
|
||||
" (all right -- a JavaScript module!)\n");
|
||||
}
|
||||
|
||||
compMgr.registerComponentWithType(
|
||||
NS_LDAPDATASOURCE_CID,
|
||||
'LDAP RDF DataSource',
|
||||
|
@ -1111,8 +1373,15 @@ var nsLDAPDataSourceModule = {
|
|||
|
||||
compMgr.registerComponentWithType(
|
||||
NS_LDAPMESSAGERDFDELEGATEFACTORY_CID,
|
||||
'LDAP MessageList RDF Delegate',
|
||||
NS_LDAPMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID,
|
||||
'LDAP Flat MessageList RDF Delegate',
|
||||
NS_LDAPFLATMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID,
|
||||
fileSpec, location, true, true,
|
||||
type);
|
||||
|
||||
compMgr.registerComponentWithType(
|
||||
NS_LDAPMESSAGERDFDELEGATEFACTORY_CID,
|
||||
'LDAP Recursive MessageList RDF Delegate',
|
||||
NS_LDAPRECURSIVEMESSAGELISTRDFDELEGATEFACTORY_CONTRACTID,
|
||||
fileSpec, location, true, true,
|
||||
type);
|
||||
|
||||
|
@ -1122,13 +1391,6 @@ var nsLDAPDataSourceModule = {
|
|||
NS_LDAPURLRDFDELEGATEFACTORY_CONTRACTID,
|
||||
fileSpec, location, true, true,
|
||||
type);
|
||||
|
||||
compMgr.registerComponentWithType(
|
||||
NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CID,
|
||||
'LDAP Connection RDF Delegate',
|
||||
NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CONTRACTID,
|
||||
fileSpec, location, true, true,
|
||||
type);
|
||||
},
|
||||
|
||||
getClassObject: function(compMgr, cid, iid) {
|
||||
|
@ -1142,8 +1404,6 @@ var nsLDAPDataSourceModule = {
|
|||
return this.nsLDAPMessageRDFDelegateFactoryFactory;
|
||||
else if (cid.equals(NS_LDAPURLRDFDELEGATEFACTORY_CID))
|
||||
return this.nsLDAPURLRDFDelegateFactoryFactory;
|
||||
else if (cid.equals(NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CID))
|
||||
return this.nsLDAPConnectionRDFDelegateFactoryFactory;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
@ -1183,18 +1443,6 @@ var nsLDAPDataSourceModule = {
|
|||
}
|
||||
},
|
||||
|
||||
// probably don't need this; use nsLDAPService instead
|
||||
//
|
||||
nsLDAPConnectionRDFDelegateFactoryFactory: {
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
return
|
||||
(new nsLDAPConnectionRDFDelegateFactory()).QueryInterface(iid);
|
||||
}
|
||||
},
|
||||
|
||||
// because of the way JS components work (the JS garbage-collector
|
||||
// keeps track of all the memory refs and won't unload until appropriate)
|
||||
// this ends up being a dummy function; it can always return true.
|
||||
|
|
|
@ -1,57 +1,40 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
|
||||
<window title="LDAP Manager Prototype"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
orient="vertical">
|
||||
<outliner flex="1">
|
||||
<outlinercol id="description"
|
||||
class="outlinercol-header outlinercol-inset-header sortDirectionIndicator"
|
||||
flex="1"
|
||||
label="Description"
|
||||
sort="rdf:http://www.mozilla.org/LDAPATTR-rdf#description"
|
||||
sortActive="true"
|
||||
primary="true"
|
||||
persist="width sortActive sortDirection" />
|
||||
|
||||
<tree datasources="rdf:ldap"
|
||||
flex="2" id="testTree"
|
||||
ref="ldap://alpha.dante.org.uk:389/dc=dante,dc=org,dc=uk??sub?drink=*">
|
||||
<splitter class="tree-splitter" />
|
||||
|
||||
<outlinercol id="cn"
|
||||
class="outlinercol-header outlinercol-inset-header sortDirectionIndicator"
|
||||
flex="1"
|
||||
label="CN"
|
||||
sort="rdf:http://www.mozilla.org/LDAPATTR-rdf#cn"
|
||||
persist="width sortActive sortDirection" />
|
||||
|
||||
<outlinerbody id="tree"
|
||||
datasources="rdf:ldap"
|
||||
ref="ldap://alpha.dante.org.uk:389/dc=dante,dc=org,dc=uk??one?(objectclass=*)"
|
||||
flex="1"
|
||||
containment="http://home.netscape.com/NC-rdf#recursiveChild">
|
||||
<template>
|
||||
<rule>
|
||||
<conditions>
|
||||
<content uri="?uri" />
|
||||
<triple subject="?uri"
|
||||
predicate="http://home.netscape.com/NC-rdf#child"
|
||||
object="?child" />
|
||||
</conditions>
|
||||
|
||||
<bindings>
|
||||
<binding subject="?child"
|
||||
predicate="http://www.mozilla.org/LDAPATTR-rdf#drink"
|
||||
object="?drink" />
|
||||
<binding subject="?child"
|
||||
predicate="http://www.mozilla.org/LDAPATTR-rdf#givenname"
|
||||
object="?givenname" />
|
||||
</bindings>
|
||||
|
||||
<action>
|
||||
<treechildren flex="1">
|
||||
<treeitem uri="?child">
|
||||
<treerow>
|
||||
<treecell class="treecell-indent" label="?drink" flex="1" />
|
||||
<treecell label="?givenname" flex="1" />
|
||||
</treerow>
|
||||
</treeitem>
|
||||
</treechildren>
|
||||
</action>
|
||||
|
||||
</rule>
|
||||
<outlinerrow uri="rdf:http://home.netscape.com/NC-rdf#recursiveChild">
|
||||
<outlinercell ref="description"
|
||||
label="rdf:http://www.mozilla.org/LDAPATTR-rdf#description" />
|
||||
<outlinercell ref="cn"
|
||||
label="rdf:http://www.mozilla.org/LDAPATTR-rdf#cn" />
|
||||
</outlinerrow>
|
||||
</template>
|
||||
|
||||
<treecols id="theColumns">
|
||||
<treecol id="drink" flex="1" />
|
||||
<treecol id="givenname" flex="1" />
|
||||
</treecols>
|
||||
|
||||
<treehead>
|
||||
<treerow id="headRow">
|
||||
<treecell label="Drink" flex="1" />
|
||||
<treecell label="Given Name" flex="1" />
|
||||
</treerow>
|
||||
</treehead>
|
||||
</tree>
|
||||
|
||||
</outlinerbody>
|
||||
</outliner>
|
||||
</window>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче