//Warning: This code has been marked up for HTML

/***************************************************************************
 %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);
   }
}