/* **************************************************************************

  $Archive: /njcl_v2rmi/src/com/novell/service/file/nw/DirectoryEntryInformation.java $
  $Revision: 1 $
  $Modtime: 1/10/01 12:47p $
 
  Copyright (c) 1998 Novell, Inc.  All Rights Reserved.

  THIS WORK IS  SUBJECT  TO  U.S.  AND  INTERNATIONAL  COPYRIGHT  LAWS  AND
  TREATIES.   NO  PART  OF  THIS  WORK MAY BE  USED,  PRACTICED,  PERFORMED
  COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,  ABRIDGED, CONDENSED,
  EXPANDED,  COLLECTED,  COMPILED,  LINKED,  RECAST, TRANSFORMED OR ADAPTED
  WITHOUT THE PRIOR WRITTEN CONSENT OF NOVELL, INC. ANY USE OR EXPLOITATION
  OF THIS WORK WITHOUT AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO
  CRIMINAL AND CIVIL LIABILITY.

****************************************************************************/

package com.novell.service.file.nw;

import com.novell.service.rfc1960.SearchStringComponent;
import com.novell.service.rfc1960.Rfc1960Parser;

/** 
 * Provides the attribute interface for Directory Entry Information.
 * A directory entry can be a file or a directory.
 *
 * <p>The jndi.ds.Attribute.getAttributeID() method returns 
 * "DirectoryEntryInformation" as the attribute ID for this interface.
 *
 * <p>This class results in a mutable object.  For versatility, code
 * block synchronization has been implemented in the various jndi search 
 * and modify methods of this classes implementation to provide for thread 
 * safe operation.
 * </p>
 * <p>If you have a multi-threaded application and a code segment of that
 * application uses the get methods of this class and there is a potential 
 * of another thread randomly using corresponding set methods of this class,
 * you should enclose the calls to the get methods in a synchronized code
 * block.
 * </p>
 * <p>If you have a multi-threaded application and a code segment of that
 * application uses set methods of this class, and there is a potential 
 * of another thread randomly using corresponding get methods, you should
 * enclose the calls to the set methods in a synchronized code block.
 * </p>
 * <p>This class contains the following directory entry information:
 * 
 * <ul>
 * <dt>*Archive date - The date the entry was last archived.
 * <dt>*Archive time - The time the entry was last archived.
 * <dt>*Archiver - The name of the object last archiving the entry.
 * <dt>*Attributes - A bit mask containing the entry's attributes.
 * <dt>*Creation date - The date the entry was created.
 * <dt>*Creation time - The time the entry was created.
 * <dt>*Creator - name of the object that created the entry.
 * <dt>Data Stream Size - The size of the data stream.
 * <dt>Directory entry number - The directory entry number.
 * <dt>DOS directory entry number - The DOS directory entry number.
 * <dt>Extended attribute data size - The data size of the entry's
 *                                    extended attribute.
 * <dt>Extended attribute key count - The key count of the entry's
 *                                    extended attribute.
 * <dt>Extended attribute key size - The size of the entry's
 *                                   extended attribute.
 * <dt>Entry name - The entry's name.
 * <dt>Flags - Data used internally.
 * <dt>*Inherited rights mask - The entry's inherited rights mask.
 * <dt>*Last access date - The date the entry was last accessed.
 * <dt>*Modifier - The name of the object that last modified the entry.
 * <dt>*Modify date - The date when the entry was last modified.
 * <dt>*Modify time - The time when entry was last modified.
 * <dt>Name length - The length of the entry's name.
 * <dt>Name space creator - The name space the entry was originally
 *                          created in.
 * <dt>Number of streams - The number of streams associated with
 *                         the entry.
 * <dt>Space allocated - The space allocated to the primary datastream.
 * <dt>Total stream size - The total size (number of 4K blocks) of streams
 *                         associated with the entry.
 * <dt>Volume number - The number of the volume that contains the entry.
 * </ul></p>
 * 
 * <p>When using the JNDI interface and doing a modify attribute operation on
 * a DirectoryEntryInformation value, the above values flagged with an
 * asterisk (*) are the only ones that will be modified. The user must set
 * all of these fields up to the desired values before making the modify call.
 * </p>
 */
public class DirectoryEntryInformation implements Cloneable, java.io.Serializable
{
/* **************************************************************************
   jndi naming interface defines
****************************************************************************/

   /**
    * Attribute ID of DirectoryEntryInformation.
    *
    * <p>(ATTRIBUTE_ID = "Entry Information")
    * </p>
    */
   public static final String ATTRIBUTE_ID = "Entry Information";

   /**
    * Schema Class Definition Name of DirectoryEntryInformation.
    *
    * <p>(SCHEMA_BINDING_NAME = ATTRIBUTE_ID + " Definition")
    * </p>
    */
   public static final String SCHEMA_BINDING_NAME =
         ATTRIBUTE_ID + " Definition";

   /**
    * Schema Syntax of DirectoryEntryInfomation.
    *
    * <p>(COMPARE_SYNTAX_STRING = 
    *       "(" +
    *       SearchStringComponent.EQUALS_STRING + "," +
    *       SearchStringComponent.PRESENT_STRING + "," +
    *       SearchStringComponent.SUBSTRING_STRING + 
    *       ")")
    * </p>
    */
   public static final String COMPARE_SYNTAX_STRING =
         new String(
               "(" +
               SearchStringComponent.EQUALS_STRING + "," +
               SearchStringComponent.PRESENT_STRING + "," +
               SearchStringComponent.SUBSTRING_STRING +
               ")");

/* **************************************************************************
   compareString field name defines
****************************************************************************/

   /**
    * Field specifier for searching on space allocation information.
    *
    * <p>(SPACEALLOC_FIELD = "SpaceAlloc")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String SPACEALLOC_FIELD = "SpaceAlloc";

   /**
    * Field specifier for searching on directory entry attributes.
    *
    * <p>(ATTRIBUTES_FIELD = "Attributes")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String ATTRIBUTES_FIELD = "Attributes";

   /**
    * Field specifier for searching on internal directory entry flags.
    *
    * <p>(FLAGS_FIELD = "Flags")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String FLAGS_FIELD = "Flags";

   /**
    * Field specifier for searching on the primary data stream size.
    *
    * <p>(DATASTREAMSIZE_FIELD = "DataStreamSize")
    * </p>
    * @see #setCompareString
    * @see #equals
    */

   public static final String DATASTREAMSIZE_FIELD = "DataStreamSize";

   /**
    * Field specifier for searching on the total size of all data streams.
    *
    * <p>This variable represents the number of 4K blocks that the given
    * file is occupying.
    *
    * <p>(TOTALSTREAMSIZE_FIELD = "TotalStreamSize")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String TOTALSTREAMSIZE_FIELD = "TotalStreamSize";

   /**
    * Field specifier for searching on the number of data streams associated
    * with this directory entry.
    *
    * <p>(NUMBEROFSTREAMS_FIELD = "NumberOfStreams")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String NUMBEROFSTREAMS_FIELD = "NumberOfStreams";

   /**
    * Field specifier for searching on creation time.
    *
    * <p>(CREATIONTIME_FIELD = "CreationTime")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String CREATIONTIME_FIELD = "CreationTime";

   /**
    * Field specifier for searching on creation date.
    *
    * <p>(CREATIONDATE_FIELD = "CreationDate")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String CREATIONDATE_FIELD = "CreationDate";

   /**
    * Field specifier for searching on creator. When searching on the
    * creator, specify the object name in a string form.
    *
    * <p>(CREATOR_FIELD = "Creator")
    * </p>
    *
    * @see #setCompareString
    * @see #equals
    */
   public static final String CREATOR_FIELD = "Creator";

