/***************************************************************************
 %name: Schema.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.NamingEnumeration;

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

import com.novell.java.io.NFile;
import com.novell.service.file.nw.NetwareFile;
import com.novell.service.file.nw.NetwareDirectory;
import com.novell.service.file.nw.NetwareVolume;
import com.novell.service.file.nw.naming.FSSchema;
import com.novell.utility.naming.Environment;

/**
 * Schema information on a File System DirContext and its attributes
 *
 * <p>This program demonstrates code that can be used to discover schema
 * information about a given File System name spaces DirContext and the
 * attributes that are associated with it.
 * </p>
 */

public class Schema
{
   /**
    * Schema example
    *
    * <p>This example shows how one might access the schema of a
    * DirContext from the NetWare file system name space
    * to determine the mandatory and optional attributes
    * </p>
    *
    * @param   args[]
    * where    args[0]  url (url to show schema on)
    *                   The name of a DirContext from the FileSystem
    *                   initial context.  For example:
    *                   "my_server/my_volume/my_dir"
    */

   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];
      StaticAttributeValueInterface sai = new TextualStatic(true);

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

      systemProps.put(Context.PROVIDER_URL, url);

      try
      {
         System.out.println("Looking up: " + url);

         // Get the initial context and look up the given name
         Object obj = new InitialContext(systemProps).lookup("");

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

         // cast the object to a DirContext
         DirContext context = (DirContext) obj;

         System.out.println("\nMandatory Attribute and Syntax Definitions\n");

         // get the Schema root of the DirContext
         DirContext root = context.getSchema("");

         // get the Schema Class Definition of the DirContext
         DirContext sctx = context.getSchemaClassDefinition("");

         // get the attributes of the Schema Class Definition
         Attributes sas = sctx.getAttributes("");

         // get the mandatory attributes list from the Schema Class Definition
         System.out.println("\t" + FSSchema.MANDATORY_ATTRIBUTE_IDS);
         Attribute sattr = (Attribute) sas.get(FSSchema.MANDATORY_ATTRIBUTE_IDS);
         if (sattr != null)
         {
            NamingEnumeration enum = sattr.getAll();

            while(enum.hasMore())
            {
               /*
                  the rules for Mandatory state that all values are strings
                  that have valid attribute IDs in them.
               */
               String attrid = (String) enum.next();

               /*
                  Get the Attribute Definition for the mandatory attribute
                  based on the attrid and well known names.
               */
               DirContext avsctx = (DirContext) root.lookup(
                  FSSchema.ATTRIBUTE_DEFINITIONS + "/" +
                  attrid + FSSchema.SCHEMA_BINDING_SUFFIX);

               // Get all the Attributes of the Attribute Definition
               Attributes avsas = avsctx.getAttributes("");

               // Display the mandatory Attribute values type
               System.out.println("\t\t\t" + FSSchema.ATTRIBUTE_TYPE);
               Attribute avsattr = avsas.get(FSSchema.ATTRIBUTE_TYPE);
               // based on ATTRIBUTE_TYPE rules, the following line is safe
               String avtype = (String) avsattr.getAll().next();
               System.out.println("\t\t\t\t" + avtype);

               /*
                  Example of how one might watch for a type that they know
                  about.
               */
               if (avtype.equals(
                     "com.novell.service.file.nw.DirectoryEntryInformation"))
                  sai.handleDirectoryEntryInformation((NetwareFile)context);

               if (avtype.equals(
                     "com.novell.service.file.nw.TrusteeEnumerator"))
                  sai.handleTrusteeEnumerator((NetwareFile)context);

               if (avtype.equals("com.novell.service.file.nw.EAEnumerator"))
                  sai.handleEAEnumerator((NetwareFile)context);

               if (avtype.equals(
                     "com.novell.service.file.nw.DirectorySpaceInformation"))
                  sai.handleDirectorySpaceInformation((NetwareDirectory)context);

               if (avtype.equals(
                     "com.novell.service.file.nw.VolumeInformation"))
                  sai.handleVolumeInformation((NetwareVolume)context);

               if (avtype.equals(
                     "com.novell.service.file.nw.VolumeRestrictionEnumerator"))
                  sai.handleVolumeRestrictionEnumerator((NetwareVolume)context);

               if (avtype.equals(
                     "com.novell.service.file.nw.VolumeUtilization"))
                  sai.handleVolumeUtilization(
                        (NetwareVolume) context,
                        "admin+1");

               // display the interfaces that the attribute value implements
               System.out.println("\t\t\t" + FSSchema.INTERFACES_IMPLEMENTED);
               avsattr = avsas.get(FSSchema.INTERFACES_IMPLEMENTED);
               NamingEnumeration avsenum = avsattr.getAll();
               while (avsenum.hasMore())
               {
                  System.out.println("\t\t\t\t" + (String) avsenum.next());
               }
            }
            System.out.println("\n");
         }

         /*
           Show an Example of discovering a needed interface at the Class
           Definition level.  This is functionally identical to the example
           given for Attribute Type.
         */
         System.out.println("\t" + FSSchema.INTERFACES_IMPLEMENTED);
         sattr = (Attribute) sas.get(FSSchema.INTERFACES_IMPLEMENTED);
         if (sattr != null)
         {
            NamingEnumeration enum = sattr.getAll();

            while(enum.hasMore())
            {
               String inter = (String) enum.next();
               System.out.println("\t\tvalue: " + inter);
               if (inter.equals("com.novell.java.io.NFile"))
                  sai.handleNFile((NFile)context);

               if (inter.equals("com.novell.service.file.nw.NetwareVolume"))
                  sai.handleNetwareVolume((NetwareVolume)context, "admin+1");

               if (inter.equals("com.novell.service.file.nw.NetwareDirectory"))
                  sai.handleNetwareDirectory((NetwareDirectory)context);

               if (inter.equals("com.novell.service.file.nw.NetwareFile"))
                  sai.handleNetwareFile((NetwareFile)context);
            }
            System.out.println("\n");
         }
      } // end try block
      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:");
      System.out.println("\tjava Schema <url>\n");
      System.out.println(
         "\t\turl = name of the DirContext to display Schema for");
      System.out.println(
         "\t\t       my_server/my_volume/my_dir");
      System.out.println("");
      System.exit(-1);
   }
}

