/***************************************************************************
 %name: GenericAttrList.java
 %version: 
 %date_modified: 
 %dependencies: TextualStatic.java
 
 Copyright (c) 1998 Novell, Inc. All Rights Reserved.

 THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
 USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
 ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
 PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
 ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS
 PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
 DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S
 PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S
 CUSTOMERS WITH RESPECT TO THIS CODE.
****************************************************************************/

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;

import javax.naming.directory.DirContext;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;

import com.novell.utility.naming.Environment;

/**
 * Generic code for listing JNDI Attribute IDs and their value types
 *
 * <p>This program demonstrates generic code that can be used to display a
 * specified DirContexts Attribute IDs and their associated value types.
 *
 *<p>Since this is generic code, this program prints the types of the
 * attribute values and the types of the interfaces that it implements,
 * rather than the actual values of the attributes.
 *
 * <p>In specific code, the attribute value objects can be cast to the actual
 * types or interface as needed.
 * </p>
 */

public class GenericAttrList
{
   /**
    * GenericAttrList example
    *
    * <p>This example lists the Attributes of a generic JNDI DirContext.
    * </p>
    * <p>This program requires a command line parameter which specifies the
    * name of a DirContext of your choice of which to display the attribute
    * values for.
    * </p>
    *
    * @param   args[]
    * where    args[0]  url (url to list)
    *                   The name of a DirContext from the NetWare
    *                   initial context.  For example:
    *                   "Servers/my_server/FileSystem/my_volume/my_dir"
    *                   "Trees/my_tree/my_tree_volume.my_context"
    */

   public static void main(String args[])
   {
      // see if user has given the URL on the command line
      if (args.length < 1)
      {
         help();
      }

      String url = args[0];

      // Set the initial context factory to NetWareInitialContextFactory
      Hashtable systemProps = new Hashtable();
      systemProps.put(
         Context.INITIAL_CONTEXT_FACTORY,
         Environment.NW_INITIAL_CONTEXT_FACTORY);

      try
      {
         // Get the initial context
         Context initialCtx = new InitialContext (systemProps);

         // Look up the object named by the command line parameter.
         System.out.println("Looking up: " + url + "\n");
         Object obj = initialCtx.lookup(url);

         /*
            See if the object is a DirContext. If it isn't a
            DirContext, the object does not have attributes.
         */
         if(!(obj instanceof DirContext))
         {
            System.out.println("This object is NOT a DirContext.");
            System.out.println("There are no attributes to display.");
            System.exit(1);
         }

         // Cast the object to a DirContext
         DirContext currCtx = (DirContext) obj;

         // Get a set of the object's attributes.
         Attributes attrSet=currCtx.getAttributes("");

         // Print the number of attributes in the set.
         System.out.println("There are " +
            attrSet.size() +
            " attributes in this attribute set.");

         // Process the attributes in the set.
         NamingEnumeration attrEnum=attrSet.getAll();
         while(attrEnum.hasMore())
         {
            // Get the attribute from the attribute set.
            Attribute attr = (Attribute)attrEnum.next();

            // Print the attribute's ID.
            System.out.println(
               "\nAttribute ID: \"" + attr.getID());

            //  get the Attribute value enumerator from the attribute
            NamingEnumeration attrValueEnum = attr.getAll();

            // display the number of attribute values in the Attribute
            System.out.println(
               "number of value objects: " + attr.size());

            /*
               iterate through the value objects,
               print the type, and the interfaces that it implements on the
               first value
            */
            boolean typeShown = false;
            while(attrValueEnum.hasMore())
            {
               // Get the value
               Object value = attrValueEnum.next();

               // if it's the first value, print its types and interfaces
               if (!typeShown)
               {
                  Class valueClass = value.getClass();
                  do
                  {
                     // print the hierarchy of this values type
                     System.out.println(
                        "Value Object Type: " + valueClass.getName());
                     valueClass = valueClass.getSuperclass();
                  }
                  while(valueClass != null);

                  // list all the interfaces that this object implements
                  Class[] interfaces = value.getClass().getInterfaces();
                  for (int i=0; i < interfaces.length; i++)
                  {
                     System.out.println(
                        "implements: " + interfaces[i].getName());
                  }
                  typeShown = true;
               }
            }
         }
      }
      catch (javax.naming.NamingException e)
      {
         System.out.println("Exception thrown: " + e);
         e.printStackTrace();
         System.exit(-1);
      }
      System.exit(0);
   }

   private static void help()
   {
      System.out.println(
         "\nTo use this example program enter the following:\n");
      System.out.println(
         "\tjava GenericAttrList <url>\n");
      System.out.println(
         "\t\turl = name of the DirContext to display, for example:");
      System.out.println(
         "\t\t       Servers/my_server/FileSystem/my_volume/my_dir/... or");
      System.out.println(
         "\t\t       Trees/my_tree/my_tree_volume.my_context");
      System.out.println("");
      System.exit(-1);
   }
}

