/***************************************************************************
 %name: TextualDynamic.java
 %version: 
 %date_modified: 
 %dependencies: Textual.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 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.service.file.nw.NetwareVolume;
import com.novell.service.file.nw.NetwareDirectory;
import com.novell.service.file.nw.NetwareFile;
import com.novell.service.file.nw.DirectoryEntryInformation;
import com.novell.service.file.nw.Trustee;
import com.novell.service.file.nw.TrusteeEnumerator;
import com.novell.service.file.nw.EAEnumerator;
import com.novell.service.file.nw.ExtendedAttribute;
import com.novell.service.file.nw.DirectorySpaceInformation;
import com.novell.service.file.nw.VolumeInformation;
import com.novell.service.file.nw.VolumeRestrictionEnumerator;
import com.novell.service.file.nw.VolumeRestriction;
import com.novell.service.file.nw.VolumeUtilization;

/** 
 * Declares methods that would handle the various attribute values
 *
 * <p>This class provides common support for several of the file systems
 * example programs.  It is entended to provide and example of utilizing the
 * dynamic attribute value interfaces.
 * </p>
 *
 * @see DirectoryAttrList
 * @see FileAttrList
 * @see VolumeAttrList
 * @see Schema
 */

public class TextualDynamic implements DynamicAttributeValueInterface
{
   private boolean verbose;
   private Textual text;

   /**
    * Constructor that allows for the verbose flag to be set
    * 
    * @param verbose             be verbose if true
    */
    
   public TextualDynamic(boolean verbose)
   {
      this.verbose = verbose;  
      text = new Textual(verbose);
   }

   /**
    * Returns the attribute value which the other methods in this class can
    * utilize.
    * 
    * <p>Given an attribute id and a DirContext, this method gets the 
    * JNDI attribute set, the attribute and then the value associated with
    * the given attribute id for the given DirContext.
    *
    * <p>The file system DirContexts have two kinds of Attribute values.  The
    * first are single valued.  The object returned can be cast to the 
    * appropriate type and passed into the various handler methods in this 
    * class.  The attrbutes of this type are:
    *
    *    DirectoryEntryInformation
    *    DirectorySpaceInformation
    *    VolumeInformation
    *    VolumeUtilization
    *
    * <p>The second type are multi-valued.  The NamingEnumerator of these are
    * retuned and then can be passed into the various handler methods in this
    * class.  The attributes of this type are:
    *
    *    TrusteeEnumerator
    *    EAEnumerator
    *    VolumeRestrictionEnumerator
    * </p>
    *
    * @param attId               Attribute ID of attribute to obtain.
    * @param context             The DirContext to obtain the attribute from.
    *
    * @return                    The attribute value. 
    */
    
   public Object getAttribute(String attrId, DirContext context)
   {
      try
      {
         // Get desired attribute set
         Attributes attrSet = context.getAttributes("",new String[]{attrId});
            
         // Get the attribute enumerator from the set.
         NamingEnumeration attrEnum = attrSet.getAll();

         /*
            We only asked for one Attribute ID, and so the attribute set
            will only contain one attribute, just get the enumerator from it.
         */

         NamingEnumeration nEnum = ((Attribute)attrEnum.next()).getAll();

         /*
            Watch for the TrusteeEnumerator and EAEnumerator, handle these
            seperately.  Return the whole enumerator (which might be empty).
         */

         if ((TrusteeEnumerator.ATTRIBUTE_ID.equals(attrId)) |
             (EAEnumerator.ATTRIBUTE_ID.equals(attrId)) |
             (VolumeRestrictionEnumerator.ATTRIBUTE_ID.equals(attrId)))
            return nEnum;

         /*
            Otherwise, it is a single valued attribute that is guaranteed
            to exist, just return it.
         */
         return nEnum.next();
      } 
      catch (NamingException ne)
      {
         System.out.println("Exception thrown: " + ne);
         ne.printStackTrace();
         System.exit(-1);
      }
      return null;
   }

   /**
    * Handles the DirectoryEntryInformation attribute value
    * 
    * <p>The DirectoryEntryInformation attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * DirectoryEntryInformation.ATTRIBUTE_ID attribute id.  The 
    * DirContext.modifyAttributes method can be used to modify the valid 
    * settable fields.
    *
    * <p>This attribute value is available for a NetwareVolume, 
    * NetwareDirectory or NetwareFile object.
    * </p>
    *
    * @param value               The DirectoryEntryInformation object
    * @param context             DirContext, used to modify
    *
    * @see com.novell.service.file.nw.DirectoryEntryInformation
    */
    
   public void handleDirectoryEntryInformation(
      DirectoryEntryInformation value,
      DirContext context)
   {
      text.displayDirectoryEntryInformation(value);
   }

   /**
    * Handles the TrusteeEnumerator attribute value
    * 
    * <p>The TrusteeEnumerator attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * TrusteeEnumerator.ATTRIBUTE_ID attribute id.  The 
    * DirContext.modifyAttributes method can be used to modify the valid 
    * settable fields (using Trustee objects).
    *
    * <p>This attribute value is available for a NetwareVolume, 
    * NetwareDirectory or NetwareFile object.
    * </p>
    *
    * @param value               NamingEnumerator, used to iterate through
    *                            Trustee objects.
    * @param context             DirContext, used to modify
    *
    * @see com.novell.service.file.nw.TrusteeEnumerator
    */
    
