/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
* Portions Copyright 2013-2015 ForgeRock AS.
*/
/**
* This class provides a mechanism for writing entries in LDIF form to a file or
* an output stream.
*/
mayInstantiate=true,
mayExtend=false,
mayInvoke=true)
{
// FIXME -- Add support for generating a hash when writing the data.
// FIXME -- Add support for signing the hash that is generated.
/** The writer to which the LDIF information will be written. */
/** The configuration to use for the export. */
/** Regular expression used for splitting comments on line-breaks. */
/**
* Creates a new LDIF writer with the provided configuration.
*
* @param exportConfig The configuration to use for the export. It must not
* be <CODE>null</CODE>.
*
* @throws IOException If a problem occurs while opening the writer.
*/
throws IOException
{
this.exportConfig = exportConfig;
}
/**
* Writes the provided comment to the LDIF file, optionally wrapping near the
* specified column. Each line will be prefixed by the octothorpe (#)
* character followed by a space. If the comment should be wrapped at a
* specified column, then it will attempt to do so at the first whitespace
* character at or before that column (so it will try not wrap in the middle
* of a word).
* <BR><BR>
* This comment will be ignored by the
* Directory Server's LDIF reader, as well as any other compliant LDIF parsing
* software.
*
* @param comment The comment to be written. Any line breaks that it
* contains will be honored, and potentially new line
* breaks may be introduced by the wrapping process. It
* must not be <CODE>null</CODE>.
* @param wrapColumn The column at which long lines should be wrapped, or
* -1 to indicate that no additional wrapping should be
* added. This will override the wrap column setting
* specified in the LDIF export configuration.
*
* @throws IOException If a problem occurs while attempting to write the
* comment to the LDIF file.
*/
throws IOException
{
// First, break up the comment into multiple lines to preserve the original
// spacing that it contained.
// Now iterate through the lines and write them out, prefixing and wrapping
// them as necessary.
{
if (wrapColumn <= 0)
{
}
else
{
if (l.length() <= breakColumn)
{
}
else
{
int startPos = 0;
{
{
}
else
{
int i=endPos - 1;
while (i > startPos)
{
if (l.charAt(i) == ' ')
{
startPos = i+1;
continue outerLoop;
}
i--;
}
// If we've gotten here, then there are no spaces on the entire
// line. If that happens, then we'll have to break in the middle
// of a word.
}
}
}
}
}
}
/**
* Iterates over each entry contained in the map and writes out the entry in
* LDIF format. The main benefit of this method is that the entries can be
* sorted by DN and output in sorted order.
*
* @param entries The Map containing the entries keyed by DN.
*
* @return <CODE>true</CODE>of all of the entries were
* written out, <CODE>false</CODE>if it was not
* because of the export configuration.
*
* @throws IOException If a problem occurs while writing the entry to LDIF.
*
* @throws LDIFException If a problem occurs while trying to determine
* whether to include the entry in the export.
*/
{
{
if (!writeEntry(entry))
{
return false;
}
}
return true;
}
/**
* Writes the provided entry to LDIF.
*
* @param entry The entry to be written. It must not be <CODE>null</CODE>.
*
* @return <CODE>true</CODE> if the entry was actually written, or
* <CODE>false</CODE> if it was not because of the export
* configuration.
*
* @throws IOException If a problem occurs while writing the entry to LDIF.
*
* @throws LDIFException If a problem occurs while trying to determine
* whether to include the entry in the export.
*/
throws IOException, LDIFException
{
}
/**
* Writes the provided template entry to LDIF.
*
* @param templateEntry The template entry to be written. It must not be
* <CODE>null</CODE>.
*
* @return <CODE>true</CODE> if the entry was actually written, or
* <CODE>false</CODE> if it was not because of the export
* configuration.
*
* @throws IOException If a problem occurs while writing the template entry
* to LDIF.
*
* @throws LDIFException If a problem occurs while trying to determine
* whether to include the template entry in the
* export.
*/
throws IOException, LDIFException
{
}
/**
* Writes a change record entry for the provided change record.
*
* @param changeRecord The change record entry to be written.
*
* @throws IOException If a problem occurs while writing the change record.
*/
throws IOException
{
// Get the information necessary to write the LDIF.
// First, write the DN.
// Figure out what type of change it is and act accordingly.
if (changeRecord instanceof AddChangeRecordEntry)
{
{
for (ByteString v : a)
{
}
}
}
else if (changeRecord instanceof DeleteChangeRecordEntry)
{
}
else if (changeRecord instanceof ModifyChangeRecordEntry)
{
{
RawAttribute a = m.getAttribute();
for (ByteString s : a.getValues())
{
{
}
else
{
}
}
{
}
}
}
else if (changeRecord instanceof ModifyDNChangeRecordEntry)
{
if (newSuperiorDN != null)
{
}
}
// Make sure there is a blank line after the entry.
}
/**
* Writes an add change record for the provided entry. No filtering will be
* performed for this entry, nor will any export plugins be invoked. Further,
* only the user attributes will be included.
*
* @param entry The entry to include in the add change record. It must not
* be <CODE>null</CODE>.
*
* @throws IOException If a problem occurs while writing the add record.
*/
throws IOException
{
// Get the information necessary to write the LDIF.
// First, write the DN.
// Next, the changetype.
// Now the objectclasses.
{
}
// Finally, the set of user attributes.
{
{
for (String o : a.getOptions())
{
}
for (ByteString v : a)
{
}
}
}
// Make sure there is a blank line after the entry.
}
/**
* Writes a delete change record for the provided entry, optionally including
* a comment with the full entry contents. No filtering will be performed for
* this entry, nor will any export plugins be invoked. Further, only the user
* attributes will be included.
*
* @param entry The entry to include in the delete change record. It
* must not be <CODE>null</CODE>.
* @param commentEntry Indicates whether to include a comment with the
* contents of the entry.
*
* @throws IOException If a problem occurs while writing the delete record.
*/
throws IOException
{
// Get the information necessary to write the LDIF.
// Add the DN and changetype lines.
// If we should include a comment with the rest of the entry contents, then
// do so now.
if (commentEntry)
{
// Write the objectclasses.
{
}
// Write the set of user attributes.
{
{
for (String o : a.getOptions())
{
}
for (ByteString v : a)
{
}
}
}
}
// Make sure there is a blank line after the entry.
}
/**
* Writes a modify change record with the provided information. No filtering
* will be performed, nor will any export plugins be invoked.
*
* @param dn The DN of the entry being modified. It must not be
* <CODE>null</CODE>.
* @param modifications The set of modifications to include in the change
* record. It must not be <CODE>null</CODE>.
*
* @throws IOException If a problem occurs while writing the modify record.
*/
throws IOException
{
// If there aren't any modifications, then there's nothing to do.
if (modifications.isEmpty())
{
return;
}
// Get the information necessary to write the LDIF.
// Write the DN and changetype.
// Iterate through the modifications and write them to the LDIF.
{
Attribute a = m.getAttribute();
for (String o : a.getOptions())
{
nameBuffer.append(o);
}
for (ByteString v : a)
{
}
// If this is the last modification, then append blank line. Otherwise
// write a line with just a dash.
{
}
}
}
/**
* Writes a modify DN change record with the provided information. No
* filtering will be performed, nor will any export plugins be invoked.
*
* @param dn The DN of the entry before the rename. It must not
* be <CODE>null</CODE>.
* @param newRDN The new RDN for the entry. It must not be
* <CODE>null</CODE>.
* @param deleteOldRDN Indicates whether the old RDN value should be removed
* from the entry.
* @param newSuperior The new superior DN for the entry, or
* <CODE>null</CODE> if the entry will stay below the
* same parent.
*
* @throws IOException If a problem occurs while writing the modify record.
*/
throws IOException
{
// Get the information necessary to write the LDIF.
// Write the current DN.
// Write the changetype. Some older tools may not support the "moddn"
// changetype, so only use it if a newSuperior element has been provided,
// but use modrdn elsewhere.
// Write the newRDN element.
// Write the deleteOldRDN element.
if (newSuperior != null)
{
}
// Make sure there is a blank line after the entry.
}
{
}
throws IOException
{
}
/**
* Flushes the data written to the output stream or underlying file.
*
* @throws IOException If a problem occurs while flushing the output.
*/
public void flush()
throws IOException
{
}
/**
* Closes the LDIF writer and the underlying output stream or file.
*
* @throws IOException If a problem occurs while closing the writer.
*/
public void close()
throws IOException
{
}
/**
* Appends an LDIF separator and properly-encoded form of the given
* value to the provided buffer. If the value is safe to include
* as-is, then a single colon, a single space, space, and the
* provided value will be appended. Otherwise, two colons, a single
* space, and a base64-encoded form of the value will be appended.
*
* @param buffer The buffer to which the information should be
* appended. It must not be <CODE>null</CODE>.
* @param valueBytes The value to append to the buffer. It must not be
* <CODE>null</CODE>.
*/
{
}
/**
* Appends an LDIF separator and properly-encoded form of the given
* value to the provided buffer. If the value is safe to include
* as-is, then a single colon, a single space, space, and the
* provided value will be appended. Otherwise, two colons, a single
* space, and a base64-encoded form of the value will be appended.
* @param buffer The buffer to which the information should be
* appended. It must not be <CODE>null</CODE>.
* @param valueBytes The value to append to the buffer. It must not be
* <CODE>null</CODE>.
* @param isURL Whether the provided value is an URL value or not.
* @param isBase64 Whether the provided value is a base 64 value or not.
*/
{
// If the value is empty, then just append a single colon (the URL '<' if
// required) and a single space.
if (isURL)
{
if (!valueIsEmpty)
{
}
}
else if (isBase64)
{
if (!valueIsEmpty)
{
}
}
else if (needsBase64Encoding(valueBytes))
{
}
else
{
if (!valueIsEmpty)
{
}
}
}
/**
* Writes the provided line to LDIF using the provided information.
*
* @param line The line of information to write. It must not be
* <CODE>null</CODE>.
* @param writer The writer to which the data should be written. It
* must not be <CODE>null</CODE>.
* @param wrapLines Indicates whether to wrap long lines.
* @param wrapColumn The column at which long lines should be wrapped.
*
* @throws IOException If a problem occurs while writing the information.
*/
boolean wrapLines, int wrapColumn)
throws IOException
{
{
int pos = wrapColumn;
{
}
}
else
{
}
}
}