// Sample code file: FilesystemEnumeration.java

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

/*
   Copyright (c) 1997-1999 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. 
*/

package com.novell.sample.snapins.filesystem;

import java.io.*;
import java.util.*;

import com.novell.application.console.snapin.*;
import com.novell.application.console.snapin.scope.*;
import com.novell.application.console.snapin.context.*;

/**
  Example implementation of the ObjectEntryEnumeration interface, which gets
  the next ObjectEntry returned by the getChildren() method of the Namespace
  snap-in.
*/
class FilesystemEnumeration implements ObjectEntryEnumeration
{
   private ObjectEntry [] entries;
   private int index = 0;
   
   FilesystemEnumeration(String [] files, 
      ObjectEntry parent,
      FilesystemNamespace namespace)
   {
      this.index = 0;
      entries = new ObjectEntry[files.length];
      for(int i = 0; i < files.length; i++)
      {
         try
         {
            entries[i] = namespace.makeObjectEntry(files[i], parent);  
         }
         catch(ObjectNotFoundException e)
         {
            throw new NoSuchElementException();
         }
      }
      sort(entries, 0, entries.length - 1);
   }

  /**
    Returns the next ObjectEntry of the enumeration. 
   */
   public ObjectEntry next()
   {
      if(hasMoreElements())
      {
         return entries[index++];
      }
      throw new NoSuchElementException();
   }

  /**
    Returns the next child as an Object (must still be an ObjectEntry). 
   */
   public Object nextElement()
   {
      return next();
   }

  /**
    Returns a boolean determining if there are more children in the enumeration.
    The boolean is set to 'true' if there are more children in the enumeration,
    otherwise it is set to 'false'.  
   */
   public boolean hasMoreElements()
   {
      return index < entries.length;
   }

   /**
     The following code sorts the object entries.
    */
   static int compare(ObjectEntry entry1, ObjectEntry entry2)
   {
      boolean container1 = entry1.getObjectType().isContainer();
      boolean container2 = entry2.getObjectType().isContainer();
      if(container1 && !container2)
      {
         return -1;
      }
      if(!container1 && container2)
      {
         return 1;
      }
      String s1 = entry1.getName().toLowerCase();
      String s2 = entry2.getName().toLowerCase();
      return s1.compareTo(s2);
   }
  
   static void insertion(ObjectEntry [] entries, int lo, int hi)
   {
      ObjectEntry temp;
      int j;
      for(int i = hi - 1; i >= lo; i--)
      {
         temp = entries[i];
         for(j = i + 1; j <= hi && compare(temp, entries[j]) > 0; j++)
         {
            entries[j - 1] = entries[j];
         }
         entries[j - 1] = temp;
      }
   }
  
   static final int optsize = 25;

   static void sort(ObjectEntry [] entries, int lo, int hi)
   {
      while((hi - lo) > optsize)
      {
         int i = lo;
         int j = hi;
         ObjectEntry temp = entries[lo];
         while(i < j)
         {
            while(compare(entries[j], temp) > 0)
            {
               j--;
            }
            entries[i] = entries[j];
            while((i < j) && compare(entries[i], temp) <= 0)
            {
               i++;
            }
            entries[j] = entries[i];
         }
         entries[i] = temp;
         sort(entries, lo, i - 1);
         lo = i + 1;
      }
      if(hi > lo)
      {
         insertion(entries, lo, hi);
      }
   }
}