Novell Home

AnyInfo Example 5: Using the Novell NWDir Bean for NDS Access

Articles and Tips: article

LAWRENCE V. FISHER
Senior Research Engineer
Developer Information

01 Sep 1998


Discusses the fifth example in the series. The NWDir bean provides developers with simple yet powerful access to NetWare services. AnyInfo uses the NWDir bean to give the client applets access to NDS.

Introduction

This article discusses the fifth example in the series introduced in the article, "The Transformation of API_Info into AnyInfo, a Multi-Tiered, Data Base Application" in the July issue.

As shown in Figure 1, this example uses the Novell NWDir bean in the middle tier. The NWDir bean is one of several Novell beans which provide developers with simple and yet powerful access to NetWare services. AnyInfo uses the NWDir bean to give the client applets access to NDS.

Figure 1: The example discussed in this article uses Novell's NWDir Bean on the server side to access NDS.

This article is divided into two parts. The first part describes what the AnyInfo application does. Part two goes into detail about AnyInfo's client proxy application and presents the code which uses Novell's NWDir bean to enable AnyInfo to operate with NDS.

Part 1: A Review of AnyInfo, a Multi-Tiered, Database Application

The AnyInfo application was developed primarily to show different ways to implement the plumbing between users and services in a multi-tiered network environment. This example demonstrates one of many ways to implement a middle tier on NetWare.

What is AnyInfo?

As shown in Figure 2, the AnyInfo application consists of four main pieces:

  1. The NDS administration snap-ins (currently implemented with the ConsoleOne snap-ins described in example 4 of this series).

  2. The client applet (described in example 2 of this series).

  3. The Client Proxy Application implemented in this example, which allows the user to select and connect to an AnyInfo database server somewhere on the network.

  4. The Access Proxy Application (to be described in example 6 of this series) which fronts an AnyInfo database server.

Figure 2: This article is concerned with the client proxy piece of Anyinfo.

The example described in this article deals with AnyInfo's client proxy piece. All AnyInfo applet clients interact with the client proxy application, allowing users to select and connect to one of any number of AnyInfo databases, represented by special AnyInfo objects in any of the NDS trees in the network.

The AnyInfo databases (in this series of examples) are kept simple, containing things like address books, so we can focus on middle tier plumbing and not end services.

All NDS trees to be used with AnyInfo must have their schemas extended (see "Some Standard NDS Terminology" below). During the extension, class definitions for AnyInfoList objects and regular AnyInfo objects are added. Special AnyInfo snap-ins (discussed in Example 4 of this series) can be used with ConsoleOne (an administration tools application provided by Novell) to extend NDS schemas for AnyInfo. For more information, refer to the May, June, and August issues of this magazine.

When a tree is extended for AnyInfo, a single AnyInfoList object is installed automatically at the root by AnyInfo's ConsoleOne snap-ins. Then, when the administrator uses ConsoleOne to add a regular AnyInfo object to the tree, a distinguished name for the new object is automatically added to the list by AnyInfo's ConsoleOne snap-ins to record its location.

Each regular AnyInfo object contains information about an AnyInfo database, i.e., its common name, server location, and administrator name.

How Does AnyInfo Work?

Initially, the AnyInfo client applet has no idea what tree or database the user wants to connect to. So, the user must click the "Select Tree" button on the applet's main window (shown in Figure 3).

Figure 3: Initially, all database interaction is disabled until AnyInfo knows what tree and what database on that tree the user is interested in.

Clicking the "Select Tree" button causes the applet to send a request to the client proxy application to obtain a list of the trees on the network (shown in Figure 4).

Figure 4: The user must select a tree so that AnyInfo will know where to find its objects.

When the user selects a tree, the applet sends a request to the client proxy application to obtain a list of the AnyInfo databases on that tree (shown in Figure 5). Along with the list of database names, the client proxy application also sends the applet the information it would need to connect to any of the databases in the list (i.e., the IP address for the database servers). There can be any number of AnyInfo databases referred to by objects in the selected tree. However, in order to keep things simple, Figure 5 shows only two.