   public void handleTrusteeEnumerator(
      NamingEnumeration value,
      DirContext context)
   {
      try
      {
         int count = 0;
         while (value.hasMore())
         {
            text.displayTrustee((Trustee)value.next());
            ++count;
         }
         message(
            "\t\t" + count + " " + Trustee.ATTRIBUTE_ID + "'s present\n");
      } 
      catch (NamingException ne)
      {
         System.out.println("Exception thrown: " + ne);
         ne.printStackTrace();
         System.exit(-1);
      }
   }

   /**
    * Handles the EAEnumerator attribute value
    * 
    * <p>The EAEnumerator attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * EAEnumerator.ATTRIBUTE_ID attribute id.  The 
    * DirContext.modifyAttributes method can be used to modify the valid 
    * settable fields (using ExtendedAttribute objects).
    *
    * <p>This attribute value is available for a NetwareVolume, 
    * NetwareDirectory or NetwareFile object.
    * </p>
    *
    * @param value               NamingEnumerator, used to iterate through
    *                            ExtendedAttribute objects.
    * @param context             DirContext, used to modify
    *
    * @see com.novell.service.file.nw.EAEnumerator
    */
    
   public void handleEAEnumerator(
      NamingEnumeration value,
      DirContext context)
   {
      try
      {
         int count = 0;
         while (value.hasMore())
         {
            text.displayExtendedAttribute((ExtendedAttribute)value.next());
            ++count;
         }
         message(
            "\t\t" + count + " " + ExtendedAttribute.ATTRIBUTE_ID + 
            "'s present\n");
      } 
      catch (NamingException ne)
      {
         System.out.println("Exception thrown: " + ne);
         ne.printStackTrace();
         System.exit(-1);
      }
   }

   /**
    * Handles the DirectorySpaceInformation attribute value
    * 
    * <p>The DirectorySpaceInformation attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * DirectorySpaceInformation.ATTRIBUTE_ID attribute id.  The 
    * DirContext.modifyAttributes method can be used to modify the valid 
    * settable fields.
    *
    * <p>This attribute value is available for a NetwareVolume and
    * a NetwareDirectory.
    * </p>
    *
    * @param value               The DirectorySpaceInformation object
    * @param context             DirContext, used to modify
    *
    * @see com.novell.service.file.nw.DirectorySpaceInformation
    */
    
   public void handleDirectorySpaceInformation(
      DirectorySpaceInformation value,
      DirContext context)
   {
      text.displayDirectorySpaceInformation(value);
   }

   /**
    * Handles the VolumeInformation attribute value
    * 
    * <p>The VolumeInformation attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * VolumeInformation.ATTRIBUTE_ID attribute id.  This attribute can
    * not be modified. 
    *
    * <p>This attribute value is available for a NetwareVolume.
    * </p>
    *
    * @param value               The VolumeInformation object
    *
    * @see com.novell.service.file.nw.VolumeInformation
    */
    
   public void handleVolumeInformation(
      VolumeInformation value)
   {
      text.displayVolumeInformation(value);
   }

   /**
    * Handles the VolumeRestrictionEnumerator attribute value
    * 
    * <p>The VolumeRestrictionEnumerator attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * VolumeRestrictionEnumerator.ATTRIBUTE_ID attribute id.  The 
    * DirContext.modifyAttributes method can be used to modify the valid 
    * settable fields (using VolumeRestriction objects).
    *
    * <p>This attribute value is available for a NetwareVolume.
    * </p>
    *
    * @param value               NamingEnumerator, used to iterate through
    *                            VolumeRestriction objects.
    * @param context             DirContext, used to modify
    *
    * @see com.novell.service.file.nw.VolumeRestrictionEnumerator
    */
    
   public void handleVolumeRestrictionEnumerator(
      NamingEnumeration value,
      DirContext context)
   {
      try
      {
         int count = 0;
         while (value.hasMore())
         {
            text.displayVolumeRestriction((VolumeRestriction)value.next());
            ++count;
         }
         message(
            "\t\t" + count + " " + VolumeRestriction.ATTRIBUTE_ID + 
            "'s present\n");
      } 
      catch (NamingException ne)
      {
         System.out.println("Exception thrown: " + ne);
         ne.printStackTrace();
         System.exit(-1);
      }
   }

   /**
    * Handles the VolumeUtilization attribute value
    * 
    * <p>The VolumeUtilization attribute value can be obtained from 
    * the DirContext.getAttributes method using the 
    * VolumeUtilization.ATTRIBUTE_ID attribute id.  This attribute can
    * not be modified. 
    *
    * <p>Volume Utilization is unique in that you must set the object name
    * before you can access any of the other setter or getter methods.  This 
    * is because the utilization information is obtained for the user that 
    * you specify at this time.
    *
    * <p>The JNDI dynamic attribute interface does not allow for the passing
    * of any parameters into the getAttributes interface.  This attribute 
    * value is designed to support the JNDI interface, that is why this
    * is the way it is.
    *
    * <p>This attribute value is available for a NetwareVolume.
    * </p>
    *
    * @param value               The VolumeUtilization object
    * @param objectName          The object name to obtain data on
    *
    * @see com.novell.service.file.nw.VolumeUtilization
    */
    
   public void handleVolumeUtilization(
      VolumeUtilization value,
      String objectName)
   {
      value.setName(objectName);
      text.displayVolumeUtilization(value);
   }

   /**
    * Display a message to the user.  Displaying the value might be 
    * surpressed via a verbose flag in the actual implementation
    * 
    * @param value               value to display to the user
    */
    
   public void message(String value)
   {
      if (verbose)
      {
         System.out.print(value);
      }
   }
}