home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / mozil06.zip / bin / components / nsLDAPDataSource.js < prev    next >
Text File  |  2001-02-14  |  15KB  |  470 lines

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the mozilla.org LDAP RDF datasource.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s): Dan Mosedale <dmose@mozilla.org>
  20.  *           Brendan Eich <brendan@mozilla.org>
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34.  
  35. const DEBUG = true;
  36.  
  37. // core RDF schema
  38. //
  39. const RDF_NAMESPACE_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  40. const NC_NAMESPACE_URI = "http://home.netscape.com/NC-rdf#";
  41.  
  42. // RDF-specific success nsresults 
  43. //
  44. const NS_ERROR_RDF_BASE = 0x804f0000; // XXX is this right?
  45. const NS_RDF_CURSOR_EMPTY = NS_ERROR_RDF_BASE + 1;
  46. const NS_RDF_NO_VALUE = NS_ERROR_RDF_BASE + 2;
  47. const NS_RDF_ASSERTION_ACCEPTED = Components.results.NS_OK;
  48. const NS_RDF_ASSERTION_REJECTED = NS_ERROR_RDF_BASE + 3;
  49.  
  50. // some stuff from ldap.h
  51. //
  52. const LDAP_RES_BIND = 0x61;
  53.  
  54. // ArrayEnumerator courtesy of Brendan Eich <brendan@mozilla.org>
  55. //
  56. function ArrayEnumerator(array) {
  57.     this.array = array;
  58.     this.index = 0;
  59. }
  60. ArrayEnumerator.prototype = {
  61.     hasMoreElements: function() { return this.index < this.array.length; },
  62.     getNext: function () { return (this.index < this.array.length) ?
  63.                        this.array[this.index++] : null; }
  64. }
  65.  
  66. // the datasource object itself
  67. //
  68. const NS_LDAPDATASOURCE_CONTRACTID = 
  69.     '@mozilla.org/rdf/datasource;1?name=ldap';
  70. const NS_LDAPDATASOURCE_CID =
  71.     Components.ID('{8da18684-6486-4a7e-b261-35331f3e7163}');
  72.  
  73. function nsLDAPDataSource() {}
  74.  
  75. nsLDAPDataSource.prototype = {
  76.  
  77.     // from nsIRDFRemoteDataSource.  right now this is just a dump()
  78.     // to see if it ever even gets used.
  79.     //
  80.     get loaded() { dump("getter for loaded called\n"); 
  81.            return false; },
  82.  
  83.     mObserverList: new Array(),    // who is watching us; XXX ok to use new Array?
  84.  
  85.     // RDF property constants.  
  86.     //
  87.     // XXXdmose - can these can actually be statics (ie JS class
  88.     // properties rather than JS instance properties)?  or would that
  89.     // make it hard for the datasource and/or component to be GCed?
  90.     //
  91.     kRDF_instanceOf: {},
  92.     kNC_child: {},
  93.  
  94.     // since we implement multiple interfaces, we have to provide QI
  95.     //
  96.     QueryInterface: function(iid) {
  97.  
  98.       if (!iid.equals(Components.interfaces.nsISupports) &&
  99.       !iid.equals(Components.interfaces.nsIRDFDataSource) &&
  100.       !iid.equals(Components.interfaces.nsIRDFRemoteDataSource) &&
  101.       !iid.equals(Components.interfaces.nsILDAPMessageListener))
  102.       throw Components.results.NS_ERROR_NO_INTERFACE;
  103.  
  104.       return this;
  105.     },
  106.  
  107.     /**
  108.      * for nsIRDFRemoteDataSource
  109.      */
  110.     Init: function(aServer, aPort, aBindname)
  111.     {
  112.  
  113.     // XXX - if this a "single-connection" datasource; we should figure
  114.     // that out here by noticing that there is a ; after "rdf:ldap", and
  115.     // that after that there is a cookie which happens to be an LDAP URL
  116.     // designating the connection.  for now, we just assume that this will
  117.     // be a "universal" datasource.
  118.  
  119.     // get the RDF service
  120.     //
  121.     var rdfSvc = Components.
  122.         classes["@mozilla.org/rdf/rdf-service;1"].
  123.         getService(Components.interfaces.nsIRDFService);
  124.  
  125.     // get some RDF Resources that we'll need
  126.     //
  127.     this.kRDF_instanceOf = rdfSvc.GetResource( RDF_NAMESPACE_URI +
  128.                            "instanceOf");
  129.     this.kNC_child = rdfSvc.GetResource( NC_NAMESPACE_URI + "child");
  130.         this.kNC_Folder = rdfSvc.GetResource( NC_NAMESPACE_URI + "Folder");
  131.  
  132.     return;
  133.     },
  134.  
  135.     /**
  136.      * Add an observer to this data source. If the datasource
  137.      * supports observers, the datasource source should hold a strong
  138.      * reference to the observer. (from nsIRDFDataSource)
  139.      *
  140.      * void AddObserver(in nsIRDFObserver aObserver);
  141.      */
  142.     AddObserver: function(aObserver) {
  143.     this.mObserverList.push(aObserver);
  144.     },
  145.  
  146.     /**
  147.      * Query whether an assertion exists in this graph. (from nsIRDFDataSource)
  148.      *
  149.      * boolean HasAssertion(in nsIRDFResource aSource,
  150.      *                        in nsIRDFResource aProperty,
  151.      *                      in nsIRDFNode     aTarget,
  152.      *                      in boolean        aTruthValue);
  153.      */
  154.     HasAssertion: function(aSource, aProperty, aTarget, aTruthValue) {
  155.  
  156.     // figure out what kind of nsIRDFNode aTarget is
  157.     // XXXdmose: code incomplete
  158.     //
  159.         aTarget = aTarget.QueryInterface(Components.interfaces.nsIRDFResource);
  160.  
  161.     // spew debugging info
  162.     //
  163.     if (DEBUG) {
  164.         dump("HasAssertion() called with args: \n\t" + aSource.Value +
  165.          "\n\t" + aProperty.Value + "\n\t" + aTarget.Value + "\n\t" +
  166.          aTruthValue + "\n\n");
  167.     }
  168.  
  169.     // the datasource doesn't currently use any sort of containers
  170.     //
  171.     if (aProperty.EqualsNode(this.kRDF_instanceOf)) {
  172.         return false;
  173.     }
  174.        
  175.     // XXXdmose: real processing should happen here
  176.     //
  177.     var myMessage = aSource.GetDelegate("ldapmessage", Components.
  178.                         interfaces.nsILDAPMessage);
  179.  
  180.     // if we haven't returned true yet, there's nothing here
  181.         //
  182.     return false;
  183.     },
  184.  
  185.     /**
  186.      * Find a child of that is related to the source by the given arc
  187.      * arc and truth value
  188.      *
  189.      * @return NS_RDF_NO_VALUE if there is no target accessable from the
  190.      * source via the specified property.
  191.      *
  192.      *    nsIRDFNode GetTarget(in nsIRDFResource aSource,
  193.      *                         in nsIRDFResource aProperty,
  194.      *                         in boolean aTruthValue);
  195.      */
  196.     GetTarget: function(aSource, aProperty, aTruthValue) 
  197.     {
  198.     if (DEBUG) {
  199.         dump("GetTarget() called with args: \n\t" + aSource.Value + 
  200.          "\n\t" + aProperty.Value + "\n\t" + aTruthValue + "\n\n");
  201.     }
  202.  
  203.     Components.returnCode = NS_RDF_NO_VALUE;
  204.  
  205.     return null;
  206.     },
  207.  
  208.     /**
  209.      * Find all children of that are related to the source by the given arc
  210.      * arc and truth value.
  211.      *
  212.      * @return NS_OK unless a catastrophic error occurs. If the
  213.      * method returns NS_OK, you may assume that nsISimpleEnumerator points
  214.      * to a valid (but possibly empty) cursor.
  215.      *
  216.      * nsISimpleEnumerator GetTargets(in nsIRDFResource aSource,
  217.      *                                in nsIRDFResource aProperty,
  218.      *                                in boolean aTruthValue);
  219.      */
  220.  
  221.      GetTargets: function(aSource, aProperty, aTruthValue) {
  222.  
  223.      function generateGetTargetsBoundCallback() {
  224.  
  225.          function getTargetsBoundCallback() {}
  226.  
  227.          getTargetsBoundCallback.prototype.onLDAPMessage = 
  228.  
  229.              function(aMessage, aRetVal) {
  230.  
  231.              if (DEBUG) {
  232.              dump("boundCallback() called with scope: \n\t" +
  233.                   aSource.Value + "\n\t" + aProperty.Value + 
  234.                   "\n\t" + aTruthValue + "\n");
  235.              dump("\taRetVal = " + aRetVal + "\n\n");
  236.              }
  237.  
  238.              // XXX how do we deal with this in release builds?
  239.              // XXX deal with already bound case
  240.              //
  241.              if (aRetVal != LDAP_RES_BIND) {
  242.              dump("bind failed\n");
  243.              }
  244.  
  245.              // kick off a search
  246.              //
  247.              var searchOp = Components.classes[
  248.              "mozilla.network.ldapoperation"].
  249.                      createInstance(Components.interfaces.
  250.                      nsILDAPOperation);
  251.              // XXX err handling
  252.              searchOp.init(connection, 
  253.                    generateGetTargetsSearchCallback());
  254.              // XXX err handling (also for url. accessors)
  255.              // XXX constipate this
  256.              // XXX real timeout
  257.              searchOp.searchExt(url.dn, url.scope, url.filter, 0, -1);
  258.          }
  259.  
  260.          return new getTargetsBoundCallback();
  261.      }
  262.  
  263.      function generateGetTargetsSearchCallback() {
  264.  
  265.          function getTargetsSearchCallback() {}
  266.  
  267.          getTargetsSearchCallback.prototype.onLDAPMessage = 
  268.  
  269.              function(aMessage, aRetVal ) {
  270.              dump("getTargetsSearchCallback() called with aRetVal=" +
  271.               aRetVal + "\n\n");
  272.          }
  273.          return new getTargetsSearchCallback();
  274.      }
  275.  
  276.      if (DEBUG) {
  277.          dump("GetTargets() called with args: \n\t" + aSource.Value + 
  278.           "\n\t" + aProperty.Value + "\n\t" + aTruthValue + "\n\n");
  279.      }
  280.  
  281.      var url = Components.classes["mozilla.network.ldapurl"]
  282.                             .getService(Components.interfaces.nsILDAPURL);
  283.      url.spec = aSource.Value;
  284.      
  285.      // get a connection object
  286.      //
  287.      var connection = Components.classes
  288.                        ["mozilla.network.ldapconnection"].createInstance(
  289.                Components.interfaces.nsILDAPConnection);
  290.      connection.init(url.host, url.port, null);
  291.  
  292.      // get and initialize an operation object
  293.      //
  294.      var operation = Components.classes["mozilla.network.ldapoperation"].
  295.                          createInstance(Components.interfaces.
  296.                         nsILDAPOperation);
  297.      operation.init(connection, generateGetTargetsBoundCallback());
  298.  
  299.      // bind to the server.  we'll get a callback when this finishes.
  300.      // XXX handle a password
  301.      //
  302.      operation.simpleBind(null);
  303.  
  304.      return new ArrayEnumerator(new Array());
  305.      },
  306.  
  307.     /**
  308.      * Get a cursor to iterate over all the arcs that originate in
  309.      * a resource.
  310.      *
  311.      * @return NS_OK unless a catastrophic error occurs. If the method
  312.      * returns NS_OK, you may assume that labels points to a valid (but
  313.      * possible empty) nsISimpleEnumerator object.
  314.      *
  315.      * nsISimpleEnumerator ArcLabelsOut(in nsIRDFResource aSource);
  316.      */
  317.     ArcLabelsOut: function(aSource) 
  318.     {
  319.     if (DEBUG) {
  320.         dump("ArcLabelsOut() called with args: \n\t" + aSource.Value + 
  321.          "\n\n");
  322.     }
  323.  
  324.     return new ArrayEnumerator(new Array());
  325.     }
  326. }
  327.  
  328. // the nsILDAPMessage associated with a given resource
  329. //
  330. const NS_LDAPMESSAGERDFDELEGATEFACTORY_CONTRACTID = 
  331.     '@mozilla.org/rdf/delegate-factory/message.ldap;1';
  332. const NS_LDAPMESSAGERDFDELEGATEFACTORY_CID = 
  333.     Components.ID('{4b6fb566-1dd2-11b2-a1a9-889a3f852b0b`}');
  334.  
  335. function nsLDAPMessageRDFDelegateFactory() {}
  336.  
  337. nsLDAPMessageRDFDelegateFactory.prototype = 
  338. {
  339.  
  340.     mConnection: {},        // connection to the LDAP server
  341.     mOperation: {},          // current LDAP operation
  342.  
  343.     // from nsIRDFDelegateFactory:
  344.     //
  345.     // Create a delegate for the specified RDF resource.
  346.     //
  347.     // The created delegate should forward AddRef() and Release()
  348.     // calls to the aOuter object.
  349.     //
  350.     // void CreateDelegate(in nsIRDFResource aOuter,
  351.     //                     in string aKey,
  352.     //                     in nsIIDRef aIID,
  353.     //                     [retval, iid_is(aIID)] out nsQIResult aResult);
  354.     CreateDelegate: function (aOuter, aKey, aIID) {
  355.  
  356.     
  357.  
  358.     }
  359.  
  360. }
  361.  
  362. // the nsILDAPURL associated with a given resource
  363. //
  364. const NS_LDAPURLRDFDELEGATEFACTORY_CONTRACTID = '@mozilla.org/rdf/delegate-factory/url.ldap;1';
  365. const NS_LDAPURLRDFDELEGATEFACTORY_CID = 
  366.     Components.ID('b6048700-1dd1-11b2-ae88-a5e18bb1f25e');
  367.  
  368. // the nsILDAPConnection associated with a given resource
  369. //
  370. const NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CONTRACTID = 
  371.     '@mozilla.org/rdf/delegate-factory/connection.ldap;1';
  372. const NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CID = 
  373.     Components.ID('57075fc6-1dd2-11b2-9df5-dbb9111d1b38');
  374.  
  375. // nsLDAPDataSource Module (for XPCOM registration)
  376. // 
  377. var nsLDAPDataSourceModule = {
  378.  
  379.     registerSelf: function (compMgr, fileSpec, location, type) {
  380.  
  381.         compMgr.registerComponentWithType(NS_LDAPDATASOURCE_CID, 
  382.                       'LDAP RDF DataSource', 
  383.                       NS_LDAPDATASOURCE_CONTRACTID, 
  384.                       fileSpec, location, true, true, 
  385.                       type);
  386.  
  387.         compMgr.registerComponentWithType(
  388.         NS_LDAPMESSAGERDFDELEGATEFACTORY_CID, 
  389.         'LDAP Message RDF Delegate', 
  390.         NS_LDAPMESSAGERDFDELEGATEFACTORY_CONTRACTID, 
  391.         fileSpec, location, true, true, 
  392.         type);
  393.  
  394.         compMgr.registerComponentWithType(NS_LDAPURLRDFDELEGATEFACTORY_CID, 
  395.                       'LDAP URL RDF Delegate', 
  396.                       NS_LDAPURLRDFDELEGATEFACTORY_CONTRACTID, 
  397.                       fileSpec, location, true, true, 
  398.                       type);
  399.  
  400.         compMgr.registerComponentWithType(
  401.         NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CID, 
  402.         'LDAP Connection RDF Delegate', 
  403.         NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CONTRACTID, 
  404.         fileSpec, location, true, true, 
  405.         type);
  406.  
  407.     },
  408.  
  409.     getClassObject: function(compMgr, cid, iid) {
  410.         if (!iid.equals(Components.interfaces.nsIFactory))
  411.             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  412.  
  413.         if (cid.equals(NS_LDAPDATASOURCE_CID))
  414.         return this.nsLDAPDataSourceFactory;    
  415.     else if (cid.equals(NS_LDAPMESSAGERDFDELEGATEFACTORY_CID))
  416.             return this.nsLDAPMessageRDFDelegateFactoryFactory;
  417.     else if (cid.equals(NS_LDAPURLRDFDELEGATEFACTORY_CID))
  418.             return this.nsLDAPURLRDFDelegateFactoryFactory;
  419.     else if (cid.equals(NS_LDAPCONNECTIONRDFDELEGATEFACTORY_CID))
  420.             return this.nsLDAPConnectionRDFDelegateFactoryFactory;
  421.  
  422.     throw Components.results.NS_ERROR_NO_INTERFACE;
  423.     },
  424.  
  425.     nsLDAPDataSourceFactory: {
  426.       createInstance: function(outer, iid) {
  427.       if (outer != null)
  428.           throw Components.results.NS_ERROR_NO_AGGREGATION;
  429.       
  430.       return (new nsLDAPDataSource()).QueryInterface(iid);
  431.       }
  432.     },
  433.  
  434.     nsLDAPMessageRDFDelegateFactoryFactory: {
  435.     createInstance: function(outer, iid) {
  436.       if (outer != null)
  437.           throw Components.results.NS_ERROR_NO_AGGREGATION;
  438.       
  439.       return (new nsLDAPMessageRDFDelegateFactory()).QueryInterface(iid);
  440.       }
  441.     },
  442.  
  443.     nsLDAPURLRDFDelegateFactoryFactory: {
  444.     createInstance: function(outer, iid) {
  445.       if (outer != null)
  446.           throw Components.results.NS_ERROR_NO_AGGREGATION;
  447.       
  448.       return (new nsLDAPURLRDFDelegateFactory()).QueryInterface(iid);
  449.       }
  450.     },
  451.  
  452.     nsLDAPConnectionRDFDelegateFactoryFactory: {
  453.     createInstance: function(outer, iid) {
  454.       if (outer != null)
  455.           throw Components.results.NS_ERROR_NO_AGGREGATION;
  456.       
  457.       return 
  458.           (new nsLDAPConnectionRDFDelegateFactory()).QueryInterface(iid);
  459.       }
  460.     },
  461.  
  462.     // because of the way JS components work (the JS garbage-collector
  463.     // keeps track of all the memory refs and won't unload until appropriate)
  464.     // this ends up being a dummy function; it can always return true.
  465.     //
  466.     canUnload: function(compMgr) { return true; }
  467. };
  468.  
  469. function NSGetModule(compMgr, fileSpec) { return nsLDAPDataSourceModule; }
  470.