   /**
    * Field specifier for searching on last modification date.
    *
    * <p>(MODIFYTIME_FIELD = "ModifyTime")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String MODIFYTIME_FIELD = "ModifyTime";

   /**
    * Field specifier for searching on last modification time.
    *
    * <p>(MODIFYDATE_FIELD = "ModifyDate")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String MODIFYDATE_FIELD = "ModifyDate";

   /**
    * Field specifier for searching on modifier. When searching on the
    * modifier, specify the object name in a string form.
    *
    * <p>(MODIFIER_FIELD = "Modifier")
    * </p>
    *
    * @see #setCompareString
    * @see #equals
    */
   public static final String MODIFIER_FIELD = "Modifier";

   /**
    * Field specifier for searching on last access date.
    *
    * <p>(LASTACCESSDATE_FIELD = "LastAccessDate")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String LASTACCESSDATE_FIELD = "LastAccessDate";

   /**
    * Field specifier for searching on last archival time.
    *
    * <p>(ARCHIVETIME_FIELD = "ArchiveTime")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String ARCHIVETIME_FIELD = "ArchiveTime";

   /**
    * Field specifier for searching on last archival date.
    *
    * <p>(ARCHIVEDATE_FIELD = "ArchiveDate")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String ARCHIVEDATE_FIELD = "ArchiveDate";

   /**
    * Field specifier for searching on archiver. When searching on the
    * archiver, specify the object name in a string form.
    *
    * <p>(ARCHIVER_FIELD = "Archiver")
    * </p>
    *
    * @see #setCompareString
    * @see #equals
    */
   public static final String ARCHIVER_FIELD = "Archiver";

   /**
    * Field specifier for searching on the inherited rights mask.
    *
    * <p>(INHERITEDRIGHTSMASK_FIELD = "InheritedRightsMask")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String INHERITEDRIGHTSMASK_FIELD = 
         "InheritedRightsMask";

   /**
    * Field specifier for searching on the name space directory entry number.
    *
    * <p>(DIRENTNUM_FIELD = "DirEntNum")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String DIRENTNUM_FIELD = "DirEntNum";

   /**
    * Field specifier for searching on the DOS directory entry number.
    *
    * <p>(DOSDIRNUM_FIELD = "DosDirNum")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String DOSDIRNUM_FIELD = "DosDirNum";

   /**
    * Field specifier for searching on the volume number where the directory
    * entry resides.
    *
    * <p>(VOLNUMBER_FIELD = "VolNumber")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String VOLNUMBER_FIELD = "VolNumber";

   /**
    * Field specifier for searching on total EA data size.
    *
    * <p>(EADATASIZE_FIELD = "EADataSize")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String EADATASIZE_FIELD = "EADataSize";

   /**
    * Field specifier for searching on number of EAs associated with this
    * directory entry.
    *
    * <p>(EAKEYCOUNT_FIELD = "EAKeyCount")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String EAKEYCOUNT_FIELD = "EAKeyCount";

   /**
    * Field specifier for searching on size of the EA key strings.
    *
    * <p>(EAKEYSIZE_FIELD = "EAKeySize")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String EAKEYSIZE_FIELD = "EAKeySize";

   /**
    * Field specifier for searching on the owning name space.
    *
    * <p>(NSCREATOR_FIELD = "NSCreator")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String NSCREATOR_FIELD = "NSCreator";

   /**
    * Field specifier for searching on length of the name space name.
    *
    * <p>(NAMELENGTH_FIELD = "NameLength")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String NAMELENGTH_FIELD = "NameLength";

   /**
    * Field specifier for searching on name space name.
    *
    * <p>(ENTRYNAME_FIELD = "EntryName")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String ENTRYNAME_FIELD = "EntryName";

   /**
    * Field specifier for searching on modify search attributes. 
    *
    * <p>(MODIFYSEARCHATTRIBUTES_FIELD = "ModifySearchAttributes")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String MODIFYSEARCHATTRIBUTES_FIELD = 
      "ModifySearchAttributes";

   /**
    * Field specifier for searching on modify mask. 
    *
    * <p>(MODIFYMASK_FIELD = "ModifyMask")
    * </p>
    * @see #setCompareString
    * @see #equals
    */
   public static final String MODIFYMASK_FIELD = 
      "ModifyMask";

/* **************************************************************************
   InheritedRightsMask mask bits
****************************************************************************/

   /**
    * Netware rights: Cannot read or write.
    *
    * <p>(TA_NONE = 0x0000)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_NONE = 0x0000;

   /**
    * Netware rights: Can read.
    *
    * <p>(TA_READ = 0x0001)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_READ = 0x0001;

   /**
    * Netware rights: Can write.
    *
    * <p>(TA_WRITE = 0x0002)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_WRITE = 0x0002;

   /**
    * Netware rights: Can open existing file (obsolete).
    *
    * <p>(TA_WRITE = 0x0004)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_OLD_OPEN = 0x0004;

   /**
    * Netware rights: Can create files.
    *
    * <p>(TA_CREATE = 0x0008)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_CREATE = 0x0008;

   /**
    * Netware rights: Can delete files.
    *
    * <p>(TA_DELETE = 0x0010)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_DELETE = 0x0010;

   /**
    * Netware rights: Can create and delete subdirectories, and can
    * grant and revoke trustee rights.
    *
    * <p>(TA_OWNERSHIP = 0x0020)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_OWNERSHIP = 0x0020;

   /**
    * Netware rights: Can search the directory.
    *
    * <p>(TA_SEARCH = 0x0040)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_SEARCH = 0x0040;

   /**
    * Netware rights: Can modify the file attributes.
    *
    * <p>(TA_MODIFY = 0x0080)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_MODIFY = 0x0080;

   /**
    * Netware rights: User has supervisor rights.
    *
    * <p>(TA_SUPERVISOR = 0x0100)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_SUPERVISOR = 0x0100;

   /**
    * Netware rights: Specifies all rights to the directory.
    *
    * <p>(TA_ALL = 0x00FB)
    * </p>
    *
    * @see #getInheritedRightsMask
    * @see #setInheritedRightsMask
    */
   public static final int TA_ALL = 0x01FF; // used to be 0x1fb


/* **************************************************************************
   read attributes mask bits
****************************************************************************/

