Previous     Contents     Index     DocHome     Next     
iPlanet Application Server Enterprise Connector of CICS Developer's Guide



Chapter 4   Programming Examples


You must know how to acquire UIF objects and execute functions by using function objects to program for the iPlanet Application Server Enterprise Connector for CICS. You also need to know how to use servlets with the iPlanet Application Server Enterprise Connector for CICS to access functions on a CICS EIS.

This chapter includes the following information:



CICS Sample

The CICS samples provided show the general flow of a connector program.


Activation

The CICS sample consist of servlets which activate CICS programs that access the CICS EIS.

You must have set up the environment before activating the samples. See Post Installation Issues in Chapter 2 of the iPlanet Application Server Enterprise Connector for CICS Administrator's Guide.


To Run the CICS Samples on NT

  1. Select Programs>iPlanet Application Server 6.0 > CICS Connector 6.0 - Sample Applications.

    The CICS samples page is displayed with links to the samples.

  2. Click on the link "To Start The PhoneBook Demo" to activate the PhoneBook servlet.


To Run the CICS Sample on Solaris

  1. Start your browser.

  2. Enter the following URL: <host name>:<web server port>/cicsSamples.

    The CICS Samples page appears, showing links to the Phone Book and Telco samples.


Phone Book Sample Operation

  1. Click on: To Start The PhoneBookDemo link

    The Phone Book Form dialog box is displayed.

  2. Type in the WebUserId and last name of the person for whom you want information.

  3. Click Display to show the person's details.

  4. The following display confirms the successful installation of the CICS connector.



Code Samples

The code samples are included to show the programmer how to set INPUT parameters, set the transaction name and get the OUPUT parameters.

This is a fully operational sample. You can use it as a model for building your own application.


PhoneBook Servlet Java Code

Code Example 4-1    PhoneBookServlet.java


/*

* @(#)SimpleServlet.java   1.22 97/10/25

*

* Copyright (c) 1996-1997 Sun Microsystems, Inc. All Rights Reserved.

*

* This software is the confidential and proprietary information of Sun

* Microsystems, Inc. ("Confidential Information"). You shall not

* disclose such Confidential Information and shall use it only in

* accordance with the terms of the license agreement you entered into

* with Sun.

*

* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE

* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE

* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR

* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES

* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING

* THIS SOFTWARE OR ITS DERIVATIVES.

*

* CopyrightVersion 1.0

*/

package PhoneBookDemo;

import java.io.*;

import com.kivasoft.IContext;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

import javax.naming.*;

import javax.naming.spi.*;

import netscape.bsp.*;

import netscape.bsp.runtime.*;

import netscape.bsp.dataobject.*;

import netscape.bsp.BspException.*;

//    <form action="/NASApp/application name/PhoneBookServlet" method=get>

/**

* This is a simple example of an HTTP Servlet. It responds to the GET

* and HEAD methods of the HTTP protocol.

*/

public class PhoneBookServlet extends HttpServlet

{

   private TestDebug deb = new TestDebug("PhoneBookDemo.log");

   private Context _context;

   protected String getInputString(HttpServletRequest   request, String parameterName)

   {

      // This method is useful since getValString returns null on

      // some platforms and an empty string on other platforms for

      // missing input parameters.   It also removes any whitespace

      // characters that the user my have inadvertantly entered.

      String parameter = request.getParameter(parameterName);

      if (parameter != null)

      {

         parameter = parameter.trim();

      }

      return parameter;

   }

   Context getContext()

      throws Exception, BspException

   {

      Hashtable env = new Hashtable(11);

      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.kivasoft.eb.jndi.GDSInitContextFactory");

      if (_context == null)

      {

         _context = new InitialContext(env );

      }

      return _context;

   }

   private void Do(IBSPRuntime runtime, IBSPServiceProvider sp, String requestCode) throws BspException