Figure 5: The user must select a database so that AnyInfo will know where to connect.

Once the database has been selected, the main applet window enables the three database operation buttons shown in Figure 6, "List Topics," "Add Record," and "Get Info." From this point on, the user can interact with the selected database.

Figure 6: Once the connection information for the desired database is known, interaction with database can take place.

Part Two: AnyInfo Client Proxy Source Code and Explanation

Putting an application's business logic (including directory access) in the middle tier, gives users the flexibility to connect to any service (not necessarily just databases), without the complication of a client installation and ongoing maintenance. In addition, if you use NDS as the directory to contain information for your business logic, you get the benefit of centralized management. As you will see, Novell's NWDir bean makes the NDS access part very easy.

Figure 7: Using the client proxy, many AnyInfo client applets can connect through different trees to different database services.

As shown in Figure 7, The client proxy application is the middle tier for AnyInfo. The purpose of the client proxy is to provide client applets with network connection services and the following NDS access services:

  • Obtain a list of NDS trees available on the network for user selection at the applet.

  • Read the list of AnyInfo objects from the selected tree's AnyInfoList object.

  • Read connection and naming information from all of the AnyInfo objects in the list.

NDS access is getting easier all the time. The AnyInfo client proxy application uses Novell's NWDir bean to access NDS. By using the NWDir bean, much of the complexity of NDS programming is removed. In fact, so far, this is the easiest way to access NDS that I have found.

The NWDir bean and other Novell beans like the NWSess bean and the NWSockets bean can be hooked into your application using a graphical fifth-generation development environment like Java's Bean Box. Or, you can interact with them as a library by calling their exposed methods in your Java code like AnyInfo did. However you decide to use the beans, do it. They will definitely save you much labor.

Some Standard NDS Terminology

Before we dive into the source code, if you are new to NDS, you may wish to read the section below for a brief review of NDS terms.

Each NDS tree can be looked at like a database. Each NDS tree is composed of objects (something like database records), which contain information about entities on the network, e.g., users and servers. Objects are composed of attributes (something like database fields).

Before an object can be created, the tree must have a description of the object's type which details its attributes. In addition, the tree must have a description for each attribute to be used in the object.

Object type descriptions are called classes and attribute descriptions are called attribute definitions. Because all of a tree's classes are related to each other by inheritance, they form a hierarchical map. An NDS tree's class and attribute definitions is called its schema.

NDS schemas establish the kinds of objects that can be added to the NDS database on a given tree. Initially, all trees have the same NDS schema, called the base schema, provided by Novell. However, an application will often need to extend a schema with new attribute definitions and classes to accommodate special needs.

Syntaxes are special typedefs created by Novell to be the data types used in attribute definitions. NDS syntaxes can only be created by Novell. Every attribute definition is built upon one of the standard syntaxes. The syntax specified for an attribute definition defines the data format for values that can be put into that attribute type. The syntax also specifies the kinds of comparisons that NDS can make to the attribute's values during a search.

Many of AnyInfo's special attributes use the SYN_DIST_NAME syntax which specifies a distinguished name for an object (a distinguished name provides a fully qualified path from the tree's root to a specific object).

Some Differences Between Standard NDS and JavaBean Terminology

JavaBean terms differ from standard NDS terms in how they describe NDS. Here are some examples:


NDS Terminology
JavaBean Terminology

NDS Tree

Directory

NDS Class

Layout

NDS Syntax

Field Type

NDS Object

Entry

NDS Attribute

Field

Distinguished Name

Full Name

Finally, the Source Code Listing

The client proxy is implemented by two classes, the AnyInfoClientProxyApplic class and the AnyInfoClientConnection class.