   /**
    * Attribute: No attributes set.
    *
    * <p>(A_NORMAL = 0x00000000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_NORMAL = 0x00000000;

   /**
    * Attribute: The entry cannot be written, deleted or renamed.
    *
    * <p>(A_READ_ONLY = 0x00000001)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_READ_ONLY = 0x00000001;

   /**
    * Attribute: The entry doesn't appear in a normal directory listing.
    *
    * <p>(A_HIDDEN = 0x00000002)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_HIDDEN = 0x00000002;

   /**
    * Attribute: The entry is used by the system and is hidden.
    *
    * <p>(A_SYSTEM = 0x00000004)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_SYSTEM = 0x00000004;

   /**
    * Attribute: The entry can be loaded for execution only once.
    *
    * <p>(A_EXECUTE_ONLY = 0x00000008)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_EXECUTE_ONLY = 0x00000008;

   /**
    * Attribute: The entry is a directory, not a file.
    *
    * <p>(A_DIRECTORY = 0x00000010)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_DIRECTORY = 0x00000010;

   /**
    * Attribute: The entry has been changed since last archived.
    *
    * <p>(A_NEEDS_ARCHIVED = 0x00000020)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_NEEDS_ARCHIVED = 0x00000020;

   /**
    * Attribute: The entry can be opened by multiple clients.
    *
    * <p>(A_SHAREABLE = 0x00000080)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_SHAREABLE = 0x00000080;

   /**
    * Attribute: A transaction on the entry is being tracked.
    *
    * <p>(A_TRANSACTIONAL = 0x00001000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_TRANSACTIONAL = 0x00001000;

   /**
    * Attribute: Not in use; provided for compatibility only.
    *
    * <p>(A_INDEXED = 0x00002000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_INDEXED = 0x00002000;

   /**
    * Attribute: Not in use.
    *
    * <p>(A_READ_AUDIT = 0x00004000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_READ_AUDIT = 0x00004000;

   /**
    * Attribute: Not in use.
    *
    * <p>(A_WRITE_AUDIT = 0x00008000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_WRITE_AUDIT = 0x00008000;

   /**
    * Attribute: The entry will be purged when deleted.
    *
    * <p>(A_IMMEDIATE_PURGE = 0x00010000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_IMMEDIATE_PURGE = 0x00010000;

   /**
    * Attribute: The entry cannot be renamed.
    *
    * <p>(A_RENAME_INHIBIT = 0x00020000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_RENAME_INHIBIT = 0x00020000;

   /**
    * Attribute: The entry cannot be deleted.
    *
    * <p>(A_DELETE_INHIBIT = 0x00040000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_DELETE_INHIBIT = 0x00040000;

   /**
    * Attribute: The entry cannot be copied.
    *
    * <p>(A_COPY_INHIBIT = 0x00080000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_COPY_INHIBIT = 0x00080000;

   /**
    * Attribute: The entry has been migrated.
    *
    * <p>(A_FILE_MIGRATED = 0x00400000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_FILE_MIGRATED = 0x00400000;

   /**
    * Attribute: The entry should not be migrated.
    *
    * <p>(A_DONT_MIGRATE = 0x00800000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_DONT_MIGRATE = 0x00800000;

   /**
    * Attribute: The entry should be compressed when migrated.
    *
    * <p>(A_IMMEDIATE_COMPRESS = 0x02000000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_IMMEDIATE_COMPRESS = 0x02000000;

   /**
    * Attribute: The entry is compressed.
    *
    * <p>(A_FILE_COMPRESSED = 0x04000000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_FILE_COMPRESSED = 0x04000000;

   /**
    * Attribute: The entry should not be compressed.
    *
    * <p>(A_DONT_COMPRESS = 0x08000000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_DONT_COMPRESS = 0x08000000;

   /**
    * Attribute: The entry cannot be compressed.
    *
    * <p>(A_CANT_COMPRESS = 0x20000000)
    * </p>
    *
    * @see #getAttributes
    * @see #setAttributes
    */
   public static final int A_CANT_COMPRESS = 0x20000000;

/* **************************************************************************
   NSCreator values
****************************************************************************/


   /**
    * NSCreator: DOS name space.
    *
    * <p>(NW_NS_DOS = 0x00)
    * </p>
    *
    * @see #getNSCreator
    * @see #setNSCreator
    */
   public static final int NW_NS_DOS = 0x00;

   /**
    * NSCreator: MAC name space.
    *
    * <p>(NW_NS_MAC = 0x01)
    * </p>
    *
    * @see #getNSCreator
    * @see #setNSCreator
    */
   public static final int NW_NS_MAC = 0x01;

   /**
    * NSCreator: NFS name space.
    *
    * <p>(NW_NS_NFS = 0x02)
    * </p>
    *
    * @see #getNSCreator
    * @see #setNSCreator
    */
   public static final int NW_NS_NFS = 0x02;

   /**
    * NSCreator: FTAM name space.
    *
    * <p>(NW_NS_FTAM = 0x03)
    * </p>
    *
    * @see #getNSCreator
    * @see #setNSCreator
    */
   public static final int NW_NS_FTAM = 0x03;

   /**
    * NSCreator: OS2 name space (LONG).
    *
    * <p>(NW_NS_OS2 = 0x04)
    * </p>
    *
    * @see #getNSCreator
    * @see #setNSCreator
    */
   public static final int NW_NS_OS2 = 0x04;


/* **************************************************************************
   Bit mask used for modify search attributes
****************************************************************************/

   /**
    * modifySearchAttributes: Search for hidden entries for modification.
    *
    * <p>(SA_HIDDEN = 0x0002)
    * </p>
    *
    * @see #getModifySearchAttributes
    * @see #setModifySearchAttributes
    */
   public static final int SA_HIDDEN = 0x0002;

   /**
    * modifySearchAttributes: Search for system entries for modification.
    *
    * <p>(SA_SYSTEM = 0x0004)
    * </p>
    *
    * @see #getModifySearchAttributes
    * @see #setModifySearchAttributes
    */
   public static final int SA_SYSTEM = 0x0004;

   /**
    * modifySearchAttributes: Search for directories only for modification.
    *
    * <p>(SA_SUBDIR_ONLY = 0x0010)
    * </p>
    *
    * @see #getModifySearchAttributes
    * @see #setModifySearchAttributes
    */
   public static final int SA_SUBDIR_ONLY = 0x0010;

   /**
    * modifySearchAttributes: Search for files and directories for
    * modification.
    *
    * <p>(SA_SUBDIR_FILES = 0x8000)
    * </p>
    *
    * @see #getModifySearchAttributes
    * @see #setModifySearchAttributes
    */
   public static final int SA_SUBDIR_FILES = 0x8000;

/* **************************************************************************
   Bit mask used for modifyMask
****************************************************************************/

   /**
    * Modify Mask: Attributes.
    *
    * <p>(DM_ATTRIBUTES = 0x0002)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_ATTRIBUTES = 0x0002;

   /**
    * Modify Mask: Creation Date.
    *
    * <p>(DM_CREATE_DATE = 0x0004)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_CREATE_DATE = 0x0004;

   /**
    * Modify Mask: Creation Time.
    *
    * <p>(DM_CREATE_TIME = 0x0008)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_CREATE_TIME = 0x0008;

   /**
    * Modify Mask: Creator.
    *
    * <p>(DM_CREATOR_ID = 0x0010)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_CREATOR = 0x0010;

   /**
    * Modify Mask: Archive Date.
    *
    * <p>(DM_ARCHIVE_DATE = 0x0020)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_ARCHIVE_DATE = 0x0020;

   /**
    * Modify Mask: Archive Time.
    *
    * <p>(DM_ARCHIVE_TIME = 0x0040)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_ARCHIVE_TIME = 0x0040;

   /**
    * Modify Mask: Archiver.
    *
    * <p>(DM_ARCHIVER_ID = 0x0080)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_ARCHIVER = 0x0080;

   /**
    * Modify Mask: Modify Date.
    *
    * <p>(DM_MODIFY_DATE = 0x0100)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_MODIFY_DATE = 0x0100;

   /**
    * Modify Mask: Modify Time.
    *
    * <p>(DM_MODIFY_TIME = 0x0200)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_MODIFY_TIME = 0x0200;

   /**
    * Modify Mask: Modifier.
    *
    * <p>(DM_MODIFIER_ID = 0x0400)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_MODIFIER = 0x0400;

   /**
    * Modify Mask: Last Access Date.
    *
    * <p>(DM_LAST_ACCESS_DATE = 0x0800)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_LAST_ACCESS_DATE = 0x0800;

   /**
    * Modify Mask: Inherited Rights Mask.
    *
    * <p>(DM_INHERITED_RIGHTS_MASK = 0x1000)
    * </p>
    *
    * @see #setModifyMask
    * @see #getModifyMask
    */
   public static final int DM_INHERITED_RIGHTS_MASK = 0x1000;

/* **************************************************************************
   DirectoryEntryInformation state data members
****************************************************************************/

   /* attribute state */