   {

      int hr = 1;

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      deb.println("Before Do()");

      deb.println("TransactionControl");

      

      if( (runtime != null) && (sp != null) )

      {

         deb.println("Before createFunctionObject()");

         fn = runtime.createFunctionObject("CICS", "TransactionControl");

         deb.println("After createFunctionObject()");

         hr = sp.enable();

         deb.println("After enable(), hr = "+hr);

         if( fn != null )

         {

            hr = fn.useServiceProvider(sp);

            deb.println("After useServiceProvider(), hr = "+hr);

            

            hr = fn.prepare(requestCode);

          prop = fn.getProperties();

            

            if( prop != null )

            {

             //   prop.setAttrFString("CONNECTION.ConversationType", "POOLED");

            //   prop.setAttrFString("CONNECTION.Applid", "PHONBOOX");

            //   prop.setAttrFString("CONNECTION.Request", "SendAndEnd");

               // prop.setAttrFString("CONNECTION.LU", "A06CICS1");

            //   prop.setAttrFString("CONNECTION.TranName", "SRVX");

               // prop.setAttrFString("CONNECTION.RelayHost", "MF");

               // prop.setAttrFString("CONNECTION.RelayPort", "4701");

               // prop.setAttrFString("CONNECTION.TargetTranName", " ");

               // prop.setAttrFString("CONNECTION.TargetSYSID", " ");

               // prop.setAttrFString("CONNECTION.RelayRC", "00");

         //      prop.setAttrFString("CONNECTION.UseStub", "Y");

         //      prop.setAttrFString("CONNECTION.HoldConversation", "Y");

               prop.setAttrInt("CONNECTION.StubReason",0 );

               deb.println("Before execute()");

               hr = fn.execute();

               deb.println("After execute(), hr = "+hr);

               if( hr == 0 )    // ??????????????????????

               {

                  prop = fn.getProperties();

                  deb.println("After getProperties()");

                  if(prop != null)

                  {

                     deb.println(" * * * * * * ");

                     deb.println("APPLID: "+prop.getAttrFString("CONNECTION.Applid"));

                     // deb.println("UserID: "+prop.getAttrFString("CONNECTION.UserID"));

                     // deb.println("Password: "+prop.getAttrFString("CONNECTION.Password"));

                     deb.println("LU: "+prop.getAttrFString("CONNECTION.LU"));

                     deb.println("TargetSYSID: "+prop.getAttrFString("CONNECTION.TargetSYSID"));

                     // deb.println("RelayHost: "+prop.getAttrFString("CONNECTION.RelayHost"));

                     // deb.println("RelayPort: "+prop.getAttrFString("CONNECTION.RelayPort"));

                     deb.println("TranName: "+prop.getAttrFString("CONNECTION.TranName"));

                     deb.println("TargetTranName: "+prop.getAttrFString("CONNECTION.TargetTranName"));

                     deb.println("Request: "+prop.getAttrFString("CONNECTION.Request"));

                     deb.println("Applind: "+prop.getAttrFString("CONNECTION.Applind"));

                     deb.println("RC: "+prop.getAttrFString("CONNECTION.RC"));

                     deb.println("RelayRC: "+prop.getAttrFString("CONNECTION.RelayRC"));

                     deb.println("StubRC: "+prop.getAttrFString("CONNECTION.StubRC"));

                     deb.println("StubReason: "+Integer.toString(prop.getAttrInt("CONNECTION.")));

                     deb.println("StubRequest: "+prop.getAttrFString("CONNECTION.StubRequest"));

                     deb.println("UseStub: "+prop.getAttrFString("CONNECTION.UseStub"));

                     deb.println(" * * * * * * ");

                  }

               } // if(hr == 0)

               else

                  deb.println("Search Failed");

            } // if(prop != null)

            else

               deb.println("Search Failed");

         } // if( fn != null )

         else

            deb.println("Search Failed");

         hr = sp.disable();

         deb.println("After disable(), hr = "+hr);

      } // if( (runtime != null) && (sp != null) )

      else

         deb.println("Search Failed");

      deb.println(" ");

      return;

   }

   private dataRecord executePB(IBSPRuntime runtime, IBSPServiceProvider sp,

            String requestCode, dataRecord input) throws BspException

