/***************************************************************************
 %name: ExtendedAttribute.java
 %version: 
 %date_modified: 
 %dependencies: none
 
 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.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.util.Hashtable;

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

import com.novell.java.io.DataAccessable;
import com.novell.service.file.nw.DataAccessableParameters;
import com.novell.service.file.nw.NFileOutputStream;
import com.novell.service.file.nw.NFileInputStream;
import com.novell.utility.naming.Environment;

/**
 * Creates an extended attribute on the specified DirContext
 *
 * <p>This program demonstrates how to create and access an extended
 * attribute on a file or a directory.  The file or directory must already
 * exist.  This is also an example of how subordinate streams work.  See
 * the Streams class for more information on using streams and random access
 * to file data.
 * </p>
 *
 * @see Streams
 */

class ExtendedAttribute
{
   /**
    * ExtendedAttribute example
    *
    * <p>This example creates then reads an extended attribute on a file or
    * directory DirContext in the NetWare file system name space.  The file
    * or directory that is having the extended attribute added to must
    * already exist.  Remember, there is no way to delete an extended
    * attribute after it has been created.
    * </p>
    *
    * @param 
    * where    args[0]  url (url of DirContext to add EA to)
    *                   The name of a Directory or File DirContext
    *                   to receive the Extended Attribute.
    *                   For example:
    *                   "my_server/my_volume/my_dir"
    *          args[1]  ea (New file name to create)
    */

   public static void main(String args[])
   {
      // see if user has given the URL and ea name on the command line
      if (args.length < 2)
      {
         help();
      }
            
      String url = args[0];
      String ea = args[1];
      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);

      // monitor open states so catch can close them if needed
      boolean osOpen = false;
      boolean isOpen = false;
      OutputStream os = null;
      InputStream is = null;

      try
      {
         // Look up the object named by the command line parameter.
         Object obj = new InitialContext(systemProps).lookup("");

         System.out.println("\nCreating EA " + ea + " in " + url + "\n");
         /*
            if it's DataAccessable, use a subordinate output stream
            to create and then read the EA.
         */

         if (obj instanceof DataAccessable)
         {
            // create the new Extended Attribute
            os = new NFileOutputStream(
               ea,
               (DataAccessable)obj,
               DataAccessableParameters.READ_WRITE,
               DataAccessableParameters.EA_STREAM_SELECTOR);
            osOpen = true;

            // write a known pattern to the extended attribute, and close
            sai.writeStream(os);
            os.close();
            osOpen = false;

            // open the newly created Extended Attribute and verify contents
            is = new NFileInputStream(
               ea,
               (DataAccessable)obj,
               DataAccessableParameters.READ,
               DataAccessableParameters.EA_STREAM_SELECTOR);
            isOpen = true;

            // read and verify well know pattern then close
            sai.readStream(is);
            is.close();
            isOpen = false;
         }
         else
         {
            System.out.println("error: " + url + " is not DataAccessable");
            System.exit(-1);
         }
      }
      catch (IOException ioe)
      {
         try
         {
            if (osOpen)
               os.close();
            if (isOpen)
               is.close();
         } 
         catch (IOException nested)
         {
            System.out.println("error with close in catch: " + nested);
            nested.printStackTrace();
         }

         System.out.println("error with stream: " + ioe);
         ioe.printStackTrace();
         System.exit(-1);
      }
      catch(javax.naming.NamingException e)
      {
         System.out.println("\nException 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 ExtendedAtribute <url> <ea>\n");
      System.out.println(
         "\t\turl = name of the directory or file to create the new EA in");
      System.out.println("\t\t       my_server/my_volume/my_dir");
      System.out.println(
         "\t\tea  = new Extended Attribute name to create");
      System.out.println("");
      System.exit(-1);
   }
}