   private int spaceAlloc;             /*IM_SPACE_ALLOWED 0x0002L */
   private int attributes;             /*IM_ATTRIBUTES 0x0004L*/
   private int flags;
   private int dataStreamSize;         /*IM_SIZE 0x0008L */
   private int totalStreamSize;        /*IM_TOTAL_SIZE 0x0010L */
   private int numberOfStreams;
   private int creationTime;           /*IM_CREATION 0x0100L */
   private int creationDate;
   private String creator;
   private int modifyTime;             /*IM_MODIFY 0x0080L */
   private int modifyDate;
   private String modifier;
   private int lastAccessDate;
   private int archiveTime;            /*IM_ARCHIVE 0x0040L */
   private int archiveDate;
   private String archiver;
   private int inheritedRightsMask;    /*IM_RIGHTS 0x0800L*/
   private int dirEntNum;              /*IM_DIRECTORY 0x0400L*/
   private int DosDirNum;
   private int volNumber;
   private int EADataSize;             /*IM_EA 0x0020L */
   private int EAKeyCount;
   private int EAKeySize;
   private int NSCreator;              /*IM_OWNING_NAMESPAC 0x0200L */
   private int nameLength;             /*IM_ENTRY_NAME 0x0001L */
   private String entryName;     // [256];

   private int modifySearchAttributes = 
                  SA_HIDDEN |
                  SA_SYSTEM |
                  SA_SUBDIR_FILES;  // default to modify anything

   // only used by the modify interface
   private int modifyMask = 0;


   // only used by the native
  /**
   * @internal
   */
  /**
   * @internal
   */
   protected int creatorID;
  /**
   * @internal
   */
   protected int modifierID;
  /**
   * @internal
   */
   protected int archiverID;

   private String compareString;
   private Rfc1960Parser ssParser = null;
   private boolean firstParser = true;

/* **************************************************************************
   Constructors
****************************************************************************/

   /**
    * Constructs a DirectoryEntryInformation object. All fields are zero
    * or NULL.
    */
   public DirectoryEntryInformation()
   {
   }
       
   /**
    * Constructs a DirectoryEntryInformation object that is ready to send
    * into a modify operation.
    * 
    * <p>This constructor is intended for the user application layer. The
    * created DirectoryEntryInformation object is targeted for use in an
    * attribute modify operation. The parameters reflect all the fields
    * that can be modified. All other fields are ignored by the modify
    * operation.
    *
    * <p>The modifyMask is used to specify which of these fields are valid 
    * and should be modified. The following constants are available for
    * this support.
    *
    * <ul>
    * <li>DM_ATTRIBUTES
    * <li>DM_CREATE_DATE
    * <li>DM_CREATE_TIME
    * <li>DM_CREATOR
    * <li>DM_ARCHIVE_DATE
    * <li>DM_ARCHIVE_TIME
    * <li>DM_ARCHIVER
    * <li>DM_MODIFY_DATE
    * <li>DM_MODIFY_TIME
    * <li>DM_MODIFIER
    * <li>DM_LAST_ACCESS_DATE
    * <li>DM_INHERITED_RIGHTS_MASK
    * </ul>
    * </p>
    *
    * @param attributes     Data member attributes value.
    * @param createDate     Data member creation date value.
    * @param createTime     Data member creation time value.
    * @param creator        Data member creator value.
    * @param modifyDate     Data member modify date value.
    * @param modifyTime     Data member modify time value.
    * @param modifier       Data member modifier value.
    * @param archiveDate    Data member archive date value.
    * @param archiveTime    Data member archive time value.
    * @param archiver       Data member archiver value.
    * @param lastAccessDate Data member last access value.
    * @param grantRights    Data member grant rights value.
    * @param revokeRights   Data member revoke rights value.
    * @param maximumSpace   Data member maximum space value.
    * @param modifySearchAttributes Data member modify search attributes value.
    *
    * @see #DM_ATTRIBUTES
    * @see #DM_CREATE_DATE
    * @see #DM_CREATE_TIME
    * @see #DM_CREATOR
    * @see #DM_ARCHIVE_DATE
    * @see #DM_ARCHIVE_TIME
    * @see #DM_ARCHIVER
    * @see #DM_MODIFY_DATE
    * @see #DM_MODIFY_TIME
    * @see #DM_MODIFIER
    * @see #DM_LAST_ACCESS_DATE
    * @see #DM_INHERITED_RIGHTS_MASK
    * @see #setModifyMask
    * @see #getModifyMask
    */

   public DirectoryEntryInformation(
      int attributes,
      int creationDate,
      int creationTime,
      String creator,
      int modifyDate,
      int modifyTime,
      String modifier,
      int archiveDate,
      int archiveTime,
      String archiver,
      int lastAccessDate,
      int grantRights,
      int revokeRights,
      int spaceAlloc,
      int modifySearchAttributes,
      int modifyMask)
   {
      this.attributes = attributes;
      this.creationDate = creationDate;
      this.creationTime = creationTime;
      this.creator = creator;
      this.modifyDate = modifyDate;
      this.modifyTime = modifyTime;
      this.modifier = modifier;
      this.archiveDate = archiveDate;
      this.archiveTime = archiveTime;
      this.archiver = archiver;
      this.lastAccessDate = lastAccessDate;
      this.inheritedRightsMask = inheritedRightsMask;
      this.spaceAlloc = spaceAlloc;
      inheritedRightsMask = revokeRights << 16;
      inheritedRightsMask |= (grantRights & 0x0000ffff);
      this.modifySearchAttributes = modifySearchAttributes;
      this.modifyMask = modifyMask;
   }

   /**
    * Constructs a DirectoryEntryInformation object specifying all
    * values that are needed to set the full state.
    *
    * @param spaceAlloc      Data member: space alloc value.
    * @param attributes      Data member: attributes value.
    * @param flags           Data member: flags value.
    * @param dataStreamSize  Data member: data stream size value.
    * @param totalStreamSize Data member: total stream size value.
    * @param numberOfStreams Data member: number of streams value.
    * @param creationTime    Data member: creation time value.
    * @param creationDate    Data member: creation date value.
    * @param creator         Data member: creator value.
    * @param modifyTime      Data member: modify time value.
    * @param modifyDate      Data member: modify date value.
    * @param modifier        Data member: modifier value.
    * @param lastAccessDate  Data member: last access date value.
    * @param archiveTime     Data member: archive time value.
    * @param archiveDate     Data member: archive date value.
    * @param archiver        Data member: archiver value.
    * @param inheritedRightsMask Data member: inherited rights mask value.
    * @param dirEntNum       Data member: dir ent num value.
    * @param DosDirNum       Data member: DOS directory number value.
    * @param volNumber       Data member: volume number value.
    * @param EADataSize      Data member: EA data size value.
    * @param EAKeyCount      Data member: EA key count value.
    * @param EAKeySize       Data member: EA key size value.
    * @param NSCreator       Data member: NS creator value.
    * @param nameLength      Data member: name length value.
    * @param entryName       Data member: entry name value.
    * @param modifySearchAttributes Data member: modify search attributes value.
     */

