/***************************************************************************
 %name: Search.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.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Binding;
import javax.naming.NamingEnumeration;
import javax.naming.NameClassPair;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchResult;

import com.novell.utility.naming.Environment;
import com.novell.service.file.nw.DirectoryEntryInformation;

/**
 * Demonstrates the unique compare functionality of the various 
 * attribute values of the file system name space provider. An
 * example for DirectoryEntryInformation is the only attribute
 * value given in this example, however all file system attribute
 * values have similiar behavior.
 */

public class Search
{
   /**
    * Searches from the DirContext selected from the URL. The search
    * parameter is used as the JNDI search string. If the filter
    * parameter is not NULL, it's value is set in the 
    * DirectoryEntryInformation search object as a sub-compare filter.
    * The search and filter parameters should be given in RFC2254 format.
    * <p>
    *
    * @param url    The url to list.
    * @param search The search string to use at the JNDI level.
    * @param filter The compare string to use at the attribute
    *               value level.
    *
    * @see com.novell.service.file.nw.DirectoryEntryInformation
    */
   public static void doSearch(String url, String search, String filter)
   {
      Hashtable systemProps = new Hashtable();
      systemProps.put(
         Context.INITIAL_CONTEXT_FACTORY,
         Environment.FS_INITIAL_CONTEXT_FACTORY);
      systemProps.put(Context.PROVIDER_URL, url);

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

         System.out.println("\nSearhing at: " + url + " with search: " + search +
            " filter: " + filter + "\n");

         NamingEnumeration sEnum = null;
         if(filter != null)
         {
            // Do a search with subsitution object.
            Object[] dei = new Object[1];
            dei[0] = new DirectoryEntryInformation();
            ((DirectoryEntryInformation) dei[0]).setCompareString(filter);
            sEnum = context.search("", search, dei, null);
         }
         else   // Do a simple search for the name only.
            sEnum = context.search("", search, null);

         int count = 0;
         while (sEnum.hasMore())
         {
            SearchResult sr = (SearchResult)sEnum.next();
            System.out.println(sr.getName() + " matched the search\n");
            ++count;
         }
         System.out.println(count + " matches found");
      }
      catch (javax.naming.NamingException e)
      {
         System.out.println("\nException thrown: " + e);
         e.printStackTrace();
         System.exit(-1);
      }
   }


   /**
    * Provides the main entry point for the program.
    *
    * <p>Requires 2 command line parameters and one optional parameter.
    * The first is the URL for the starting DirContext node of the Search.
    * The second is the search string for the JNDI level search. The
    * third is the sub-compare filter that is set in the
    * DirectoryEntryInformation search object. The search and filter
    * parameters should be given in RFC2254 format </p>
    *
    * @param url    The name of a DirContext from the File system
    *               initial context. For example:
    *               "my_server/my_volume/my_dir"
    * @param search The search string to use at the JNDI level.
    * @param filter The compare string to use at the attribute
    *               value level.
    */
   public static void main(String args[])
   {
      // See if the user has given the URL and search string.
      if(args.length < 2)
         help();

      // See if the user has given the filter string.
      String filter = null;
      if(args.length > 2)
         filter = args[2];
      doSearch(args[0], args[1], filter);
      System.exit(0);
   }

   private static void help()
   {
      System.out.println(
         "\nTo use this example program enter the following:\n");
      System.out.println(
         "\tjava Search <url> <search> [filter]\n");
      System.out.println(
         "\t\turl = name of the File System DirContext to search on");
      System.out.println("\t\t       my_server/my_volume/my_dir\n");
      System.out.println(
         "\t\tsearch = search string for JNDI level");
      System.out.println("\t\t       \"(Entry Information=tfile.txt)\"  name search");
      System.out.println("\t\t       \"(Entry Information={0})\" replacement\n");
      System.out.println(
         "\t\tfilter = optional compare filter if using replacement object");
      System.out.println(
         "\t\t       (&(EntryName=tfile.txt)(SpaceAlloc<=1024))");
      System.out.println("");
      System.out.println(
      "The search and filter parameters should follow the RFC 2254 format\n\n" +
      "If the name search format is used for the search parameter\n" +
      "(first example), dont supply the filter parameter\n\n" +
      "If the replacement format is used for the search parameter\n" +
      "(second example), the filter parameter is used\n\n" +
      "See the javadoc for the various Attribute values to find\n" +
      "valid id's for use in both the search and filter.\n");
      System.exit(-1);
   }
}