   {

      int hr = 1;

      IBSPFunctionObject fn = null;

      IBSPDataObject data = null, prop = null;

      String lastname = new String("");

      String firstname = new String("");

      String extension = new String("");

      String zipcode = new String("");

      dataRecord o_entry = null;

      deb.println("Before executePB()");

      deb.println("PhoneBook");

      if( (runtime != null) && (sp != null) )

      {

         deb.println("Before createFunctionObject()");

         fn = runtime.createFunctionObject("CICS", "phonebook");

         deb.println("After createFunctionObject()");

         hr = sp.enable();

         deb.println("After enable(), hr = "+hr);

         if( fn != null )

         {

            hr = fn.useServiceProvider(sp);

            deb.println("After useServiceProvider(), hr = "+hr+" requestCode : "+requestCode);

            hr = fn.prepare(requestCode);

            deb.println("After prepare(), hr = "+hr);

            data = fn.getDataBlock();

            deb.println("After getDataBlock()");

            if( data != null )

            {

               //            data.setAttrFString("CICS.INPUT.BDATA",   "");

               data.setAttrFString("INPUT.REQC", requestCode);

               data.setAttrFString("INPUT.LNAME",input.m_lastName);

               data.setAttrFString("INPUT.FNAME",input.m_firstName);

               data.setAttrFString("INPUT.EXTENTION",input.m_extension);

               data.setAttrFString("INPUT.ZIPC",input.m_zipcode);

               prop = fn.getProperties();

               deb.println("After getProperties()");

               if( prop != null )

               {

                  //prop.setAttrFString("CONNECTION.ConversationType", "POOLED");

                  //prop.setAttrFString("CONNECTION.Applid", "PHONBOOX");

                  //prop.setAttrFString("CONNECTION.Request", "SendAndEnd");

                  // prop.setAttrFString("CONNECTION.LU", "A06CICS1");

                  //prop.setAttrFString("CONNECTION.TranName", "SRVX");

                  // prop.setAttrFString("CONNECTION.RelayHost", "MF");

                  // prop.setAttrFString("CONNECTION.RelayPort", "4701");

                  // prop.setAttrFString("CONNECTION.TargetTranName", " ");

                  // prop.setAttrFString("CONNECTION.TargetSYSID", " ");

                  // prop.setAttrFString("CONNECTION.RelayRC", "00");

                //   prop.setAttrFString("CONNECTION.UseStub", "Y");

                //   prop.setAttrFString("CONNECTION.HoldConversation", "Y");

                  prop.setAttrInt("CONNECTION.StubReason",0 );

               }

               deb.println("Before execute()");

               hr = fn.execute();

               deb.println("After execute(), hr = "+hr);

               if( hr == 0 ) // ??????????????????????

               {

                  data = fn.getDataBlock();

                  deb.println("After getDataBlock()");

                  if( data != null )

                  {

                     deb.println(" * * * * * * ");

                     deb.println("MSG: "+data.getAttrFString("OUTPUT.MSG"));

                     deb.println("REQC: "+data.getAttrFString("OUTPUT.REQC"));

                     lastname = data.getAttrFString("OUTPUT.LNAME");

                     deb.println("LNAME: "+lastname);

                     firstname = data.getAttrFString("OUTPUT.FNAME");

                     deb.println("FNAME: "+firstname);

                     extension = data.getAttrFString("OUTPUT.EXTENTION");

                     deb.println("EXTENTION: "+extension);

                     zipcode = data.getAttrFString("OUTPUT.ZIPC");

                     deb.println("ZIPC: "+zipcode);

                     o_entry = new dataRecord(lastname, firstname, extension, zipcode);

                     o_entry.m_message = new String(data.getAttrFString("OUTPUT.MSG"));

                  }

                  prop = fn.getProperties();

                  deb.println("After getProperties()");

                  if(prop != null)

                  {

                     deb.println("APPLID: "+prop.getAttrFString("CONNECTION.Applid"));

                     // deb.println("UserID: "+prop.getAttrFString("CONNECTION.UserID"));

                     // deb.println("Password: "+prop.getAttrFString("CONNECTION.Password"));

                     deb.println("LU: "+prop.getAttrFString("CONNECTION.LU"));

                     deb.println("TargetSYSID: "+prop.getAttrFString("CONNECTION.TargetSYSID"));

                     // deb.println("RelayHost: "+prop.getAttrFString("CONNECTION.RelayHost"));

                     // deb.println("RelayPort: "+prop.getAttrFString("CONNECTION.RelayPort"));

                     deb.println("TranName: "+prop.getAttrFString("CONNECTION.TranName"));

                     deb.println("TargetTranName: "+prop.getAttrFString("CONNECTION.TargetTranName"));

                     deb.println("Request: "+prop.getAttrFString("CONNECTION.Request"));

                     deb.println("Applind: "+prop.getAttrFString("CONNECTION.Applind"));

                     deb.println("RC: "+prop.getAttrFString("CONNECTION.RC"));

                     deb.println("RelayRC: "+prop.getAttrFString("CONNECTION.RelayRC"));

                     deb.println("StubRC: "+prop.getAttrFString("CONNECTION.StubRC"));

                     deb.println("StubReason: "+Integer.toString(prop.getAttrInt("CONNECTION.StubReason")));

                     deb.println("StubRequest: "+prop.getAttrFString("CONNECTION.StubRequest"));

                     deb.println("UseStub: "+prop.getAttrFString("CONNECTION.UseStub"));

                     deb.println(" * * * * * * ");

                  }

               } // if(hr == 0)

               else

                  deb.println("Search Failed");

            } // if(data != null)

            else

               deb.println("Search Failed");

         

         } // if( fn != null )

         else

            deb.println("Search Failed");

         hr = sp.disable();

         deb.println("After disable(), hr = "+hr);

      

      } // if( (runtime != null) && (sp != null) )

      else

         deb.println("Search Failed");

      deb.println(" ");

      return o_entry;

   }

