You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2010/01/26 23:43:29 UTC
svn commit: r903465 [1/5] - in /directory/shared/trunk/ldap-ldif: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/directory/
src/main/java/org/apache/directory/shared/ src/main/java/org/apache/dire...
Author: elecharny
Date: Tue Jan 26 22:43:27 2010
New Revision: 903465
URL: http://svn.apache.org/viewvc?rev=903465&view=rev
Log:
Moved the LDIF part from shared-ldap
Added:
directory/shared/trunk/ldap-ldif/ (with props)
directory/shared/trunk/ldap-ldif/pom.xml
directory/shared/trunk/ldap-ldif/src/
directory/shared/trunk/ldap-ldif/src/main/
directory/shared/trunk/ldap-ldif/src/main/java/
directory/shared/trunk/ldap-ldif/src/main/java/org/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java (with props)
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifControl.java
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifEntry.java
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifReader.java
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifRevertor.java
directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifUtils.java
directory/shared/trunk/ldap-ldif/src/test/
directory/shared/trunk/ldap-ldif/src/test/java/
directory/shared/trunk/ldap-ldif/src/test/java/org/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReaderTest.java
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifReaderTest.java
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifRevertorTest.java
directory/shared/trunk/ldap-ldif/src/test/java/org/apache/directory/shared/ldap/ldif/LdifUtilsTest.java
directory/shared/trunk/ldap-ldif/src/test/resources/
directory/shared/trunk/ldap-ldif/src/test/resources/log4j.properties
Propchange: directory/shared/trunk/ldap-ldif/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jan 26 22:43:27 2010
@@ -0,0 +1,5 @@
+target
+.classpath
+.project
+.settings
+.buildpath
Added: directory/shared/trunk/ldap-ldif/pom.xml
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/pom.xml?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/pom.xml (added)
+++ directory/shared/trunk/ldap-ldif/pom.xml Tue Jan 26 22:43:27 2010
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-parent</artifactId>
+ <version>0.9.18-SNAPSHOT</version>
+ </parent>
+ <artifactId>shared-ldif</artifactId>
+ <name>Apache Directory Shared LDIF</name>
+ <inceptionYear>2010</inceptionYear>
+
+ <issueManagement>
+ <system>jira</system>
+ <url>http://issues.apache.org/jira/browse/DIRSHARED</url>
+ </issueManagement>
+
+ <description>
+ Common LDIF packages used by clients and servers.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+
+ <dependency>
+ <artifactId>shared-asn1</artifactId>
+ <groupId>${groupId}</groupId>
+ <version>${version}</version>
+ </dependency>
+
+ <dependency>
+ <artifactId>shared-ldap</artifactId>
+ <groupId>${groupId}</groupId>
+ <version>${version}</version>
+ </dependency>
+
+ <dependency>
+ <artifactId>shared-ldap-constants</artifactId>
+ <groupId>${groupId}</groupId>
+ <version>${version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <configuration />
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/Abstract*</exclude>
+ <exclude>**/*RegressionTest*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
Added: directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java (added)
+++ directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java Tue Jan 26 22:43:27 2010
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.shared.ldap.ldif;
+
+
+/**
+ * A type safe enumeration for an LDIF record's change type.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public enum ChangeType
+{
+ Add( 0 ),
+ Modify( 1 ),
+ ModDn( 2 ),
+ ModRdn( 3 ),
+ Delete( 4 );
+
+ /** Add ordinal value */
+ public static final int ADD_ORDINAL = 0;
+
+ /** Modify ordinal value */
+ public static final int MODIFY_ORDINAL = 1;
+
+ /** ModDN ordinal value */
+ public static final int MODDN_ORDINAL = 2;
+
+ /** ModRDN ordinal value */
+ public static final int MODRDN_ORDINAL = 3;
+
+ /** Delete ordinal value */
+ public static final int DELETE_ORDINAL = 4;
+
+ /* the ordinal value for a change type */
+ private final int changeType;
+
+
+ /**
+ * Creates a new instance of ChangeType.
+ *
+ * @param changeType
+ */
+ private ChangeType( int changeType )
+ {
+ this.changeType = changeType;
+ }
+
+
+ /**
+ * Get's the ordinal value for a ChangeType.
+ *
+ * @return the changeType
+ */
+ public int getChangeType()
+ {
+ return changeType;
+ }
+
+ public static ChangeType getChangeType( int val )
+ {
+ switch( val )
+ {
+ case 0: return Add;
+
+ case 1: return Modify;
+
+ case 2: return ModDn;
+
+ case 3: return ModRdn;
+
+ case 4: return Delete;
+
+ default:
+ throw new IllegalArgumentException( "Unknown change type value " + val );
+ }
+ }
+}
Propchange: directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/ChangeType.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java (added)
+++ directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifAttributesReader.java Tue Jan 26 22:43:27 2010
@@ -0,0 +1,310 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.shared.ldap.ldif;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <pre>
+ * <ldif-file> ::= "version:" <fill> <number> <seps> <dn-spec> <sep>
+ * <ldif-content-change>
+ *
+ * <ldif-content-change> ::=
+ * <number> <oid> <options-e> <value-spec> <sep> <attrval-specs-e>
+ * <ldif-attrval-record-e> |
+ * <alpha> <chars-e> <options-e> <value-spec> <sep> <attrval-specs-e>
+ * <ldif-attrval-record-e> |
+ * "control:" <fill> <number> <oid> <spaces-e> <criticality>
+ * <value-spec-e> <sep> <controls-e>
+ * "changetype:" <fill> <changerecord-type> <ldif-change-record-e> |
+ * "changetype:" <fill> <changerecord-type> <ldif-change-record-e>
+ *
+ * <ldif-attrval-record-e> ::= <seps> <dn-spec> <sep> <attributeType>
+ * <options-e> <value-spec> <sep> <attrval-specs-e>
+ * <ldif-attrval-record-e> | e
+ *
+ * <ldif-change-record-e> ::= <seps> <dn-spec> <sep> <controls-e>
+ * "changetype:" <fill> <changerecord-type> <ldif-change-record-e> | e
+ *
+ * <dn-spec> ::= "dn:" <fill> <safe-string> | "dn::" <fill> <base64-string>
+ *
+ * <controls-e> ::= "control:" <fill> <number> <oid> <spaces-e> <criticality>
+ * <value-spec-e> <sep> <controls-e> | e
+ *
+ * <criticality> ::= "true" | "false" | e
+ *
+ * <oid> ::= '.' <number> <oid> | e
+ *
+ * <attrval-specs-e> ::= <number> <oid> <options-e> <value-spec> <sep>
+ * <attrval-specs-e> |
+ * <alpha> <chars-e> <options-e> <value-spec> <sep> <attrval-specs-e> | e
+ *
+ * <value-spec-e> ::= <value-spec> | e
+ *
+ * <value-spec> ::= ':' <fill> <safe-string-e> |
+ * "::" <fill> <base64-chars> |
+ * ":<" <fill> <url>
+ *
+ * <attributeType> ::= <number> <oid> | <alpha> <chars-e>
+ *
+ * <options-e> ::= ';' <char> <chars-e> <options-e> |e
+ *
+ * <chars-e> ::= <char> <chars-e> | e
+ *
+ * <changerecord-type> ::= "add" <sep> <attributeType> <options-e> <value-spec>
+ * <sep> <attrval-specs-e> |
+ * "delete" <sep> |
+ * "modify" <sep> <mod-type> <fill> <attributeType> <options-e> <sep>
+ * <attrval-specs-e> <sep> '-' <sep> <mod-specs-e> |
+ * "moddn" <sep> <newrdn> <sep> "deleteoldrdn:" <fill> <0-1> <sep>
+ * <newsuperior-e> <sep> |
+ * "modrdn" <sep> <newrdn> <sep> "deleteoldrdn:" <fill> <0-1> <sep>
+ * <newsuperior-e> <sep>
+ *
+ * <newrdn> ::= ':' <fill> <safe-string> | "::" <fill> <base64-chars>
+ *
+ * <newsuperior-e> ::= "newsuperior" <newrdn> | e
+ *
+ * <mod-specs-e> ::= <mod-type> <fill> <attributeType> <options-e>
+ * <sep> <attrval-specs-e> <sep> '-' <sep> <mod-specs-e> | e
+ *
+ * <mod-type> ::= "add:" | "delete:" | "replace:"
+ *
+ * <url> ::= <a Uniform Resource Locator, as defined in [6]>
+ *
+ *
+ *
+ * LEXICAL
+ * -------
+ *
+ * <fill> ::= ' ' <fill> | e
+ * <char> ::= <alpha> | <digit> | '-'
+ * <number> ::= <digit> <digits>
+ * <0-1> ::= '0' | '1'
+ * <digits> ::= <digit> <digits> | e
+ * <digit> ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+ * <seps> ::= <sep> <seps-e>
+ * <seps-e> ::= <sep> <seps-e> | e
+ * <sep> ::= 0x0D 0x0A | 0x0A
+ * <spaces> ::= ' ' <spaces-e>
+ * <spaces-e> ::= ' ' <spaces-e> | e
+ * <safe-string-e> ::= <safe-string> | e
+ * <safe-string> ::= <safe-init-char> <safe-chars>
+ * <safe-init-char> ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x1F] | [0x21-0x39] | 0x3B | [0x3D-0x7F]
+ * <safe-chars> ::= <safe-char> <safe-chars> | e
+ * <safe-char> ::= [0x01-0x09] | 0x0B | 0x0C | [0x0E-0x7F]
+ * <base64-string> ::= <base64-char> <base64-chars>
+ * <base64-chars> ::= <base64-char> <base64-chars> | e
+ * <base64-char> ::= 0x2B | 0x2F | [0x30-0x39] | 0x3D | [0x41-9x5A] | [0x61-0x7A]
+ * <alpha> ::= [0x41-0x5A] | [0x61-0x7A]
+ *
+ * COMMENTS
+ * --------
+ * - The ldap-oid VN is not correct in the RFC-2849. It has been changed from 1*DIGIT 0*1("." 1*DIGIT) to
+ * DIGIT+ ("." DIGIT+)*
+ * - The mod-spec lacks a sep between *attrval-spec and "-".
+ * - The BASE64-UTF8-STRING should be BASE64-CHAR BASE64-STRING
+ * - The ValueSpec rule must accept multilines values. In this case, we have a LF followed by a
+ * single space before the continued value.
+ * </pre>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdifAttributesReader extends LdifReader
+{
+ /** A logger */
+ private static final Logger LOG = LoggerFactory.getLogger( LdifAttributesReader.class );
+
+ /**
+ * Constructors
+ */
+ public LdifAttributesReader()
+ {
+ lines = new ArrayList<String>();
+ position = new Position();
+ version = DEFAULT_VERSION;
+ }
+
+
+ /**
+ * Parse an AttributeType/AttributeValue
+ *
+ * @param attributes The entry where to store the value
+ * @param line The line to parse
+ * @param lowerLine The same line, lowercased
+ * @throws NamingException If anything goes wrong
+ */
+ private void parseAttribute( Attributes attributes, String line, String lowerLine ) throws NamingException
+ {
+ int colonIndex = line.indexOf( ':' );
+
+ String attributeType = lowerLine.substring( 0, colonIndex );
+
+ // We should *not* have a DN twice
+ if ( attributeType.equals( "dn" ) )
+ {
+ LOG.error( "An entry must not have two DNs" );
+ throw new NamingException( "A ldif entry should not have two DNs" );
+ }
+
+ Object attributeValue = parseValue( line, colonIndex );
+
+ // Update the entry
+ Attribute attribute = attributes.get( attributeType );
+
+ if ( attribute == null )
+ {
+ attributes.put( attributeType, attributeValue );
+ }
+ else
+ {
+ attribute.add( attributeValue );
+ }
+ }
+
+ /**
+ * Parse a ldif file. The following rules are processed :
+ *
+ * <ldif-file> ::= <ldif-attrval-record> <ldif-attrval-records> |
+ * <ldif-change-record> <ldif-change-records> <ldif-attrval-record> ::=
+ * <dn-spec> <sep> <attrval-spec> <attrval-specs> <ldif-change-record> ::=
+ * <dn-spec> <sep> <controls-e> <changerecord> <dn-spec> ::= "dn:" <fill>
+ * <distinguishedName> | "dn::" <fill> <base64-distinguishedName>
+ * <changerecord> ::= "changetype:" <fill> <change-op>
+ *
+ * @return The read entry
+ * @throws NamingException If the entry can't be read or is invalid
+ */
+ private Attributes parseAttributes() throws NamingException
+ {
+ if ( ( lines == null ) || ( lines.size() == 0 ) )
+ {
+ LOG.debug( "The entry is empty : end of ldif file" );
+ return null;
+ }
+
+ Attributes attributes = new BasicAttributes( true );
+
+ // Now, let's iterate through the other lines
+ for ( String line:lines )
+ {
+ // Each line could start either with an OID, an attribute type, with
+ // "control:" or with "changetype:"
+ String lowerLine = line.toLowerCase();
+
+ // We have three cases :
+ // 1) The first line after the DN is a "control:" -> this is an error
+ // 2) The first line after the DN is a "changeType:" -> this is an error
+ // 3) The first line after the DN is anything else
+ if ( lowerLine.startsWith( "control:" ) )
+ {
+ LOG.error( "We cannot have changes when reading a file which already contains entries" );
+ throw new NamingException( "No changes withing entries" );
+ }
+ else if ( lowerLine.startsWith( "changetype:" ) )
+ {
+ LOG.error( "We cannot have changes when reading a file which already contains entries" );
+ throw new NamingException( "No changes withing entries" );
+ }
+ else if ( line.indexOf( ':' ) > 0 )
+ {
+ parseAttribute( attributes, line, lowerLine );
+ }
+ else
+ {
+ // Invalid attribute Value
+ LOG.error( "Expecting an attribute type" );
+ throw new NamingException( "Bad attribute" );
+ }
+ }
+
+ LOG.debug( "Read an attributes : {}", attributes );
+
+ return attributes;
+ }
+
+
+ /**
+ * A method which parses a ldif string and returns a list of entries.
+ *
+ * @param ldif The ldif string
+ * @return A list of entries, or an empty List
+ * @throws NamingException
+ * If something went wrong
+ */
+ public Attributes parseAttributes( String ldif ) throws NamingException
+ {
+ lines = new ArrayList<String>();
+ position = new Position();
+
+ LOG.debug( "Starts parsing ldif buffer" );
+
+ if ( StringTools.isEmpty( ldif ) )
+ {
+ return new BasicAttributes( true );
+ }
+
+ StringReader strIn = new StringReader( ldif );
+ reader = new BufferedReader( strIn );
+
+ try
+ {
+ readLines();
+
+ Attributes attributes = parseAttributes();
+
+ if ( LOG.isDebugEnabled() )
+ {
+ LOG.debug( "Parsed {} entries.", ( attributes == null ? 0 : 1 ) );
+ }
+
+ return attributes;
+ }
+ catch (NamingException ne)
+ {
+ LOG.error( "Cannot parse the ldif buffer : {}", ne.getMessage() );
+ throw new NamingException( "Error while parsing the ldif buffer" );
+ }
+ finally
+ {
+ try
+ {
+ reader.close();
+ }
+ catch ( IOException ioe )
+ {
+ // Do nothing
+ }
+ }
+ }
+}
\ No newline at end of file
Added: directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifControl.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifControl.java?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifControl.java (added)
+++ directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifControl.java Tue Jan 26 22:43:27 2010
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.shared.ldap.ldif;
+
+import org.apache.directory.shared.ldap.message.control.AbstractControl;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+/**
+ * The LdifControl class stores a control defined for an entry found in a ldif
+ * file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdifControl extends AbstractControl
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Create a new Control
+ *
+ * @param oid
+ * OID of the created control
+ */
+ public LdifControl( String oid )
+ {
+ super( oid );
+ }
+
+ public String toString()
+ {
+ return "LdifControl : {" + getOid() + ", " + isCritical() + ", " + StringTools.dumpBytes( getValue() ) + "}";
+ }
+}
Added: directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifEntry.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifEntry.java?rev=903465&view=auto
==============================================================================
--- directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifEntry.java (added)
+++ directory/shared/trunk/ldap-ldif/src/main/java/org/apache/directory/shared/ldap/ldif/LdifEntry.java Tue Jan 26 22:43:27 2010
@@ -0,0 +1,1061 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.shared.ldap.ldif;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NamingException;
+
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.ModificationOperation;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.entry.client.ClientEntry;
+import org.apache.directory.shared.ldap.entry.client.ClientModification;
+import org.apache.directory.shared.ldap.entry.client.ClientStringValue;
+import org.apache.directory.shared.ldap.entry.client.DefaultClientAttribute;
+import org.apache.directory.shared.ldap.entry.client.DefaultClientEntry;
+import org.apache.directory.shared.ldap.message.control.Control;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.name.RDN;
+import org.apache.directory.shared.ldap.util.StringTools;
+
+
+/**
+ * A entry to be populated by an ldif parser.
+ *
+ * We will have different kind of entries :
+ * - added entries
+ * - deleted entries
+ * - modified entries
+ * - RDN modified entries
+ * - DN modified entries
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdifEntry implements Cloneable, Externalizable
+{
+ private static final long serialVersionUID = 2L;
+
+ /** Used in toArray() */
+ public static final Modification[] EMPTY_MODS = new Modification[0];
+
+ /** the change type */
+ private ChangeType changeType;
+
+ /** the modification item list */
+ private List<Modification> modificationList;
+
+ private Map<String, Modification> modificationItems;
+
+ /** The new superior */
+ private String newSuperior;
+
+ /** The new rdn */
+ private String newRdn;
+
+ /** The delete old rdn flag */
+ private boolean deleteOldRdn;
+
+ /** the entry */
+ private ClientEntry entry;
+
+
+ /** The control */
+ private Control control;
+
+ /**
+ * Creates a new Entry object.
+ */
+ public LdifEntry()
+ {
+ changeType = ChangeType.Add; // Default LDIF content
+ modificationList = new LinkedList<Modification>();
+ modificationItems = new HashMap<String, Modification>();
+ entry = new DefaultClientEntry( null );
+ control = null;
+ }
+
+
+ /**
+ * Set the Distinguished Name
+ *
+ * @param dn
+ * The Distinguished Name
+ */
+ public void setDn( LdapDN dn )
+ {
+ entry.setDn( (LdapDN)dn.clone() );
+ }
+
+
+ /**
+ * Set the Distinguished Name
+ *
+ * @param dn
+ * The Distinguished Name
+ */
+ public void setDn( String dn ) throws InvalidNameException
+ {
+ LdapDN ldapDn = new LdapDN( dn );
+ entry.setDn( ldapDn );
+ }
+
+
+ /**
+ * Set the modification type
+ *
+ * @param changeType
+ * The change type
+ *
+ */
+ public void setChangeType( ChangeType changeType )
+ {
+ this.changeType = changeType;
+ }
+
+ /**
+ * Set the change type
+ *
+ * @param changeType
+ * The change type
+ */
+ public void setChangeType( String changeType )
+ {
+ if ( "add".equals( changeType ) )
+ {
+ this.changeType = ChangeType.Add;
+ }
+ else if ( "modify".equals( changeType ) )
+ {
+ this.changeType = ChangeType.Modify;
+ }
+ else if ( "moddn".equals( changeType ) )
+ {
+ this.changeType = ChangeType.ModDn;
+ }
+ else if ( "modrdn".equals( changeType ) )
+ {
+ this.changeType = ChangeType.ModRdn;
+ }
+ else if ( "delete".equals( changeType ) )
+ {
+ this.changeType = ChangeType.Delete;
+ }
+ }
+
+ /**
+ * Add a modification item (used by modify operations)
+ *
+ * @param modification The modification to be added
+ */
+ public void addModificationItem( Modification modification )
+ {
+ if ( changeType == ChangeType.Modify )
+ {
+ modificationList.add( modification );
+ modificationItems.put( modification.getAttribute().getId(), modification );
+ }
+ }
+
+ /**
+ * Add a modification item (used by modify operations)
+ *
+ * @param modOp The operation. One of :
+ * - ModificationOperation.ADD_ATTRIBUTE
+ * - ModificationOperation.REMOVE_ATTRIBUTE
+ * - ModificationOperation.REPLACE_ATTRIBUTE
+ *
+ * @param attr The attribute to be added
+ */
+ public void addModificationItem( ModificationOperation modOp, EntryAttribute attr )
+ {
+ if ( changeType == ChangeType.Modify )
+ {
+ Modification item = new ClientModification( modOp, attr );
+ modificationList.add( item );
+ modificationItems.put( attr.getId(), item );
+ }
+ }
+
+
+ /**
+ * Add a modification item
+ *
+ * @param modOp The operation. One of :
+ * - ModificationOperation.ADD_ATTRIBUTE
+ * - ModificationOperation.REMOVE_ATTRIBUTE
+ * - ModificationOperation.REPLACE_ATTRIBUTE
+ *
+ * @param modOp The modification operation value
+ * @param id The attribute's ID
+ * @param value The attribute's value
+ */
+ public void addModificationItem( ModificationOperation modOp, String id, Object value )
+ {
+ if ( changeType == ChangeType.Modify )
+ {
+ EntryAttribute attr = null;
+
+ if ( value == null )
+ {
+ value = new ClientStringValue( null );
+ attr = new DefaultClientAttribute( id, (Value<?>)value );
+ }
+ else
+ {
+ attr = (EntryAttribute)value;
+ }
+
+ Modification item = new ClientModification( modOp, attr );
+ modificationList.add( item );
+ modificationItems.put( id, item );
+ }
+ }
+
+
+ /**
+ * Add an attribute to the entry
+ *
+ * @param attr
+ * The attribute to be added
+ */
+ public void addAttribute( EntryAttribute attr ) throws NamingException
+ {
+ entry.put( attr );
+ }
+
+ /**
+ * Add an attribute to the entry
+ *
+ * @param id
+ * The attribute ID
+ *
+ * @param value
+ * The attribute value
+ *
+ */
+ public void addAttribute( String id, Object value ) throws NamingException
+ {
+ if ( value instanceof String )
+ {
+ entry.add( id, (String)value );
+ }
+ else
+ {
+ entry.add( id, (byte[])value );
+ }
+ }
+
+
+ /**
+ * Remove a list of Attributes from the LdifEntry
+ *
+ * @param ids The Attributes to remove
+ * @return The list of removed EntryAttributes
+ */
+ public List<EntryAttribute> removeAttribute( String... ids )
+ {
+ if ( entry.containsAttribute( ids ) )
+ {
+ return entry.removeAttributes( ids );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Add an attribute value to an existing attribute
+ *
+ * @param id
+ * The attribute ID
+ *
+ * @param value
+ * The attribute value
+ *
+ */
+ public void putAttribute( String id, Object value ) throws NamingException
+ {
+ if ( value instanceof String )
+ {
+ entry.add( id, (String)value );
+ }
+ else
+ {
+ entry.add( id, (byte[])value );
+ }
+ }
+
+ /**
+ * Get the change type
+ *
+ * @return The change type. One of : ADD = 0; MODIFY = 1; MODDN = 2; MODRDN =
+ * 3; DELETE = 4;
+ */
+ public ChangeType getChangeType()
+ {
+ return changeType;
+ }
+
+ /**
+ * @return The list of modification items
+ */
+ public List<Modification> getModificationItems()
+ {
+ return modificationList;
+ }
+
+
+ /**
+ * Gets the modification items as an array.
+ *
+ * @return modification items as an array.
+ */
+ public Modification[] getModificationItemsArray()
+ {
+ return modificationList.toArray( EMPTY_MODS );
+ }
+
+
+ /**
+ * @return The entry Distinguished name
+ */
+ public LdapDN getDn()
+ {
+ return entry.getDn();
+ }
+
+ /**
+ * @return The number of entry modifications
+ */
+ public int size()
+ {
+ return modificationList.size();
+ }
+
+ /**
+ * Returns a attribute given it's id
+ *
+ * @param attributeId
+ * The attribute Id
+ * @return The attribute if it exists
+ */
+ public EntryAttribute get( String attributeId )
+ {
+ if ( "dn".equalsIgnoreCase( attributeId ) )
+ {
+ return new DefaultClientAttribute( "dn", entry.getDn().getName() );
+ }
+
+ return entry.get( attributeId );
+ }
+
+ /**
+ * Get the entry's entry
+ *
+ * @return the stored Entry
+ */
+ public Entry getEntry()
+ {
+ if ( isEntry() )
+ {
+ return entry;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return True, if the old RDN should be deleted.
+ */
+ public boolean isDeleteOldRdn()
+ {
+ return deleteOldRdn;
+ }
+
+ /**
+ * Set the flage deleteOldRdn
+ *
+ * @param deleteOldRdn
+ * True if the old RDN should be deleted
+ */
+ public void setDeleteOldRdn( boolean deleteOldRdn )
+ {
+ this.deleteOldRdn = deleteOldRdn;
+ }
+
+ /**
+ * @return The new RDN
+ */
+ public String getNewRdn()
+ {
+ return newRdn;
+ }
+
+ /**
+ * Set the new RDN
+ *
+ * @param newRdn
+ * The new RDN
+ */
+ public void setNewRdn( String newRdn )
+ {
+ this.newRdn = newRdn;
+ }
+
+ /**
+ * @return The new superior
+ */
+ public String getNewSuperior()
+ {
+ return newSuperior;
+ }
+
+ /**
+ * Set the new superior
+ *
+ * @param newSuperior
+ * The new Superior
+ */
+ public void setNewSuperior( String newSuperior )
+ {
+ this.newSuperior = newSuperior;
+ }
+
+ /**
+ * @return True if the entry is an ADD entry
+ */
+ public boolean isChangeAdd()
+ {
+ return changeType == ChangeType.Add;
+ }
+
+ /**
+ * @return True if the entry is a DELETE entry
+ */
+ public boolean isChangeDelete()
+ {
+ return changeType == ChangeType.Delete;
+ }
+
+ /**
+ * @return True if the entry is a MODDN entry
+ */
+ public boolean isChangeModDn()
+ {
+ return changeType == ChangeType.ModDn;
+ }
+
+ /**
+ * @return True if the entry is a MODRDN entry
+ */
+ public boolean isChangeModRdn()
+ {
+ return changeType == ChangeType.ModRdn;
+ }
+
+ /**
+ * @return True if the entry is a MODIFY entry
+ */
+ public boolean isChangeModify()
+ {
+ return changeType == ChangeType.Modify;
+ }
+
+ /**
+ * Tells if the current entry is a added one
+ *
+ * @return <code>true</code> if the entry is added
+ */
+ public boolean isEntry()
+ {
+ return changeType == ChangeType.Add;
+ }
+
+ /**
+ * @return The associated control, if any
+ */
+ public Control getControl()
+ {
+ return control;
+ }
+
+ /**
+ * Add a control to the entry
+ *
+ * @param control
+ * The control
+ */
+ public void setControl( Control control )
+ {
+ this.control = control;
+ }
+
+ /**
+ * Clone method
+ * @return a clone of the current instance
+ * @exception CloneNotSupportedException If there is some problem while cloning the instance
+ */
+ public LdifEntry clone() throws CloneNotSupportedException
+ {
+ LdifEntry clone = (LdifEntry) super.clone();
+
+ if ( modificationList != null )
+ {
+ for ( Modification modif:modificationList )
+ {
+ Modification modifClone = new ClientModification( modif.getOperation(),
+ (EntryAttribute) modif.getAttribute().clone() );
+ clone.modificationList.add( modifClone );
+ }
+ }
+
+ if ( modificationItems != null )
+ {
+ for ( String key:modificationItems.keySet() )
+ {
+ Modification modif = modificationItems.get( key );
+ Modification modifClone = new ClientModification( modif.getOperation(),
+ (EntryAttribute) modif.getAttribute().clone() );
+ clone.modificationItems.put( key, modifClone );
+ }
+
+ }
+
+ if ( entry != null )
+ {
+ clone.entry = (ClientEntry)entry.clone();
+ }
+
+ return clone;
+ }
+
+ /**
+ * Dumps the attributes
+ * @return A String representing the attributes
+ */
+ private String dumpAttributes()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for ( EntryAttribute attribute:entry )
+ {
+ if ( attribute == null )
+ {
+ sb.append( " Null attribute\n" );
+ continue;
+ }
+
+ sb.append( " ").append( attribute.getId() ).append( ":\n" );
+
+ for ( Value<?> value:attribute )
+ {
+ if ( !value.isBinary() )
+ {
+ sb.append( " " ).append( value.getString() ).append('\n' );
+ }
+ else
+ {
+ sb.append( " " ).append( StringTools.dumpBytes( value.getBytes() ) ).append('\n' );
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Dumps the modifications
+ * @return A String representing the modifications
+ */
+ private String dumpModificationItems()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for ( Modification modif:modificationList )
+ {
+ sb.append( " Operation: " );
+
+ switch ( modif.getOperation() )
+ {
+ case ADD_ATTRIBUTE :
+ sb.append( "ADD\n" );
+ break;
+
+ case REMOVE_ATTRIBUTE :
+ sb.append( "REMOVE\n" );
+ break;
+
+ case REPLACE_ATTRIBUTE :
+ sb.append( "REPLACE \n" );
+ break;
+
+ default :
+ break; // Do nothing
+ }
+
+ EntryAttribute attribute = modif.getAttribute();
+
+ sb.append( " Attribute: " ).append( attribute.getId() ).append( '\n' );
+
+ if ( attribute.size() != 0 )
+ {
+ for ( Value<?> value:attribute )
+ {
+ if ( !value.isBinary() )
+ {
+ sb.append( " " ).append( value.getString() ).append('\n' );
+ }
+ else
+ {
+ sb.append( " " ).append( StringTools.dumpBytes( value.getBytes() ) ).append('\n' );
+ }
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+
+ /**
+ * @return a String representing the Entry, as a LDIF
+ */
+ public String toString()
+ {
+ try
+ {
+ return LdifUtils.convertToLdif( this );
+ }
+ catch ( NamingException ne )
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * @see Object#hashCode()
+ *
+ * @return the instance's hash code
+ */
+ public int hashCode()
+ {
+ int result = 37;
+
+ if ( entry.getDn() != null )
+ {
+ result = result*17 + entry.getDn().hashCode();
+ }
+
+ if ( changeType != null )
+ {
+ result = result*17 + changeType.hashCode();
+
+ // Check each different cases
+ switch ( changeType )
+ {
+ case Add :
+ // Checks the attributes
+ if ( entry != null )
+ {
+ result = result * 17 + entry.hashCode();
+ }
+
+ break;
+
+ case Delete :
+ // Nothing to compute
+ break;
+
+ case Modify :
+ if ( modificationList != null )
+ {
+ result = result * 17 + modificationList.hashCode();
+
+ for ( Modification modification:modificationList )
+ {
+ result = result * 17 + modification.hashCode();
+ }
+ }
+
+ break;
+
+ case ModDn :
+ case ModRdn :
+ result = result * 17 + ( deleteOldRdn ? 1 : -1 );
+
+ if ( newRdn != null )
+ {
+ result = result*17 + newRdn.hashCode();
+ }
+
+ if ( newSuperior != null )
+ {
+ result = result*17 + newSuperior.hashCode();
+ }
+
+ break;
+
+ default :
+ break; // do nothing
+ }
+ }
+
+ if ( control != null )
+ {
+ result = result * 17 + control.hashCode();
+ }
+
+ return result;
+ }
+
+ /**
+ * @see Object#equals(Object)
+ * @return <code>true</code> if both values are equal
+ */
+ public boolean equals( Object o )
+ {
+ // Basic equals checks
+ if ( this == o )
+ {
+ return true;
+ }
+
+ if ( o == null )
+ {
+ return false;
+ }
+
+ if ( ! (o instanceof LdifEntry ) )
+ {
+ return false;
+ }
+
+ LdifEntry otherEntry = (LdifEntry)o;
+
+ // Check the DN
+ LdapDN thisDn = entry.getDn();
+ LdapDN dnEntry = otherEntry.getDn();
+
+ if ( !thisDn.equals( dnEntry ) )
+ {
+ return false;
+ }
+
+
+ // Check the changeType
+ if ( changeType != otherEntry.changeType )
+ {
+ return false;
+ }
+
+ // Check each different cases
+ switch ( changeType )
+ {
+ case Add :
+ // Checks the attributes
+ if ( entry == null )
+ {
+ if ( otherEntry.entry != null )
+ {
+ return false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if ( otherEntry.entry == null )
+ {
+ return false;
+ }
+
+ if ( entry.size() != otherEntry.entry.size() )
+ {
+ return false;
+ }
+
+ if ( !entry.equals( otherEntry.entry ) )
+ {
+ return false;
+ }
+
+ break;
+
+ case Delete :
+ // Nothing to do, if the DNs are equals
+ break;
+
+ case Modify :
+ // Check the modificationItems list
+
+ // First, deal with special cases
+ if ( modificationList == null )
+ {
+ if ( otherEntry.modificationList != null )
+ {
+ return false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if ( otherEntry.modificationList == null )
+ {
+ return false;
+ }
+
+ if ( modificationList.size() != otherEntry.modificationList.size() )
+ {
+ return false;
+ }
+
+ // Now, compares the contents
+ int i = 0;
+
+ for ( Modification modification:modificationList )
+ {
+ if ( ! modification.equals( otherEntry.modificationList.get( i ) ) )
+ {
+ return false;
+ }
+
+ i++;
+ }
+
+ break;
+
+ case ModDn :
+ case ModRdn :
+ // Check the deleteOldRdn flag
+ if ( deleteOldRdn != otherEntry.deleteOldRdn )
+ {
+ return false;
+ }
+
+ // Check the newRdn value
+ try
+ {
+ RDN thisNewRdn = new RDN( newRdn );
+ RDN entryNewRdn = new RDN( otherEntry.newRdn );
+
+ if ( !thisNewRdn.equals( entryNewRdn ) )
+ {
+ return false;
+ }
+ }
+ catch ( InvalidNameException ine )
+ {
+ return false;
+ }
+
+ // Check the newSuperior value
+ try
+ {
+ LdapDN thisNewSuperior = new LdapDN( newSuperior );
+ LdapDN entryNewSuperior = new LdapDN( otherEntry.newSuperior );
+
+ if ( ! thisNewSuperior.equals( entryNewSuperior ) )
+ {
+ return false;
+ }
+ }
+ catch ( InvalidNameException ine )
+ {
+ return false;
+ }
+
+ break;
+
+ default :
+ break; // do nothing
+ }
+
+ if ( control != null )
+ {
+ return control.equals( otherEntry.control );
+ }
+ else
+ {
+ return otherEntry.control == null;
+ }
+ }
+
+
+ /**
+ * @see Externalizable#readExternal(ObjectInput)
+ *
+ * @param in The stream from which the LdifEntry is read
+ * @throws IOException If the stream can't be read
+ * @throws ClassNotFoundException If the LdifEntry can't be created
+ */
+ public void readExternal( ObjectInput in ) throws IOException , ClassNotFoundException
+ {
+ // Read the changeType
+ int type = in.readInt();
+ changeType = ChangeType.getChangeType( type );
+ entry = (ClientEntry)in.readObject();
+
+ switch ( changeType )
+ {
+ case Add :
+ // Fallback
+ case Delete :
+ // we don't have anything to read, but the control
+ break;
+
+ case ModDn :
+ // Fallback
+ case ModRdn :
+ deleteOldRdn = in.readBoolean();
+
+ if ( in.readBoolean() )
+ {
+ newRdn = in.readUTF();
+ }
+
+ if ( in.readBoolean() )
+ {
+ newSuperior = in.readUTF();
+ }
+
+ break;
+
+ case Modify :
+ // Read the modification
+ int nbModifs = in.readInt();
+
+
+ for ( int i = 0; i < nbModifs; i++ )
+ {
+ int operation = in.readInt();
+ String modStr = in.readUTF();
+ DefaultClientAttribute value = (DefaultClientAttribute)in.readObject();
+
+ addModificationItem( ModificationOperation.getOperation( operation ), modStr, value );
+ }
+
+ break;
+ }
+
+ if ( in.available() > 0 )
+ {
+ // We have a control
+ control = (Control)in.readObject();
+ }
+ }
+
+
+ /**
+ * @see Externalizable#readExternal(ObjectInput)<p>
+ *
+ *@param out The stream in which the ChangeLogEvent will be serialized.
+ *
+ *@throws IOException If the serialization fail
+ */
+ public void writeExternal( ObjectOutput out ) throws IOException
+ {
+ // Write the changeType
+ out.writeInt( changeType.getChangeType() );
+
+ // Write the entry
+ out.writeObject( entry );
+
+ // Write the data
+ switch ( changeType )
+ {
+ case Add :
+ // Fallback
+ case Delete :
+ // we don't have anything to write, but the control
+ break;
+
+ case ModDn :
+ // Fallback
+ case ModRdn :
+ out.writeBoolean( deleteOldRdn );
+
+ if ( newRdn != null )
+ {
+ out.writeBoolean( true );
+ out.writeUTF( newRdn );
+ }
+ else
+ {
+ out.writeBoolean( false );
+ }
+
+ if ( newSuperior != null )
+ {
+ out.writeBoolean( true );
+ out.writeUTF( newSuperior );
+ }
+ else
+ {
+ out.writeBoolean( false );
+ }
+ break;
+
+ case Modify :
+ // Read the modification
+ out.writeInt( modificationList.size() );
+
+ for ( Modification modification:modificationList )
+ {
+ out.writeInt( modification.getOperation().getValue() );
+ out.writeUTF( modification.getAttribute().getId() );
+
+ EntryAttribute attribute = modification.getAttribute();
+ out.writeObject( attribute );
+ }
+
+ break;
+ }
+
+ if ( control != null )
+ {
+ // Write the control
+ out.writeObject( control );
+
+ }
+
+ // and flush the result
+ out.flush();
+ }
+}