   public DirectoryEntryInformation(
         int spaceAlloc,
         int attributes,
         int flags,
         int dataStreamSize,
         int totalStreamSize,
         int numberOfStreams,
         int creationTime,
         int creationDate,
         String creator,
         int modifyTime,
         int modifyDate,
         String modifier,
         int lastAccessDate,
         int archiveTime,
         int archiveDate,
         String archiver,
         int inheritedRightsMask,
         int dirEntNum,
         int DosDirNum,
         int volNumber,
         int EADataSize,
         int EAKeyCount,
         int EAKeySize,
         int NSCreator,
         int nameLength,
         String entryName,
         int modifySearchAttributes)
   {
      this.spaceAlloc = spaceAlloc;
      this.attributes = attributes;
      this.flags = flags;
      this.dataStreamSize = dataStreamSize;
      this.totalStreamSize = totalStreamSize;
      this.numberOfStreams = numberOfStreams;
      this.creationTime = creationTime;
      this.creationDate = creationDate;
      this.creator = creator;
      this.modifyTime = modifyTime;
      this.modifyDate = modifyDate;
      this.modifier = modifier;
      this.lastAccessDate = lastAccessDate;
      this.archiveTime = archiveTime;
      this.archiveDate = archiveDate;
      this.archiver = archiver;
      this.inheritedRightsMask = inheritedRightsMask;
      this.dirEntNum = dirEntNum;
      this.DosDirNum = DosDirNum;
      this.volNumber = volNumber;
      this.EADataSize = EADataSize;
      this.EAKeyCount = EAKeyCount;
      this.EAKeySize = EAKeySize;
      this.NSCreator = NSCreator;
      this.nameLength = nameLength;
      this.entryName = entryName;
      this.modifySearchAttributes = modifySearchAttributes;
      modifyMask = 0;
   }

/* **************************************************************************
   Public Accessor methods
****************************************************************************/

   /**
    * Returns the SpaceAlloc field.
    *
    * @return The SpaceAlloc for this directory entry.
    */
   public int getSpaceAlloc()
   {
      return(spaceAlloc);
   }

   /**
    * Sets the SpaceAlloc field.
    *
    * @param value The SpaceAlloc for this directory entry.
    */
   public void setSpaceAlloc(int value)
   {
      spaceAlloc = value;
   }

   /**
    * Returns the directory entry attributes.
    *
    * @return The attributes for this directory entry.
    *
    * @see #A_NORMAL
    */
   public int getAttributes()
   {
      return(attributes);

   }

   /**
    * Sets the directory entry attributes.
    *
    * @param value The attributes for this directory entry.
    *
    * @see #A_NORMAL
    */
   public void setAttributes(int value)
   {
      attributes = value;
   }

   /**
    * Returns the Flags field.
    *
    * @return The Flags for this directory entry.
    */
   public int getFlags()
   {
      return(flags);
   }

   /**
    * Sets the Flags field.
    *
    * @param value The Flags for this directory entry.
    */
   public void setFlags(int value)
   {
      flags = value;
   }

   /**
    * Returns the DataStreamSize field.
    *
    * @return The DataStreamSize for this directory entry.
    */
   public int getDataStreamSize()
   {
      return(dataStreamSize);
   }

   /**
    * Sets the DataStreamSize field.
    *
    * @param value The DataStreamSize for this directory entry.
    */
   public void setDataStreamSize(int value)
   {
      dataStreamSize = value;
   }

   /**
    * Returns the TotalStreamSize field.
    *
    * <p>The TotalStreamSize is the number of 4K blocks that the
    * given file occupies.
    *
    * @return The TotalStreamSize for this directory entry.
    */
   public int getTotalStreamSize()
   {
      return(totalStreamSize);
   }

   /**
    * Sets the TotalStreamSize field.
    *
    * @param value The TotalStreamSize for this directory entry, which
    *              is the number of 4K blocks that the directory entry
    *              occupies.
    */
   public void setTotalStreamSize(int value)
   {
      totalStreamSize = value;
   }

   /**
    * Returns the NumberOfStreams field.
    *
    * @return The NumberOfStreams for this directory entry.
    */
   public int getNumberOfStreams()
   {
      return(numberOfStreams);
   }

   /**
    * Sets the NumberOfStreams field.
    *
    * @param value The NumberOfStreams for this directory entry.
    */
   public void setNumberOfStreams(int value)
   {
      numberOfStreams = value;
   }

   /**
    * Returns the CreationTime field.
    *
    * @return The CreationTime for this directory entry.
    *
    * @see #setCreationTime(int)
    */
   public int getCreationTime()
   {
      return(creationTime);
   }

   /**
    * Sets the CreationTime field.
    *
    * @param value The CreationTime for this directory entry in
    *              the order of seconds (5 bits), minutes (6 bits)
    *              and hours (5 bits).
    */
   public void setCreationTime(int value)
   {
      creationTime = value;
   }

   /**
    * Returns the CreationDate field.
    *
    * @return The CreationDate for this directory entry.
    *
    * @see #setCreationDate(int)
    */
   public int getCreationDate()
   {
      return(creationDate);
   }

   /**
    * Sets the CreationDate field.
    *
    * <p>To use the month value as 0-11 java base you must
    * subtract 1. Also, be aware that Novell starts at 1980,
    * thus you need to add the year to 1980.
    *
    * @param value The CreationDate for this directory entry in
    *              the order of dsy (5 bits), month (4 bits)
    *              and year (7 bits).
    */
   public void setCreationDate(int value)
   {
      creationDate = value;
   }

   /**
    * Returns the Creator field. A reference to this object's Creator field
    * is returned. If you modify the state of the returned object, it will
    * be reflected in this object.
    *
    * @return The Creator for this directory entry.
    */

   public String getCreator()
   {
      return(creator);
   }

   /**
    * Sets the Creator field of the Attribute. The actual parameter
    * reference will be stored by this object (it will  not be cloned).
    * Later modifications to to this references state will be reflected
    * in this object.
    *
    * @param value The Creator for this directory entry.
    */
   public void setCreator(String value)
   {
      creator = value;
   }

   /**
    * Returns the ModifyTime field.
    *
    * @return The ModifyTime for this directory entry.
    */
   public int getModifyTime()
   {
      return(modifyTime);
   }

   /**
    * Sets the ModifyTime field.
    *
    * @param value The ModifyTime for this directory entry.
    */
   public void setModifyTime(int value)
   {
      modifyTime = value;
   }

   /**
    * Returns the ModifyDate field.
    *
    * @return The ModifyDate for this directory entry.
    */
   public int getModifyDate()
   {
      return(modifyDate);
   }

   /**
    * Sets the ModifyDate field.
    *
    * @param value The ModifyDate for this directory entry.
    */
   public void setModifyDate(int value)
   {
      modifyDate = value;
   }

   /**
    * Returns a reference to this object's Modifier field. If you modify
    * the state of the returned object, it will be reflected in this
    * object.
    *
    * @return The Modifier for this directory entry.
    */
   public String getModifier()
   {
      return(modifier);
   }

   /**
    * Sets the Modifier field of the Attribute. The actual parameter
    * reference will be stored by this object (it will not be cloned).
    * Later modifications to this references state will be reflected
    * in this object.
    *
    * @param value The Modifier for this directory entry.
    */
   public void setModifier(String value)
   {
      modifier = value;
   }

   /**
    * Returns the LastAccessDate field.
    *
    * @return The LastAccessDate for this directory entry.
    */
   public int getLastAccessDate()
   {
      return(lastAccessDate);
   }

   /**
    * Sets the LastAccessDate field.
    *
    * @param value The LastAccessDate for this directory entry.
    */
   public void setLastAccessDate(int value)
   {
      lastAccessDate = value;
   }

   /**
    * Returns the ArchiveTime field.
    *
    * @return The ArchiveTime for this directory entry.
    */
   public int getArchiveTime()
   {
      return(archiveTime);
   }

   /**
    * Sets the ArchiveTime field.
    *
    * @param value The ArchiveTime for this directory entry.
    */
   public void setArchiveTime(int value)
   {
      archiveTime = value;
   }

   /**
    * Returns the ArchiveDate field.
    *
    * @return The ArchiveDate for this directory entry.
    */
   public int getArchiveDate()
   {
      return(archiveDate);
   }

   /**
    * Sets the ArchiveDate field.
    *
    * @param value The ArchiveDate for this directory entry.
    */
   public void setArchiveDate(int value)
   {
      archiveDate = value;
   }