   private IBSPRuntime getRuntime() throws BspException

   {

      com.kivasoft.IContext _ctx =

         ((com.netscape.server.servlet.platformhttp.PlatformServletContext)

         getServletContext()).getContext();

      deb.println(" before access_cBSPRuntime.getcBSPRuntime ");

      IBSPRuntime ibspruntime = access_cBSPRuntime.getcBSPRuntime(_ctx, null, null);

      deb.println(" after access_cBSPRuntime.getcBSPRuntime ");

      return ibspruntime;

   }

   

   private IBSPServiceProvider getServiceProvider(IBSPRuntime runtime)

   {

      deb.println("Before createServiceProvider()");

      if (runtime != null)

         return runtime.createServiceProvider("CICS", "CICS_sp1");

      else

         deb.println("runtime is null");

      return null;

   }

   public dataRecord sendRequest(String i_requestCode, dataRecord i_entry,String WebUserId) throws Exception

   {

      dataRecord output = null;

      int operation = -1;

IBSPServiceProvider sp=null;

int hr=1;

try

{

      deb.println("i_requestCode : "+i_requestCode);

      deb.println(" Before getRuntime()");

      IBSPRuntime runtime = getRuntime();

      deb.println("After getRuntime()");

      if(   runtime != null )

      {

         deb.println("Before getServiceProvider()");

         sp = getServiceProvider(runtime);

         deb.println("After getServiceProvider()");

         if( sp != null )

         {

IBSPDataObject config=sp.getConfig();

      if(WebUserId!=null)

      {

         config.setAttrFString("WebUserId",WebUserId);

         deb.println("after set webuserid"+WebUserId);

}

            deb.println("requestCode : "+i_requestCode);

            if (i_requestCode.equals("TAD") ||

               i_requestCode.equals("ADD") ||

               i_requestCode.equals("DISPLAY") ||

               i_requestCode.equals("DELETE") ||

               i_requestCode.equals("UPDATE"))

               output = executePB(runtime,sp, i_requestCode, i_entry);

            

            if (i_requestCode.equals("PREPARE") ||

               i_requestCode.equals("ROLLBACK") ||

               i_requestCode.equals("COMMIT"))

               Do(runtime, sp, i_requestCode);

         }

         

      }

}

catch(BspException BspError)

{

if(sp!=null)

{

hr = sp.disable();

          deb.println("After disable(), hr = "+hr);

}

throw(BspError);

}

catch(Exception Error)

{

if(sp!=null)

{

hr = sp.disable();

          deb.println("After disable(), hr = "+hr);

}

throw(Error);

}

      return (output);

   }   

