Class RandomAccessLDIF
- java.lang.Object
-
- com.isode.dsapi.RandomAccessLDIF
-
public class RandomAccessLDIF extends java.lang.Object
A class which enables random-access to LDIF files for both reading and writing.- Author:
- jp
-
-
Constructor Summary
Constructors Constructor Description RandomAccessLDIF(java.lang.String in_fnam, java.lang.String tmp_fnam, java.lang.String out_fnam)
Set up an RandomAccessLDIF object with the given files.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
close()
Close the input/output files.java.lang.String
error()
Return the next error/warning-string stored from previous operations, or null if there are no more.boolean
exists(DN dn)
Check whether the given DN exists as a real entry within the logical tree (in other words, it is a leaf or parent).protected void
finalize()
Releases any native structures associated with this object.GenericEntry
get(DN dn)
Get the entry with the given DN from the logical contents of the object.boolean
getAllowUnknownAttrs()
Get the current 'allow unknown attributes' flag status.ChangeEntry
getChange(DN dn)
Get the change entry with the given DN from the logical contents of the object.Entry
getEntry(DN dn)
Get the normal entry with the given DN from the logical contents of the object.boolean
isClosed()
Check if RandomAccessLDIF has been closed yet.GenericEntry
next()
Get the next entry from the search as a GenericEntry.ChangeEntry
nextChange()
Get the next entry from the search as a ChangeEntry.DN
nextDN()
Get the next entry from the search as a DN.Entry
nextEntry()
Get the next entry from the search as an Entry.void
put(GenericEntry entry)
Write an entry to the logical tree.boolean
remove(DN dn)
Remove the entry with the given DN from the logical contents.void
search(DN dn, boolean sorted, boolean subtree)
Start a search through the logical tree.void
setAllowUnknownAttrs(boolean flag)
Set the status of the 'allow unknown attributes' flag.java.lang.String
toString()
Returns a String representation of the objectboolean
wasGlue()
Test whether the last DN visited corresponds to a glue entry in the tree.boolean
wasLeaf()
Test whether the last DN visited corresponds to a leaf entry in the tree.boolean
wasParent()
Test whether the last DN visited corresponds to a parent entry in the tree.boolean
wasReal()
Test whether the last DN visited corresponds to a real entry in the tree (either a leaf or a parent).void
write()
The final output file is created and written (if one was specified in the constructor), based on the logical tree in memory and the entries from the input and cache files.
-
-
-
Constructor Detail
-
RandomAccessLDIF
public RandomAccessLDIF(java.lang.String in_fnam, java.lang.String tmp_fnam, java.lang.String out_fnam) throws OperationFailedException, java.lang.NullPointerException, NativeLibraryException
Set up an RandomAccessLDIF object with the given files. Any combination of the given files may be passed, with the remainder passed as 'null'.If the input filename is passed, then the logical contents of the object are initialised from this read-only LDIF file. Otherwise the logical contents of the object are initialised to an empty tree.
If the cache filename is passed, then this allows adding new entries to the logical contents of the object. The new entries are saved temporarily in the cache file. If the caller re-reads these entries, they are re-read from the cache file as necessary. If there is a final output file, they are re-read again when that file is built up. The cache file is always deleted when the object is closed. If no cache filename is passed, then no put() calls can be made.
If the output filename is passed, then a final output file can be written with the final logical contents of the object using the write() call. It is permissible for the input and output filenames to be the same, in which case the output file is written with ".new" appended, and on the close(), the input file is renamed with ".bak" appended and the new output file put into its place. If no output filename is passed, or if write() isn't called, then the final logical contents of the object are discarded when it is closed.
Note that certain combinations of non-null arguments suit particular uses:
- For read-only random-access to a file (no modifications), only the input filename is passed. Deletions are permitted to the logical contents, but they are not saved anywhere.
- For a temporary caching file, only the cache filename is passed. The logical contents of the object are initially empty, additions and modifications are permitted to the logical contents (with new entries cached in the cache file), but everything will be discarded on close().
- For making random-access modifications to an existing LDIF file, all three file parameters are passed, with the input and output filenames the same. The logical contents start off as a copy of the input file, tracking modifications as they are made and temporarily storing new entries in the cache file, before finally rewriting the output file from the logical contents on write() and close().
Note that initialising the object with a large input file may take a few moments, as the file has to be scanned to create the in-memory DN tree. If there are any problems whilst scanning the input file, warnings are added to the list of strings returned by error(), and the scan continues. For this reason, it is important to check the error() function for warnings after constructing the object.
- Parameters:
in_fnam
- Input file pathname, or null for no input filetmp_fnam
- Cache file pathname, or null for no cache fileout_fnam
- Output file pathname, or null for no output file- Throws:
OperationFailedException
- Can't open/create one of the filesjava.lang.NullPointerException
- Both arguments were nullNativeLibraryException
- Internal unrecoverable error
-
-
Method Detail
-
write
public void write() throws OperationFailedException, NativeLibraryException
The final output file is created and written (if one was specified in the constructor), based on the logical tree in memory and the entries from the input and cache files. Note that if the input and output filenames are the same, then this only writes the .new file; it doesn't rename the files (which is done in the final close()). This means that it is possible to repeat this call if it fails.There may be problems whilst writing the output file, which cause the function to return with OperationFailedException; any partial output file is deleted in this case.
- Throws:
OperationFailedException
- Writing the output file failed; see the error() outputNativeLibraryException
- Internal unrecoverable error
-
close
public void close() throws OperationFailedException, NativeLibraryException
Close the input/output files. The cache file is deleted, and the input and output files are renamed (if the output file is overwriting the input file). Note that if an output file is required, then write() must be called before close().If deleting or renaming files fails, then the files may be left in an inconsistant state: the cache file may still be there, and the new copy of the output file may still have its .new extension instead of having been renamed in place of the original file. These errors are logged, and OperationFailedException will be thrown in this case.
If any operation is attempted on the object after this call, a NativeLibraryException will be thrown. In particular, fetching errors with error() must be done before closing the stream.
Note that a close() is done automatically when the object is finalized by Java, but the delay before this happens is unpredictable. For this reason it is vital to close the files manually with this call.
- Throws:
NativeLibraryException
- Internal unrecoverable errorOperationFailedException
- Final delete of cache file or renames of input files didn't complete successfully.
-
setAllowUnknownAttrs
public void setAllowUnknownAttrs(boolean flag)
Set the status of the 'allow unknown attributes' flag. With this flag set, unknown attributes found in the LDIF file won't be rejected with an error, but will be passed back with an 'octetstring' syntax. These unknown attributes can be written over LDAP or to LDIF files, but not sent over DAP.- Parameters:
flag
- Allow unknown attributes?
-
getAllowUnknownAttrs
public boolean getAllowUnknownAttrs()
Get the current 'allow unknown attributes' flag status.- Returns:
- Allow unknown attributes?
-
put
public void put(GenericEntry entry) throws OperationFailedException, java.lang.NullPointerException, BadEntryException, BadDNException, NativeLibraryException
Write an entry to the logical tree. This overwrites any existing entry with the same DN. This operation is permitted only if there is a cache file active. Any GenericEntry subclass instance may be written -- Entry, AddEntry, ModifyEntry, DeleteEntry or RenameEntry -- although normal entries and change-entries cannot be mixed in the same file.- Parameters:
entry
- GenericEntry to write- Throws:
OperationFailedException
- Error writing data to the filejava.lang.NullPointerException
- Argument is nullBadEntryException
- The entry could not be converted to LDIF formatBadDNException
- The DN could not be converted to LDIF formatNativeLibraryException
- Internal unrecoverable error
-
wasLeaf
public boolean wasLeaf() throws NativeLibraryException
Test whether the last DN visited corresponds to a leaf entry in the tree. This tests the last entry visited by exists(), get(), getEntry(), getChange(), nextDN(), next(), nextEntry() or nextChange(). The type of the last-visited logical tree entry may be: leaf entry, parent entry, glue entry or missing.- Returns:
- 'true' if last DN visited was a leaf
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
wasParent
public boolean wasParent() throws NativeLibraryException
Test whether the last DN visited corresponds to a parent entry in the tree. This tests the last entry visited by exists(), get(), getEntry(), getChange(), nextDN(), next(), nextEntry() or nextChange(). The type of the last-visited logical tree entry may be: leaf entry, parent entry, glue entry or missing.- Returns:
- 'true' if last DN visited was a parent
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
wasReal
public boolean wasReal() throws NativeLibraryException
Test whether the last DN visited corresponds to a real entry in the tree (either a leaf or a parent). This tests the last entry visited by exists(), get(), getEntry(), getChange(), nextDN(), next(), nextEntry() or nextChange(). The type of the last-visited logical tree entry may be: leaf entry, parent entry, glue entry or missing.- Returns:
- 'true' if last DN visited was a parent or leaf
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
wasGlue
public boolean wasGlue() throws NativeLibraryException
Test whether the last DN visited corresponds to a glue entry in the tree. This tests the last entry visited by exists(), get(), getEntry(), getChange(), nextDN(), next(), nextEntry() or nextChange(). The type of the last-visited logical tree entry may be: leaf entry, parent entry, glue entry or missing.- Returns:
- 'true' if last DN visited was a glue entry
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
exists
public boolean exists(DN dn) throws NativeLibraryException
Check whether the given DN exists as a real entry within the logical tree (in other words, it is a leaf or parent). Real entries must have entry-data associated with them, so glue entries do not count.- Returns:
- DN corresponds to a real entry?
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
remove
public boolean remove(DN dn) throws NativeLibraryException
Remove the entry with the given DN from the logical contents.- Returns:
- true: deleted, false: not found
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
get
public GenericEntry get(DN dn) throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the entry with the given DN from the logical contents of the object.The actual entry data is fetched from either the input file or the cache file. A missing entry is indicated by a null return rather than by an exception. A GenericEntry is returned, which may be an instance of: Entry, AddEntry, ModifyEntry, DeleteEntry or RenameEntry
- Returns:
- GenericEntry loaded, or null for DN not found
- Throws:
OperationFailedException
- Failed loading the entry from the input or cache fileBadEntryException
- A bad entry on the file was encounteredBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
getEntry
public Entry getEntry(DN dn) throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the normal entry with the given DN from the logical contents of the object. If a ChangeEntry is returned, this is rejected with a BadEntryException.The actual entry data is fetched from either the input file or the cache file. A missing entry is indicated by a null return rather than by an exception.
- Returns:
- Entry loaded, or null for DN not found
- Throws:
OperationFailedException
- Failed loading the entry from the input or cache fileBadEntryException
- A bad entry on the file was encounteredBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
getChange
public ChangeEntry getChange(DN dn) throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the change entry with the given DN from the logical contents of the object. If a normal entry is returned, this is rejected with a BadEntryException.The actual entry data is fetched from either the input file or the cache file. A missing entry is indicated by a null return rather than by an exception.
- Returns:
- ChangeEntry loaded, or null for DN not found
- Throws:
OperationFailedException
- Failed loading the entry from the input or cache fileBadEntryException
- A bad entry on the file was encounteredBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
error
public java.lang.String error() throws NativeLibraryException
Return the next error/warning-string stored from previous operations, or null if there are no more. Note that one error/warning string is returned per call, so this call must be repeated until all errors have been exhausted.- Returns:
- Error/warning string, or null
- Throws:
NativeLibraryException
- Internal unrecoverable error
-
search
public void search(DN dn, boolean sorted, boolean subtree) throws OperationFailedException, NativeLibraryException
Start a search through the logical tree. The starting point of the scan is below the given DN, or starting from root if 'dn' is null. The data is returned sorted if 'sorted' is true, otherwise in the internal ordering (which may be a hashed ordering). The scan is a one-level scan, unless 'subtree' is true, in which case it is a subtree scan with each subtree dumped immediately after its parent. There can be only one search active at any one time in any given RandomAccessLDIF instance.Note that adding or deleting entries in the logical tree causes the search to be aborted. Any next() or nextDN() call made after changes to the logical tree will throw an exception.
- Parameters:
dn
- DN to search below, or null to start from rootsorted
- Sorted search? Otherwise unsorted.subtree
- Subtree search? Otherwise a one-level search.- Throws:
OperationFailedException
- There was no entry with that DNNativeLibraryException
- Internal unrecoverable error
-
nextDN
public DN nextDN() throws OperationFailedException, NativeLibraryException
Get the next entry from the search as a DN. If the end of the search is reached, null is returned. This operation may return DNs that are glue entries (i.e. that don't have a corresponding entry stored for them).- Throws:
OperationFailedException
- A modification has been made to the logical tree.NativeLibraryException
- Internal unrecoverable error
-
next
public GenericEntry next() throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the next entry from the search as a GenericEntry. If the end of the search is reached, null is returned. Note that this operation skips over glue entries.- Throws:
OperationFailedException
- Failed seeking to the entry; or a modification has been made to the logical tree.BadEntryException
- A bad entry on the file was encounteredBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
nextEntry
public Entry nextEntry() throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the next entry from the search as an Entry. If the end of the search is reached, null is returned. If the entry returned is not a normal entry, then a BadEntryException is thrown. Note that this operation skips over glue entries.- Throws:
OperationFailedException
- Failed seeking to the entry; or a modification has been made to the logical tree.BadEntryException
- A bad entry on the file was encountered, or it was a ChangeEntryBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
nextChange
public ChangeEntry nextChange() throws OperationFailedException, BadEntryException, BadDNException, NativeLibraryException
Get the next entry from the search as a ChangeEntry. If the end of the search is reached, null is returned. If the entry returned is not a change-entry, then a BadEntryException is thrown. Note that this operation skips over glue entries.- Throws:
OperationFailedException
- Failed seeking to the entry; or a modification has been made to the logical tree.BadEntryException
- A bad entry on the file was encountered, or it wasn't a ChangeEntryBadDNException
- The loaded entry has a bad DNNativeLibraryException
- Internal unrecoverable error
-
isClosed
public boolean isClosed()
Check if RandomAccessLDIF has been closed yet.- Returns:
- 'true' if it has been closed
-
finalize
protected void finalize() throws java.lang.Throwable
Releases any native structures associated with this object.- Overrides:
finalize
in classjava.lang.Object
- Throws:
java.lang.Throwable
-
toString
public java.lang.String toString()
Returns a String representation of the object- Overrides:
toString
in classjava.lang.Object
- Returns:
- String representation of the object
-
-