Below is a source code listing for the methods in the AnyInfoClientConnection class which use NWDir methods. All data types and methods belonging to the NWDir bean are in bold. The large italic, double-underlined numbers refer to explanations after the code listing.

Below is a source code listing for the methods in the AnyInfoClientConnection class which use NWDir methods. All data types and methods belonging to the NWDir bean are in bold. The large italic numbers refer to explanations after the code listing.

/**************************************************************************AnyInfoClientConnection()      * The AnyInfoClientConnection constructor creates input and output streams       to the AnyInfo client Applet which initiated the connection.     * Starts the thread and then passes the buffer containing the client's       request to dispatchRequest() to handle it.**************************************************************************
1.
public final static String ANY_INFO_CLASSNAME        = "DEVINFO:AnyInfoClass";public final static String ANY_INFO_SERVER_ATTRNAME    = "DEVINFO:AnyInfo Server";public final static String ANY_INFO_SUBJECT_ATTRNAME = "DEVINFO:AnyInfo Subject";public final static String ANY_INFO_OPRTR_ATTRNAME  = "DEVINFO:AnyInfo Operator";public final static String ANY_INFOLIST_CLASSNAME  = "DEVINFO:AnyInfoListClass";public final static String ANY_INFOLIST_ENTRY_ATTRNAME = "DEVINFO:AnyInfoListEntry";
2
 public final static String ANY_INFOLIST_OBJECTNAME   = "AnyInfoList";public final static String NET_ADDX_ATTRNAME        = "Network Address";public final static String BUFFER_ITEM_DLIMTER      = "@";public final static String B_SLASH= "\\";  // 2 \s to nullify esc sequence.rotected String           treeName      = null;protected Socket          client ;protected DataInputStream inFromClient;protected PrintStream outToClient;protected AnyInfoClientProxyApplic server;public  NWDir          nwDirBean;   public AnyInfoClientConnection( Socket client_socket , AnyInfoClientProxyApplic theServer )   {
3.
   /** NWDIR BEAN CONSTRUCTOR **/       nwDirBean = new NWDir();    // each client connection gets its very own NWDir bean    server = theServer;     client = client_socket;     try     {   inFromClient = new DataInputStream ( client.getInputStream() );         outToClient = new PrintStream ( client.getOutputStream () );    }       catch( IOException e )      {   System.out.println ( "Exception while getting socket streams:"+e);          e.printStackTrace();        try         {   client.close();     }           catch(IOException e2 )          {   System.out.println ( "Error while attempting to close");    }           return;     }       this.start();   // causes the JVM to call this thread's run() when its ready    }/**************************************************************************run()      * Obligatory thread method that is called by thread manager after this       thread is started with start().**************************************************************************/   public void run ()   {   dispatchRequest();  }

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = These AnyInfoClientConnection methods contain no NWDir calls but they are called by the methodsthat do. To save space and tedium only their descriptions are shown here:- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private void dispatchRequest() // called by AnyInfoClientConnection's run() method     * dispatchRequest() parses the client's request buffer to figure out what to do with it       and then calls whatever is needed to do the right thing.     * If the request is supposed to be handled in the client proxy (only REQ_GET_TREE_LIST       and REQ_GET_DB_LIST are handled here) the specified response is developed       and returned to the client.     * All other requests are forwarded to the appropriate AnyInfo access Application       fronting an AnyInfo database server to be serviced.      * All tree names, IP addresses, etc. needed to service the request are obtained        from the request buffer sent by the client applet. The client applet maintains        this information as it interacts with the user. private String iPAddress2String( byte[] adx )       * Converts a byte array TCP address value from a NWDir bean "Net Address" attribute         into a String. private String shuffleName4Bean( String ndsStyleName )       * Converts an NDS style distinguished name (e.g., OBJNAME.ORGUNIT.ORG) into an NWDir       bean style name (e.g., ORG\ORGUNIT\OBJNAME). public String sendReceive2AccessProxy ( String ipAddress, String request )       * Given an appropriate IP address sendReceive2AccessProxy() forwards a request         buffer to an AnyInfo access proxy application fronting an AnyInfo database         server somewhere on the network and recieves its response.       * The stream's printLn() and readLine() are synchronous calls and block automatically. void sendReplyAndFlush ( String proxyApp2ClientAppletBfr )       * Sends the response from the AnyInfo client proxy application to the      AnyInfo client Applet which initiated this connection. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = *//**************************************************************************getTreeList() - called by dispatchRequest()       * Obtains a list of tree names in an Enumeration and puts them into         a buffer for transmittal back to the AnyInfo client Applet.***************************************************************************/   public String getTreeList()   {String resultStr = new String();
4.
     /** NWDIR BEAN METHOD **/Enumeration treeList = nwDirBean.getTrees();while ( treeList.hasMoreElements() ){String name = (String)treeList.nextElement();    if( name != null)        resultStr = resultStr+name+BUFFER_ITEM_DLIMTER; } return(resultStr);  }/**************************************************************************setTreeName() - called by dispatchRequest() before it calls getBfr4AllAnyInfoObjList()* Creates an instance of the NWDir bean for this client connection.       * Sets the NWDir bean's context to the selected tree (the tree name is         sent to this application by the AnyInfo client Applet in response to         the users tree selection).***************************************************************************/   public void setTreeName(String theTreeName)   {       try        {String fullTreeName = NWDir.PREFIX+theTreeName;

5.  /** NWDIR BEAN METHOD **/    nwDirBean.setFullName(fullTreeName);    treeName = theTreeName;   }   catch(NWBeanException e)   {e.printStackTrace();}}/**************************************************************************getBfr4AllAnyInfoObjList() - called by dispatchRequest()* Obtains a list of all regular AnyInfo objects in the selected NDS tree and sequences through each one of them to make sure that each has a reference to an accessable database server object in the tree and that the server referenced by the server object is able to communicate.* If an AnyInfo object has a reference to a valid database server, the database name and administrator is then read from the object as well.* When complete, the buffer (a big String) will contain the database names,   their IP addresses, and administrator names for all of the AnyInfo objects   in the tree. This is the information needed by the client applet for   the user to make a database selection. The selected database's IP address is then sent along with all further queries database.* The client applet will retrieve the database subject names from the buffer and present them to the user so that a database can be selected.***************************************************************************/ public String getBfr4AllAnyInfoObjList( ) {String infoLists = new String("");
6.
 Enumeration anyInfoObj_enum = getAnyInfoDNamesFromAnyInfoListObj();if ( anyInfoObj_enum != null ){  while ( anyInfoObj_enum.hasMoreElements() )   {NWValueDistinguishedName listEntryValue =    (NWValueDistinguishedName)anyInfoObj_enum.nextElement();if( listEntryValue != null )   {   String anyInfoObjDistName = listEntryValue.toString();    anyInfoObjDistName = shuffleName4Bean(anyInfoObjDistName);        try     {       /** NWDIR BEAN METHOD **/           NWEntry anyInfoObjEntry  =           nwDirBean.findEntry(NWDir.PREFIX+treeName+anyInfoObjDistName);     NWEntry serverObj = getDSEntry4Server( anyInfoObjEntry );
7
      String databaseSrvrIPAdx = getIPAddress4AnyInfoSrvrObj( serverObj );            if( databaseSrvrIPAdx != null )
8
        {  String dbSubjectName = getAnyInfoDBSubjectName( anyInfoObjEntry );          String oprtrDName = getAnyInfoOperatorName( anyInfoObjEntry );          if(dbSubjectName != null
        }   }   catch( NWBeanException e )  {  System.out.println ("getBfr4AllAnyInfoObjList - NWBeanException" );     e.printStackTrace();    infoLists = null;    }      }    }  }  return ( infoLists );}

/***************************************************************************getAnyInfoDNamesFromAnyInfoListObj() - called by getBfr4AllAnyInfoObjList()     * Obtains a list of distinguished names corresponding to every       regular AnyInfo object in the selected tree.     * getAnyInfoDBsFromAnyInfoListObj() obtains this list by reading all       ANY_INFOLIST_ENTRY_ATTRNAME attributes from the AnyInfoList object       located at the root of the selected tree.**************************************************************************/ private Enumeration getAnyInfoDNamesFromAnyInfoListObj() {Enumeration server_enum = null;  try  {String entryString = NWDir.PREFIX+treeName+B_SLASH+ANY_INFOLIST_OBJECTNAME;   /** NWDIR BEAN METHOD **/       NWEntry listObj  = nwDirBean.findEntry( entryString );     /** NWDIR BEAN METHOD **/       server_enum = listObj.getFieldValues(ANY_INFOLIST_ENTRY_ATTRNAME);  }  catch( NWBeanException e )  {    e.printStackTrace();    }  return (server_enum); }/**************************************************************************getDSEntry4Server() - called by getBfr4AllAnyInfoObjList()       * Given an NWEntry which references a regular AnyInfo object in         an NDS tree, getDSEntry4Server() will read the server distinguished         name value from its ANY_INFO_SERVER_ATTRNAME attribute.       * The obtained distinguished name is used to find the server object         in the tree and instantiate an NWEntry object referring to it.***************************************************************************/ private NWEntry getDSEntry4Server(NWEntry anyInfoObj) {NWEntry serverObj  = null;   try   {   /** NWDIR BEAN METHOD **/       NWValueDistinguishedName serverDName =               (NWValueDistinguishedName)anyInfoObj.getFieldValue( ANY_INFO_SERVER_ATTRNAME );                      String shuffledServerName =          NWDir.PREFIX+treeName+shuffleName4Bean( serverDName.toString() );   /** NWDIR BEAN METHOD **/       serverObj  = nwDirBean.findEntry( shuffledServerName );    }  catch( NWBeanException e )  {    e.printStackTrace();    }   return(serverObj); }/**************************************************************************getIPAddress4AnyInfoSrvrObj() - called by getBfr4AllAnyInfoObjList()       * Given an NWEntry which references an NCP Server object in         an NDS tree, getIPAddress4AnyInfoSrvrObj() will read the values from its         "Net Address" attribute.       * It then determines which of the "Net Address" values is the TCP address         and converts it from a byte array into a String.***************************************************************************/ protected String getIPAddress4AnyInfoSrvrObj( NWEntry serverObj ) {String databaseSrvrIPAdx = null;/** NWDIR BEAN METHOD **/   Enumeration netAdxs_enum = serverObj.getFieldValues( NET_ADDX_ATTRNAME ) ;

while ( netAdxs_enum.hasMoreElements() )    { NWValueNetAddress netAddxValue = (NWValueNetAddress)netAdxs_enum.nextElement();    /** NWDIR BEAN METHOD **/        long type = netAddxValue.getType();        if(  type == NWValueNetAddress.NT_TCP )        {        /** NWDIR BEAN METHOD **/            byte[ ] adx = netAddxValue.getAddress();            databaseSrvrIPAdx = iPAddress2String( adx);            break;       }   }   return( databaseSrvrIPAdx ); }/**************************************************************************getAnyInfoDBSubjectName() - called by getBfr4AllAnyInfoObjList()       * Given an NWEntry which references a regular AnyInfo object in         an NDS tree, getAnyInfoDBSubjectName() will read the name of the         database (e.g., "Address Book") value from its ANY_INFO_SUBJECT_ATTRNAME attribute.***************************************************************************/ private String getAnyInfoDBSubjectName(NWEntry anyInfoObj) {String databaseValStr  = null;   if(anyInfoObj != null )   {   /** NWDIR BEAN METHOD **/       NWValueCaseIgnoreString subjectValue =               (NWValueCaseIgnoreString)anyInfoObj.getFieldValue( ANY_INFO_SUBJECT_ATTRNAME );       databaseValStr = subjectValue.toString();   }   return(databaseValStr); }/**************************************************************************getAnyInfoOperatorName() - called by getBfr4AllAnyInfoObjList()       * Given an NWEntry which references a regular AnyInfo object in         an NDS tree, getAnyInfoDBSubjectName() will read the distinguished name for the         administrator's user object from its ANY_INFO_OPRTR_ATTRNAME attribute.***************************************************************************/private String getAnyInfoOperatorName(NWEntry anyInfoObj) {String oprtrDNameValStr  = null;   if(anyInfoObj != null )   {   /** NWDIR BEAN METHOD **/       NWValueDistinguishedName oprtrDName =               (NWValueDistinguishedName)anyInfoObj.getFieldValue( ANY_INFO_OPRTR_ATTRNAME );       oprtrDNameValStr = oprtrDName.toString();   }  return(oprtrDNameValStr); }
  1. These are the String IDs for the NDS schema extensions made by AnyInfo's ConsoleOne snap-ins. AnyInfo requires that a tree's schema be extended with two new classes and four attribute definitions. For a description of NDS terms, refer to the "Some Standard NDS Terminology" section above. For more information on the schema extensions required by AnyInfo and the ConsoleOne snap-in code that is used to create and manage objects instantiated from them, refer to example four of this series in the August issue of this magazine.

    The AnyInfo class describes an object that will contain information about an AnyInfo database, including its location on the network. There are three AnyInfo attributes referred to in this code:

    • The Subject Name This attribute is needed to contain the name given to a database by an administrator. Users select from a list of subject names to select the AnyInfo database that they want to connect to.

    • AnyInfo:Server The AnyInfo Server attribute contains the distinguished name of the server object representing the server running an AnyInfo database. In the AnyInfo application, when the list of databases is developed by the client proxy, the IP address of each server object is read. After the user selects an AnyInfo database subject name, the corresponding IP address is used to make the connection to the database server.

    • AnyInfo:Operator The AnyInfo Operator attribute is intended to contain the distinguished name of the user object representing the person responsible for loading the AnyInfo database on the server named in the AnyInfo Server attribute. In the AnyInfo application, this attribute will be accessed if an attempt to connect with the AnyInfo database on the host server fails for some reason.

    The AnyInfoList class describes an object that will contain a list of references to all of the AnyInfo objects in a tree. The AnyInfoListEntry attribute is a multi-valued attribute, meaning it can contain many values. As the administrator uses AnyInfo ConsoleOne snap-ins to create regular AnyInfo objects, they will automatically add distinguished names for the new objects as attribute values to the AnyInfoListEntry attribute in the AnyInfoList object at the root of the tree.

  2. This is the name of the single AnyInfoList object created at the root of the tree by AnyInfo's ConsoleOne snap-ins when they extend the tree's schema. For more information on the schema extensions required by AnyInfo and the ConsoleOne snap-in code that is used to create and manage objects instantiated from them, refer to example four of this series in the August issue of this magazine.

  3. The AnyInfoClientProxyApplic is the main class in this application. It contains a ServerSocket which is used to continually listen for client connections. When the AnyInfoClientProxyApplic class detects a client connection, it instantiates an instance of the AnyInfoClientConnection class to handle it. AnyInfoClientConnection extends Java's Thread class, so when it calls Thread's start( ) method, Java's thread manager will give time to AnyInfoClientConnection's run( ) method on a new thread.

    The first thing that AnyInfoClientConnection's run( ) method does is instantiate an instance of the NWDir( ) bean. Note that there is no preliminary setup to create an NWDir bean. However, it does need to know the context for future calls made to it, i.e. what tree is it supposed to be interacting with. This context will be set after the user makes a tree selection.

  4. The NWDir bean's getTrees( ) method is called in the client proxy in response to the user selecting the "Get Trees" button on the applet's main window. At this point, all of the other buttons on the main window are disabled. A buffer is sent back to the applet to allow the user to select a tree. When the user selects the tree, the applet will send the tree name back to the client proxy in a request for the AnyInfo databases on that tree.

  5. After the user makes the tree selection, the client proxy's dispatchRequest( ) method calls the setTreeName( ) method containing the NWDir bean's setFullName( ) method to set the bean's context to the selected tree so that bean calls to find objects can be made later in the getBfr4AllAnyInfoObjsList( ) method.

    Note: The NWDir bean can only deal with the NDS namespace type. Even so, it still requires that full names be prefixed with "NDS:\\". This prefix convention makes the NWDir bean consistent with other Novell beans, which can deal with multiple namespace types.

  6. The client proxy's getBfr4AllAnyInfoObjList( ) method is called after the NWDir bean's context has been set to the user selected tree. The first thing that getBfr4AllAnyInfoObjList( ) does is to call getAnyInfoDNamesFromAnyInfoListObj( ) to obtain a list of all AnyInfo objects in the tree.

    getBfr4AllAnyInfoObjList( ) sequences through the list of AnyInfo objects to gather information about the database referred to by each object.

    Notice that each name submitted to the NWDir bean's findEntry( ) method requires a name format that is different than a conventional NDS name. The client proxy method, shuffleName4Bean( ) is called to convert the NDS style distinguished name (e.g., OBJNAME.ORGUNIT.ORG) from the AnyInfoList object into an NWDir bean style name (e.g., ORG\ORGUNIT\OBJNAME).

    The NWDir bean's findEntry( ) method returns a reference to an NWEntry object which is essentially equivalent to an NDS object reference. See "Some Differences Between Standard NDS and NWDir Bean Terminology", above for more information on what the NWDir term "object" means.

  7. The client proxy's getBfr4AllAnyInfoObjList( ) method calls the getIPAddress4AnyInfoSrvrObj( ) method for each AnyInfo object obtained from the AnyInfoList object. The purpose of the getIPAddress4AnyInfoSrvrObj( ) method is to use the Server attribute value from the AnyInfo objects to look up their NCP Server objects in the tree. If the server objects can be accessed, their Net Address attributes are read. A Net Address can contain lots of different types of addresses, including IPX and IP types. The client proxy is looking for a Net Address of type NT_TCP.

  8. If the client proxy's getIPAddress4AnyInfoSrvrObj( ) method can obtain a valid IP address from an AnyInfo object's server reference, the database name and administrator name attribute values are also read and added to the response buffer.

Normally, default NDS security would require that an NDS user object representing the person that obtained the current connection to this NDS tree be listed in the read AnyInfo object's access control list (or ACL) before a read operation would be allowed. However, the AnyInfo client proxy can read all of these AnyInfo attributes without an authenticated connection to the tree because all of the AnyInfo attributes were defined as having the DS_PUBLIC_READ context flag set when the tree's schema was extended for them.

Attributes defined with the DS_PUBLIC_READ context flag are exempt from normal NDS security and can be read by anyone with Browse rights, i.e., any member of PUBLIC.

Conclusion

The NWDir bean is easy and fun to use, yet highly functional.

Since the NWDir bean is Java and therefore cross-platform, it could be used to give client side applications the ability to access NDS as well.

However, wherever you use NWDir, you will need to install NJCL (Novell Java Class Library) which will in turn require other things to be installed. So, the NWDir bean is particularly suitable for server side use because, by using the NWDir bean on the server, your clients can access the application with applets only, and no client software installation or maintenance is necessary.

For more information about other examples in this series, refer to: http://developer.novell.com/education/roadmap

To download the project corresponding to this article, refer to: http://www.novell.com/coolsolutions/tools/15618.html


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© 2014 Novell