   /**

    * Handle the GET and HEAD methods by building a simple web page.

    * HEAD is just like GET, except that the server returns only the

    * headers (including content length) not the body we write.

    */

   public void doGet (

      HttpServletRequest   request,

      HttpServletResponse   response ) throws ServletException, IOException

   {

      deb.println("4. Before sendRequest ");

RequestDispatcher dispatcher=null;

try

{

String WebUserId=getInputString(request,"WebUserId");

      dataRecord input = new dataRecord(

            getInputString(request,"lastname"),

            getInputString(request,"firstname"),

            getInputString(request,"extension"),

            getInputString(request,"zipcode"));

      deb.println("4a. last Name : "+ input.m_lastName);

      String oper = null;

      oper = getInputString(request,"tad");

      if(oper == null)

         oper = getInputString(request,"add");

      if(oper == null)

         oper = getInputString(request,"disp");

      if(oper == null)

         oper = getInputString(request,"del");

      if(oper == null)

         oper = getInputString(request,"update");

      if(oper == null)

         oper = getInputString(request,"prepare");

      if(oper == null)

         oper = getInputString(request,"rollback");

      if(oper == null)

         oper = getInputString(request,"commit");

      deb.println("5. Operation:"+oper);

      dataRecord output = sendRequest(oper,input,WebUserId);

      deb.println("6. After sendRequest ");

      deb.println("7. first Name : "+ output.m_firstName);

      deb.println("8. extension : "+ output.m_extension );

      deb.println("9. zipcode   : "+ output.m_zipcode );

response.setContentType("text/html");

      dispatcher = getServletContext().getRequestDispatcher("/jsp/PhoneBookForm.jsp");

      request.setAttribute("lastname_value",output.m_lastName);

      request.setAttribute("firstname_value",output.m_firstName);

      request.setAttribute("extension_value",output.m_extension);

      request.setAttribute("zipcode_value",output.m_zipcode);

      request.setAttribute("message_value",output.m_message);

}

catch(BspException BspError)

    {

    deb.println("BspException:"+BspError.getMessage());

response.setContentType("text/html");

    dispatcher = getServletContext().getRequestDispatcher("/jsp/ExceptionForm.jsp");

IBSPDataObjectStructure info = null;

       info=BspError.getInfo();

       if (info != null && info.attrExists("msgid") )

          request.setAttribute("BspException",BspError.getMessage()+",Error code : " + info.getAttrInt("msgid"));

else

       request.setAttribute("BspException",BspError.getMessage());

    }

catch(Exception exception)

    {

    deb.println("Exception:"+exception.toString());

response.setContentType("text/html");

    dispatcher = getServletContext().getRequestDispatcher("/jsp/ExceptionForm.jsp");

    request.setAttribute("Exception",exception.toString());

    }

    dispatcher.include(request, response);

deb.println("8. before return ");

return;

   }

   /** handles the HTTP POST operation **/

   public void doPost (HttpServletRequest request,HttpServletResponse response)

      throws ServletException, IOException {

      doGet(request,response);

   }

}



PhoneBook JSP Sample Code

Code Example 4-2    PhoneBookForm.jsp

<%

   String lastname_value = "GRYNBAUM";

   /** get the error message from the request attributes **/

   Object obj1 = request.getAttribute("lastname_value");

   if (obj1!=null) {

      lastname_value = (String) obj1;

   }

%>

<%

   String firstname_value = "";

   /** get the error message from the request attributes **/

   Object obj2 = request.getAttribute("firstname_value");

   if (obj2!=null) {

      firstname_value = (String) obj2;

   }

%>

<%

   String extension_value = "";

   /** get the error message from the request attributes **/

   Object obj3 = request.getAttribute("extension_value");

   if (obj3!=null) {

      extension_value = (String) obj3;

   }

%>

<%

   String zipcode_value = "";

   /** get the error message from the request attributes **/

   Object obj4 = request.getAttribute("zipcode_value");

   if (obj4!=null) {

      zipcode_value = (String) obj4;

   }

