/***************************************************************************
 %name: Streams.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.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
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.java.io.NOutputStream;
import com.novell.java.io.NInputStream;
import com.novell.java.io.RandomAccess;
import com.novell.utility.naming.Environment;

/**
 * Streams and Random Access example
 *
 * <p>This program demonstrates how to do input stream, output stream and
 * random access to an existing file.  The ExtendedAttribute and FileCreator
 * classes demonstrate the use of Subordinate Streams.  See these two classes
 * for more information.  WARNING, file data in file specified by URL will be
 * lost
 *
 * </p>
 *
 * @see ExtendedAttribute
 * @see FileCreator
 */

class Streams
{
   /**
    * Streams example
    *
    * <p>This example opens an InputStream on an existing file and reads it.
    * It then opens an OuputStream on the same file, and writes it.  It then
    * opens a RandomAccess on the same file, and reads it.  WARNING
    * any data in the file specified by the url will be lost!
    * </p>
    *
    * <p>This program requires a command line parameter.  The first
    * specifies the name of a Directory DirContext of your choice of which to
    * use as the parent. 
    * </p>
    *
    * @param   args[]
    * where    args[0]  url (the file to access)
    *                   The name of a Directory DirContext to be the
    *                   parent for the newly created directory.
    *                   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);

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

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

         System.out.println("\ncheckin data access on" + url + "\n");

         // if it's not DataAccessable quit
         if (obj instanceof DataAccessable)
         {
            // open an inputstream, and read the contexts
            is = new NInputStream((DataAccessable)obj);
            isOpen = true;

            byte[] buffer = new byte[80];  // get about 1 lines worth

            // while not eof, read the file
            int count;
            do
            {
               count = is.read(buffer);
               System.out.println(new String(buffer));
            }
            while(count != -1);
            is.close();
            isOpen = false;

            // open an output stream,  write with a well known pattern
            os = new NOutputStream((DataAccessable)obj);
            osOpen = true;
            sai.writeStream(os);
            os.close();
            osOpen = false;

            // open random access, verify well known pattern
            ra = new RandomAccess((DataAccessable)obj);
            raOpen = true;
            sai.readRandom(ra);
            ra.close();
            raOpen = 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();
            if (raOpen)
               ra.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 Streams <url>\n");
      System.out.println(
         "\t\turl = name of an existing file to do streams testing on");
      System.out.println("\t\t       my_server/my_volume/my_dir/my_file");
      System.out.println("");
      System.out.println("Warning: file data will be lost in specified file!");
      System.out.println("");
      System.exit(-1);
   }
}