   /**
    * Returns a reference to this object's Archiver field. If you modify
    * the state of the returned object, it will be reflected in this
    * object.
    *
    * @return The Archiver for this directory entry.
    */
   public String getArchiver()
   {
      return(archiver);
   }

   /**
    * Sets the Archiver field of the Attribute. The actual parameter
    * reference will be stored by this object (it will not be cloned).
    * Later modifications to this reference state will be reflected
    * in this object.
    *
    * @param value The Archiver for this directory entry.
    */
   public void setArchiver(String value)
   {
      archiver = value;
   }

   /**
    * Returns the inheritedRightsMask field.
    *
    * @return The inheritedRightsMask for this directory entry.
    *
    * @see #TA_NONE
    */
   public int getInheritedRightsMask()
   {
      // only return the grant rights portion
      return(inheritedRightsMask & TA_ALL);
   }

   /**
    * Sets the inheritedRightsMask field.
    *
    * @param value The inheritedRightsMask for this directory entry.
    *
    * @see #TA_NONE
    */
   public void setInheritedRightsMask(int value)
   {
      // revoke everything, then grant back only what the user wants

      value &= TA_ALL; // accept valid grant mask
      inheritedRightsMask = value | (0x1FF << 16);
   }

   /**
    * Returns the DirEntNum field.
    *
    * @return The DirEntNum for this directory entry.
    */
   public int getDirEntNum()
   {
      return(dirEntNum);
   }

   /**
    * Sets the DirEntNum field.
    *
    * @param value The DirEntNum for this directory entry.
    */
   public void setDirEntNum(int value)
   {
      dirEntNum = value;
   }

   /**
    * Returns the DosDirNum field.
    *
    * @return The DosDirNum for this directory entry.
    */
   public int getDosDirNum()
   {
      return(DosDirNum);
   }

   /**
    * Sets the DosDirNum field.
    *
    * @param value The DosDirNum for this directory entry.
    */
   public void setDosDirNum(int value)
   {
      DosDirNum = value;
   }

   /**
    * Returns the VolNumber field.
    *
    * @return The VolNumber for this directory entry.
    */
   public int getVolNumber()
   {
      return(volNumber);
   }

   /**
    * Sets the VolNumber field.
    *
    * @param value The VolNumber for this directory entry.
    */
   public void setVolNumber(int value)
   {
      volNumber = value;
   }

   /**
    * Returns the EADataSize field.
    *
    * @return The EADataSize for this directory entry.
    */
   public int getEADataSize()
   {
      return(EADataSize);
   }

   /**
    * Sets the EADataSize field.
    *
    * @param value The EADataSize for this directory entry.
    */
   public void setEADataSize(int value)
   {
      EADataSize = value;
   }

   /**
    * Returns the EAKeyCount field.
    *
    * @return The EAKeyCount for this directory entry.
    */
   public int getEAKeyCount()
   {
      return(EAKeyCount);
   }

   /**
    * Sets the EAKeyCount field.
    *
    * @param value The EAKeyCount for this directory entry.
    */
   public void setEAKeyCount(int value)
   {
      EAKeyCount = value;
   }

   /**
    * Returns the EAKeySize field.
    *
    * @return The EAKeySize for this directory entry.
    */
   public int getEAKeySize()
   {
      return(EAKeySize);
   }

   /**
    * Sets the EAKeySize field.
    *
    * @param value The EAKeySize for this directory entry.
    */
   public void setEAKeySize(int value)
   {
      EAKeySize = value;
   }

   /**
    * Returns the NSCreator field.
    *
    * @return The NSCreator for this directory entry.
    *
    * @see #NW_NS_DOS
    */
   public int getNSCreator()
   {
      return(NSCreator);
   }

   /**
    * Sets the NSCreator field.
    *
    * @param value The NSCreator for this directory entry.
    *
    * @see #NW_NS_DOS
    */
   public void setNSCreator(int value)
   {
      NSCreator = value;
   }


   /**
    * Returns the NameLength field.
    *
    * @return The NameLength for this directory entry.
    */
   public int getNameLength()
   {
      return(nameLength);
   }

   /**
    * Sets the NameLength field.
    *
    * @param value The NameLength for this directory entry.
    */
   public void setNameLength(int value)
   {
      nameLength = value;
   }

   /**
    * Returns the EntryName field.
    *
    * @return The EntryName for this directory entry.
    */
   public String getEntryName()
   {
      return(entryName);
   }

   /**
    * Sets the EntryName field.
    *
    * @param value The EntryName for this directory entry.
    */
   public void setEntryName(String value)
   {
      entryName = value;
      nameLength = entryName.length();
   }

   /**
    * Returns the modifySearchAttributes field of the Attribute. This 
    * value is a mask that determines what the search will be while modifying
    * this attribute.
    *
    * @return The modifySearchAttributes for this directory entry.
    *
    * @see #SA_HIDDEN
    */
   public int getModifySearchAttributes()
   {
      return(modifySearchAttributes);
   }

   /**
    * Sets the modifySearchAttributes field of the Attribute. This 
    * value is a mask that determines what the search will be while
    * modifying this attribute.
    *
    * @param value The modifySearchAttributes for this directory entry.
    */
   public void setModifySearchAttributes(int value)
   {
      modifySearchAttributes = value;
   }

   /**
    * Returns the modifyMask field of the Attribute. This value is a
    * mask that determines which data members of the object are valid
    * and should be used for a modify operation.
    *
    * @return The modifyMask for this directory entry.
    *
    * @see #SA_HIDDEN
    */
   public int getModifyMask()
   {
      return(modifyMask);
   }

   /**
    * Sets the modifyMask field of the Attribute. This value is a mask 
    * that determines which data members of the object are valid and
    * should be used for a modify operation.
    *
    * @param value The modifyMask for this directory entry.
    */
   public void setModifyMask(int value)
   {
      modifyMask = value;
   }

/* **************************************************************************
 public compareString support methods
****************************************************************************/

   /**
    * Sets the compare string value. The compare string uses the RFC1960
    * (LDAP) search string format and is used to allow individual compares
    * on the following fields:
    * <ul>
    * <li>SpaceAlloc
    * <li>Attributes
    * <li>Flags
    * <li>DataStreamSize
    * <li>TotalStreamSize
    * <li>NumberOfStreams
    * <li>CreationTime
    * <li>CreationDate
    * <li>Creator
    * <li>CreatorId
    * <li>ModifyTime
    * <li>ModifyDate
    * <li>Modifier
    * <li>ModifierId
    * <li>LastAccessDate
    * <li>ArchiveTime
    * <li>ArchiveDate
    * <li>Archiver
    * <li>ArchiverId
    * <li>InheritedRightsMask
    * <li>DirEntNum
    * <li>DosDirNum
    * <li>VolNumber
    * <li>EADataSize
    * <li>EAKeyCount
    * <li>EAKeySize
    * <li>NSCreator
    * <li>NameLength
    * <li>EntryName
    * </ul>
    *
    * <p>See the various SearchStringComponent compare methods referenced
    * below for detailed information on the operation types allowed for
    * String and integer data members.
    *
    * <p>The names of these fields takes the names of their corresponding
    * methods minus the get or set prefix. Given the following string:
    * <i>"(&(Name=*printer*)(ObjectId>=2)(Rights>=128))"</i>
    *
    * <p>The equals method returns TRUE if the name has the substring
    * "printer" in it, the objectId is not 2 and the rights are set to
    * be able to modify (TA_MODIFY). If the approximate operator type
    * is used on the Rights field the various bits of the operand value
    * are checked. If any of them are set, equals will return TRUE. For
    * example: "(Rights~=3) returns TRUE if either the TA_READ or
    * TA_WRITE bits are set, and regardless of what other bits might be set.
    *
    * <p>If the string passed in is not a valid RFC1960 formated string,
    * this method will throw an IllegalArgumentException. If the
    * compareString value is NULL, RFC1960 formated compares will be
    * disabled. </p>
    *
    * @param compareString  The RFC1960 formated search string. NULL 
    *                       disables this compare functionality.
    *
    * @exception IllegalArgumentException when the string passed in
    *            is not a valid RFC1960 formatted string.
    *
    * @see #equals
    * @see #SPACEALLOC_FIELD
    */
   public void setCompareString(String compareString)
   {
      firstParser = true;
      if (compareString != null)
      {
         this.compareString = new String(compareString);
         ssParser = new Rfc1960Parser(compareString);
      }else
      {
         this.compareString = null;
         ssParser = null;
      }
   }