%>

<%

   String message_value = "";

   /** get the error message from the request attributes **/

   Object obj5 = request.getAttribute("message_value");

   if (obj5!=null) {

      message_value = (String) obj5;

   }

%>

<%

   String WebUserId = "";

   /** get the error message from the request attributes **/

   Object obj6 = request.getParameter("WebUserId");

   if (obj6!=null) {

      WebUserId = (String) obj6;

   }

%>

<HTML>

<HEAD>

   <TITLE>Phone Book Demo</TITLE>

</HEAD>

<BODY>

<center>

<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="600" >

   <tr>

   <td VALIGN=TOP WIDTH="420">

   <form action="/NASApp/PhoneBookDemo/PhoneBookServlet" method=post>

   <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=6 WIDTH="100%">

      <tr>

         <td BGCOLOR="#8979C8">

            <b><font face="sans-serif,arial,helvetica" color=white>

            Phone Book Form</font></b>

         </td>

      </tr>

      <tr VALIGN=TOP>

         <td BGCOLOR="#666699">

         <p>

         <center>

         <TABLE BORDER=0 cellspacing=0 cellpadding=0>

         <tr>

            <td><font face="arial, helvetica, sans-serif" color=white size="-1">WebUserId:</font></td>

            <td><font face="arial, helvetica, sans-serif">

               <input type="text" name="WebUserId" size=20 maxsize=50 value="W2" ></font>

            </td>

         </tr>

         <tr>

            <td><font face="arial, helvetica, sans-serif" color=white size="-1">Last Name:</font></td>

            <td><font face="arial, helvetica, sans-serif">

               <input type="text" name="lastname" value="<%=lastname_value%>" size=20 maxsize=50></font>

            </td>

         </tr>

         <tr>

            <td><font face="arial, helvetica, sans-serif" color=white size="-1">First Name:</font></td>

            <td><font face="arial, helvetica, sans-serif">

               <input type="text" name="firstname" value="<%=firstname_value%>" size=20 maxsize=50></font>

            </td>

         </tr>

         <tr>

            <td><font face="arial, helvetica, sans-serif" color=white size="-1">Extension:</font></td>

            <td><font face="arial, helvetica, sans-serif">

               <input type="text" name="extension" value="<%=extension_value%>" size=20 maxsize=20></font>

            </td>

         </tr>

         <tr>

            <td><font face="arial, helvetica, sans-serif" color=white size="-1">Zip Code:</font></td>

            <td><font face="arial, helvetica, sans-serif">

               <input type="text" name="zipcode" value="<%=zipcode_value%>" size=20 maxsize=20></font>

            </td>

         </tr>

         <tr>

            <td><font face="arial, helvetica, sans-serif">

               <input type="hidden" name="WebUserId" value="<%=WebUserId%>" size=20 maxsize=50 ></font>

            </td>

         </tr>

         </TABLE>

         </center>

         </td>

      </tr>

   </TABLE>

   <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH="100%" >

   <tr>

      <td BGCOLOR="#666699">

      <TABLE>

         <tr>

         <td valign=top><input type="submit" name="tad" value=" TAD ">

         &nbsp;

         </td>

         <td valign=top><input type="submit" name="add" value=" ADD ">

         &nbsp;

         </td>

         <td valign=top><input type="submit" name="disp" value="DISPLAY">

         &nbsp;

         </td>

         <td valign=top><input type="submit" name="del" value="DELETE">

         &nbsp;

         </td>   

         <td valign=top><input type="submit" name="update" value="UPDATE">

         &nbsp;

         </td>

         </tr>

      </TABLE>

      </td>

   </tr>

   </TABLE>

   </td>

   </tr>

   </form>

</TABLE>

<BR><B>Message : "<%=message_value%>" </B></BR>

<!--#include file="Copyright.jsp" -->

</BODY>

</HTML>




Telco Sample



Refer to the iPlanet Application Server Enterprise Connector for CICS Administrator's Guide for information on how to activate the CICS Telco sample.


Previous     Contents     Index     DocHome     Next     
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.

Last Updated November 13, 2000