/*
* 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
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* 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
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2009 Sun Microsystems, Inc.
*/
package org.opends.sdk.ldif;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.opends.sdk.*;
import org.opends.sdk.requests.AddRequest;
import org.opends.sdk.requests.DeleteRequest;
import org.opends.sdk.requests.ModifyDNRequest;
import org.opends.sdk.requests.ModifyRequest;
import org.opends.sdk.schema.Schema;
import com.sun.opends.sdk.util.Validator;
/**
* An LDIF change record writer writes change records using the LDAP
* Data Interchange Format (LDIF) to a user defined destination.
*
* @see RFC 2849 - The LDAP
* Data Interchange Format (LDIF) - Technical Specification
*/
public final class LDIFChangeRecordWriter extends AbstractLDIFWriter
implements ChangeRecordWriter
{
/**
* Creates a new LDIF change record writer which will append lines of
* LDIF to the provided list.
*
* @param ldifLines
* The list to which lines of LDIF should be appended.
*/
public LDIFChangeRecordWriter(List ldifLines)
{
super(ldifLines);
}
/**
* Creates a new LDIF change record writer whose destination is the
* provided output stream.
*
* @param out
* The output stream to use.
*/
public LDIFChangeRecordWriter(OutputStream out)
{
super(out);
}
/**
* {@inheritDoc}
*/
public void close() throws IOException
{
close0();
}
/**
* {@inheritDoc}
*/
public void flush() throws IOException
{
flush0();
}
/**
* Specifies whether or not user-friendly comments should be added
* whenever distinguished names or UTF-8 attribute values are
* encountered which contained non-ASCII characters. The default is
* {@code false}.
*
* @param addUserFriendlyComments
* {@code true} if user-friendly comments should be added, or
* {@code false} otherwise.
* @return A reference to this {@code LDIFEntryWriter}.
*/
public LDIFChangeRecordWriter setAddUserFriendlyComments(
boolean addUserFriendlyComments)
{
this.addUserFriendlyComments = addUserFriendlyComments;
return this;
}
/**
* Specifies whether or not all operational attributes should be
* excluded from any change records that are written to LDIF. The
* default is {@code false}.
*
* @param excludeOperationalAttributes
* {@code true} if all operational attributes should be
* excluded, or {@code false} otherwise.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setExcludeAllOperationalAttributes(
boolean excludeOperationalAttributes)
{
this.excludeOperationalAttributes = excludeOperationalAttributes;
return this;
}
/**
* Specifies whether or not all user attributes should be excluded
* from any change records that are written to LDIF. The default is
* {@code false}.
*
* @param excludeUserAttributes
* {@code true} if all user attributes should be excluded, or
* {@code false} otherwise.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setExcludeAllUserAttributes(
boolean excludeUserAttributes)
{
this.excludeUserAttributes = excludeUserAttributes;
return this;
}
/**
* Excludes the named attribute from any change records that are
* written to LDIF. By default all attributes are included unless
* explicitly excluded.
*
* @param attributeDescription
* The name of the attribute to be excluded.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setExcludeAttribute(
AttributeDescription attributeDescription)
{
Validator.ensureNotNull(attributeDescription);
excludeAttributes.add(attributeDescription);
return this;
}
/**
* Excludes all change records which target entries beneath the named
* entry (inclusive) from being written to LDIF. By default all change
* records are written unless explicitly excluded or included.
*
* @param excludeBranch
* The distinguished name of the branch to be excluded.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setExcludeBranch(DN excludeBranch)
{
Validator.ensureNotNull(excludeBranch);
excludeBranches.add(excludeBranch);
return this;
}
/**
* Ensures that the named attribute is not excluded from any change
* records that are written to LDIF. By default all attributes are
* included unless explicitly excluded.
*
* @param attributeDescription
* The name of the attribute to be included.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setIncludeAttribute(
AttributeDescription attributeDescription)
{
Validator.ensureNotNull(attributeDescription);
includeAttributes.add(attributeDescription);
return this;
}
/**
* Ensures that all change records which target entries beneath the
* named entry (inclusive) are written to LDIF. By default all change
* records are written unless explicitly excluded or included.
*
* @param includeBranch
* The distinguished name of the branch to be included.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setIncludeBranch(DN includeBranch)
{
Validator.ensureNotNull(includeBranch);
includeBranches.add(includeBranch);
return this;
}
/**
* Sets the schema which should be used when filtering change records
* (not required if no filtering is to be performed). The default
* schema is used if no other is specified.
*
* @param schema
* The schema which should be used when filtering change
* records.
* @return A reference to this {@code LDIFChangeRecordWriter}.
*/
public LDIFChangeRecordWriter setSchema(Schema schema)
{
Validator.ensureNotNull(schema);
this.schema = schema;
return this;
}
/**
* Specifies the column at which long lines should be wrapped. A value
* less than or equal to zero (the default) indicates that no wrapping
* should be performed.
*
* @param wrapColumn
* The column at which long lines should be wrapped.
* @return A reference to this {@code LDIFEntryWriter}.
*/
public LDIFChangeRecordWriter setWrapColumn(int wrapColumn)
{
this.wrapColumn = wrapColumn;
return this;
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeChangeRecord(AddRequest change)
throws IOException, NullPointerException
{
Validator.ensureNotNull(change);
// Skip if branch containing the entry is excluded.
if (isBranchExcluded(change.getName()))
{
return this;
}
writeKeyAndValue("dn", change.getName().toString());
writeControls(change.getControls());
writeLine("changetype: add");
for (final Attribute attribute : change.getAttributes())
{
// Filter the attribute if required.
if (isAttributeExcluded(attribute.getAttributeDescription()))
{
continue;
}
final String attributeDescription =
attribute.getAttributeDescriptionAsString();
for (final ByteString value : attribute)
{
writeKeyAndValue(attributeDescription, value);
}
}
// Make sure there is a blank line after the entry.
impl.println();
return this;
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeChangeRecord(ChangeRecord change)
throws IOException, NullPointerException
{
Validator.ensureNotNull(change);
// Skip if branch containing the entry is excluded.
if (isBranchExcluded(change.getName()))
{
return this;
}
final IOException e =
change.accept(ChangeRecordVisitorWriter.getInstance(), this);
if (e != null)
{
throw e;
}
else
{
return this;
}
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeChangeRecord(DeleteRequest change)
throws IOException, NullPointerException
{
Validator.ensureNotNull(change);
// Skip if branch containing the entry is excluded.
if (isBranchExcluded(change.getName()))
{
return this;
}
writeKeyAndValue("dn", change.getName().toString());
writeControls(change.getControls());
writeLine("changetype: delete");
// Make sure there is a blank line after the entry.
impl.println();
return this;
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeChangeRecord(ModifyDNRequest change)
throws IOException, NullPointerException
{
Validator.ensureNotNull(change);
// Skip if branch containing the entry is excluded.
if (isBranchExcluded(change.getName()))
{
return this;
}
writeKeyAndValue("dn", change.getName().toString());
writeControls(change.getControls());
// 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.
if (change.getNewSuperior() == null)
{
writeLine("changetype: modrdn");
}
else
{
writeLine("changetype: moddn");
}
writeKeyAndValue("newrdn", change.getNewRDN().toString());
writeKeyAndValue("deleteoldrdn", change.isDeleteOldRDN() ? "1"
: "0");
if (change.getNewSuperior() != null)
{
writeKeyAndValue("newsuperior", change.getNewSuperior()
.toString());
}
// Make sure there is a blank line after the entry.
impl.println();
return this;
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeChangeRecord(ModifyRequest change)
throws IOException, NullPointerException
{
Validator.ensureNotNull(change);
// If there aren't any modifications, then there's nothing to do.
if (!change.hasChanges())
{
return this;
}
// Skip if branch containing the entry is excluded.
if (isBranchExcluded(change.getName()))
{
return this;
}
writeKeyAndValue("dn", change.getName().toString());
writeControls(change.getControls());
writeLine("changetype: modify");
for (final Change modification : change.getChanges())
{
final ModificationType type = modification.getModificationType();
final Attribute attribute = modification.getAttribute();
final String attributeDescription =
attribute.getAttributeDescriptionAsString();
// Filter the attribute if required.
if (isAttributeExcluded(attribute.getAttributeDescription()))
{
continue;
}
writeKeyAndValue(type.toString(), attributeDescription);
for (final ByteString value : attribute)
{
writeKeyAndValue(attributeDescription, value);
}
writeLine("-");
}
// Make sure there is a blank line after the entry.
impl.println();
return this;
}
/**
* {@inheritDoc}
*/
public LDIFChangeRecordWriter writeComment(CharSequence comment)
throws IOException, NullPointerException
{
writeComment0(comment);
return this;
}
}