   /**
    * Returns the current value of compareString.
    * 
    * @return The current value of compareString.
    *
    * @see Trustee#setCompareString
    */
   public String getCompareString()
   {
      return compareString;
   }


   /**
    * Returns the RFC1960 search string parser for the compare string.
    * 
    * <p>Returns a Rfc1960Parser object that was instantiated with the
    * compareString last set by the setCompareString method.
    * </p>
    *
    * @return The Rfc1960Parser object for the current compare String,
    *         or NULL if the compare string has not been set.
    */
   public Rfc1960Parser getSearchStringParser()
   {
      if (firstParser)
      {
         firstParser = false;
         return ssParser;
      }else
      {
         if (compareString == null)
            return null;
         return new Rfc1960Parser(compareString);
      }
   }

/* **************************************************************************
* overriden Object methods
****************************************************************************/

   /**
    * Tests if the specified object is equal to this directory entry
    * information object.
    * 
    * <p>This method compares the input object against this object. If the 
    * input object has a RFC1960 compare string, this method will do the 
    * comparision based on the commands in the compare string.
    * </p>
    *
    * @param obj The object to compare.
    *
    * @return    TRUE if equals, otherwise FALSE.
    *
    * @exception IllegalArgumentException if the operationType is illegal
    *            for the data type being compared.
    *
    * @see #setCompareString
    * @see #SPACEALLOC_FIELD
    */
   public boolean equals(Object obj)
   {
      if (obj == null || !(obj instanceof DirectoryEntryInformation))
         return false;

      DirectoryEntryInformation dei = (DirectoryEntryInformation) obj;

      Rfc1960Parser ssp = dei.getSearchStringParser();
      if (ssp == null)
      {
         // do a simple compare

         if (obj == this)
            return true;

         if (spaceAlloc == dei.getSpaceAlloc() &&
             attributes == dei.getAttributes() &&
             flags == dei.getFlags() &&
             dataStreamSize == dei.getDataStreamSize() &&
             totalStreamSize == dei.getTotalStreamSize() &&
             numberOfStreams == dei.getNumberOfStreams() &&
             creationTime == dei.getCreationTime() &&
             creationDate == dei.getCreationDate() &&
             creator.equals(dei.getCreator()) &&
             modifyTime == dei.getModifyTime() &&
             modifyDate == dei.getModifyDate() &&
             modifier.equals(dei.getModifier()) &&
             lastAccessDate == dei.getLastAccessDate() &&
             archiveTime == dei.getArchiveTime() &&
             archiveDate == dei.getArchiveDate() &&
             archiver.equals(dei.getArchiver()) &&
             getInheritedRightsMask() == dei.getInheritedRightsMask() &&
             dirEntNum == dei.getDirEntNum() &&
             DosDirNum == dei.getDosDirNum() &&
             volNumber == dei.getVolNumber() &&
             EADataSize == dei.getEADataSize() &&
             EAKeyCount == dei.getEAKeyCount() &&
             EAKeySize == dei.getEAKeySize() &&
             NSCreator == dei.getNSCreator() &&
             entryName.equalsIgnoreCase(dei.getEntryName()) &&
             SearchStringComponent.compareStringsEqual(
                                       compareString, 
                                       dei.getCompareString()) &&
             modifySearchAttributes == dei.getModifySearchAttributes() &&
             modifyMask == dei.getModifyMask())
            return true;
         return false;
      }
      while (ssp.hasMoreElements())
      {
         SearchStringComponent ssc = ssp.next();
         String name = ssc.getAttributeId();
         boolean compared = false;

         if (name.equals(SPACEALLOC_FIELD))
         {
            compared =ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getSpaceAlloc() :
                                 Integer.parseInt(ssc.getOperand()),
                              spaceAlloc);
         }else
         {
         if (name.equals(ATTRIBUTES_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getAttributes() :
                                 Integer.parseInt(ssc.getOperand()),
                              attributes);
         }else
         {
         if (name.equals(FLAGS_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getFlags() :
                                 Integer.parseInt(ssc.getOperand()),
                              flags);
         }else
         {
         if (name.equals(DATASTREAMSIZE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getDataStreamSize() :
                                 Integer.parseInt(ssc.getOperand()),
                              dataStreamSize);
         }else
         {
         if (name.equals(TOTALSTREAMSIZE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getTotalStreamSize() :
                                 Integer.parseInt(ssc.getOperand()),
                              totalStreamSize);
         }else
         {
         if (name.equals(NUMBEROFSTREAMS_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getNumberOfStreams() :
                                 Integer.parseInt(ssc.getOperand()),
                              numberOfStreams);
         }else
         {
         if (name.equals(CREATIONTIME_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getCreationTime() :
                                 Integer.parseInt(ssc.getOperand()),
                              creationTime);
         }else
         {
         if (name.equals(CREATIONDATE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getCreationDate() :
                                 Integer.parseInt(ssc.getOperand()),
                              creationDate);
         }else
         {
         if (name.equals(CREATOR_FIELD))
         {
            compared = ssc.compareString(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getCreator() :
                                 ssc.getOperand(),
                              creator,
                              true);
         }else
         {
         if (name.equals(MODIFYTIME_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getModifyTime() :
                                 Integer.parseInt(ssc.getOperand()),
                              modifyTime);
         }else
         {
         if (name.equals(MODIFYDATE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getModifyDate() :
                                 Integer.parseInt(ssc.getOperand()),
                              modifyDate);
         }else
         {
         if (name.equals(MODIFIER_FIELD))
         {
            compared = ssc.compareString(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getModifier() :
                                 ssc.getOperand(),
                              modifier,
                              true);
         }else
         {
         if (name.equals(LASTACCESSDATE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getLastAccessDate() :
                                 Integer.parseInt(ssc.getOperand()),
                              lastAccessDate);
         }else
         {
         if (name.equals(ARCHIVETIME_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getArchiveTime() :
                                 Integer.parseInt(ssc.getOperand()),
                              archiveTime);
         }else
         {
         if (name.equals(ARCHIVEDATE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getArchiveDate() :
                                 Integer.parseInt(ssc.getOperand()),
                              archiveDate);
         }else
         {
         if (name.equals(ARCHIVER_FIELD))
         {
            compared = ssc.compareString(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getArchiver() :
                                 ssc.getOperand(),
                              archiver,
                              true);
         }else
         {
         if (name.equals(INHERITEDRIGHTSMASK_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getInheritedRightsMask() :
                                 Integer.parseInt(ssc.getOperand()),
                              getInheritedRightsMask());
         }else
         {
         if (name.equals(DIRENTNUM_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getDirEntNum() :
                                 Integer.parseInt(ssc.getOperand()),
                              dirEntNum);
         }else
         {
         if (name.equals(DOSDIRNUM_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getDosDirNum() :
                                 Integer.parseInt(ssc.getOperand()),
                              DosDirNum);
         }else
         {
         if (name.equals(VOLNUMBER_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getVolNumber() :
                                 Integer.parseInt(ssc.getOperand()),
                              volNumber);
         }else
         {
         if (name.equals(EADATASIZE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getEADataSize() :
                                 Integer.parseInt(ssc.getOperand()),
                              EADataSize);
         }else
         {
         if (name.equals(EAKEYCOUNT_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getEAKeyCount() :
                                 Integer.parseInt(ssc.getOperand()),
                              EAKeyCount);
         }else
         {
         if (name.equals(EAKEYSIZE_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getEAKeySize() :
                                 Integer.parseInt(ssc.getOperand()),
                              EAKeySize);
         }else
         {
         if (name.equals(NSCREATOR_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getNSCreator() :
                                 Integer.parseInt(ssc.getOperand()),
                              NSCreator);
         }else
         {
         if (name.equals(NAMELENGTH_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getNameLength() :
                                 Integer.parseInt(ssc.getOperand()),
                              nameLength);
         }else
         {
         if (name.equals(ENTRYNAME_FIELD))
         {
            compared = ssc.compareString(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getEntryName() :
                                 ssc.getOperand(),
                              entryName,
                              true);
         }else
         {
         if (name.equals(MODIFYSEARCHATTRIBUTES_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getModifySearchAttributes() :
                                 Integer.parseInt(ssc.getOperand()),
                              modifySearchAttributes);
         }else
         {
         if (name.equals(MODIFYMASK_FIELD))
         {
            compared = ssc.compareInt(
                              ssc.getOperationType(), 
                              ssc.operandReplacement() ?
                                 dei.getModifyMask() :
                                 Integer.parseInt(ssc.getOperand()),
                              modifyMask);
         }else
            compared = false;

         }}}}}}}}}}}}}}}}}}}}}}}}}}}
         ssp.setCompareResult(ssc, compared);
      }
      return ssp.compared();
   }

   /**
    * Creates and returns a comma separated list of all attribute values.
    *
    * <p>The list of returned values is in the following format:
    * "spaceAlloc: n, attributes: n, flags: n, dataStreamSize: n, 
    * totalStreamSize: n, numberOfStreams: n, creationTime: n, 
    * creationDate: n, creator: s, modifyTime: n, modifyDate: n, modifier: s, 
    * lastAccessDate: n, archiveTime: n, archiveDate: n, archiver: s,
    * inheritedRightsMask: n, dirEntNum: n, DosDirNum: n, volNumber: n,
    * EADataSize: n, EAKeyCount: n, EAKeySize: n, NSCreator: n, 
    * nameLength: n, entryName: s, modifySearchAttributes: n, 
    * compareString: s, modifyMask: n"
    * </p>
    *
    * @return Comma separated list of attribute values
    */
   public String toString()
   {
      return new String(
                     "spaceAlloc: " + spaceAlloc +
                     ", attributes: " + attributes +
                     ", flags: " + flags +
                     ", dataStreamSize: " + dataStreamSize +
                     ", totalStreamSize: " + totalStreamSize +
                     ", numberOfStreams: " + numberOfStreams +
                     ", creationTime: " + creationTime +
                     ", creationDate: " + creationDate +
                     ", creator: " + creator +
                     ", modifyTime: " + modifyTime +
                     ", modifyDate: " + modifyDate +
                     ", modifier: " + modifier +
                     ", lastAccessDate: " + lastAccessDate +
                     ", archiveTime: " + archiveTime +
                     ", archiveDate: " + archiveDate +
                     ", archiver: " + archiver +
                     ", inheritedRightsMask: " + inheritedRightsMask +
                     ", dirEntNum: " + dirEntNum +
                     ", DosDirNum: " + DosDirNum +
                     ", volNumber: " + volNumber +
                     ", EADataSize: " + EADataSize +
                     ", EAKeyCount: " + EAKeyCount +
                     ", EAKeySize: " + EAKeySize +
                     ", NSCreator: " + NSCreator +
                     ", entryName: " + entryName +
                     ", modifySearchAttributes: " + modifySearchAttributes +
                     ", compareString: " + compareString +
                     ", modifyMask: " + modifyMask);
   }

   /**
    * Clones this object.
    * 
    * <p>Instantiates a new instance of this type and assigns all fields
    * using the current values of the fields of this directory entry
    * information object.
    * </p>
    *
    * @return A new VolumeRestriction object with the same values.
    */
   public Object clone()
   {
      DirectoryEntryInformation obj = null;
      try
      {
         obj = (DirectoryEntryInformation) super.clone();
      }
      catch (CloneNotSupportedException e)
      {
         // this shouldn't happen, since we are Cloneable
         throw (new InternalError());
      }

      obj.spaceAlloc = spaceAlloc;
      obj.attributes = attributes;
      obj.flags = flags;
      obj.dataStreamSize = dataStreamSize;
      obj.totalStreamSize = totalStreamSize;
      obj.numberOfStreams = numberOfStreams;
      obj.creationTime = creationTime;
      obj.creationDate = creationDate;
      obj.creator = creator;
      obj.modifyTime = modifyTime;
      obj.modifyDate = modifyDate;
      obj.modifier = modifier;
      obj.lastAccessDate = lastAccessDate;
      obj.archiveTime = archiveTime;
      obj.archiveDate = archiveDate;
      obj.archiver = archiver;
      obj.inheritedRightsMask = inheritedRightsMask;
      obj.dirEntNum = dirEntNum;
      obj.DosDirNum = DosDirNum;
      obj.volNumber = volNumber;
      obj.EADataSize = EADataSize;
      obj.EAKeyCount = EAKeyCount;
      obj.EAKeySize = EAKeySize;
      obj.NSCreator = NSCreator;
      obj.nameLength = nameLength;
      obj.entryName = entryName;
      obj.modifySearchAttributes = SA_HIDDEN | SA_SYSTEM | SA_SUBDIR_FILES;
      obj.modifyMask = modifyMask;
      obj.creatorID = creatorID;
      obj.modifierID = modifierID;
      obj.archiverID = archiverID;
      obj.compareString = compareString;
      obj.ssParser = ssParser;
      obj.firstParser = firstParser;
      obj.setCompareString(compareString);
      obj.setModifyMask(modifyMask);
      return obj;
   }

   public void copy(DirectoryEntryInformation from)
   {
      this.spaceAlloc = from.spaceAlloc;
      this.attributes = from.attributes;
      this.flags = from.flags;
      this.dataStreamSize = from.dataStreamSize;
      this.totalStreamSize = from.totalStreamSize;
      this.numberOfStreams = from.numberOfStreams;
      this.creationTime = from.creationTime;
      this.creationDate = from.creationDate;
      this.creator = from.creator;
      this.modifyTime = from.modifyTime;
      this.modifyDate = from.modifyDate;
      this.modifier = from.modifier;
      this.lastAccessDate = from.lastAccessDate;
      this.archiveTime = from.archiveTime;
      this.archiveDate = from.archiveDate;
      this.archiver = from.archiver;
      this.inheritedRightsMask = from.inheritedRightsMask;
      this.dirEntNum = from.dirEntNum;
      this.DosDirNum = from.DosDirNum;
      this.volNumber = from.volNumber;
      this.EADataSize = from.EADataSize;
      this.EAKeyCount = from.EAKeyCount;
      this.EAKeySize = from.EAKeySize;
      this.NSCreator = from.NSCreator;
      this.nameLength = from.nameLength;
      this.entryName = from.entryName;
      this.modifySearchAttributes = from.SA_HIDDEN | SA_SYSTEM | SA_SUBDIR_FILES;
      this.modifyMask = from.modifyMask;
      this.creatorID = from.creatorID;
      this.modifierID = from.modifierID;
      this.archiverID = from.archiverID;
      this.compareString = from.compareString;
      this.ssParser = from.ssParser;
      this.firstParser = from.firstParser;
   }
}
