001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.name;
021
022 import java.io.IOException;
023 import java.io.ObjectInput;
024 import java.io.ObjectOutput;
025
026 import org.apache.directory.shared.ldap.util.StringTools;
027 import org.slf4j.Logger;
028 import org.slf4j.LoggerFactory;
029
030 /**
031 * A helper class which serialize and deserialize a DN
032 *
033 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
034 * @version $Rev$, $Date$
035 */
036 public class LdapDNSerializer
037 {
038 /** The LoggerFactory used by this class */
039 protected static final Logger LOG = LoggerFactory.getLogger( LdapDNSerializer.class );
040
041 /**
042 * Serialize a DN
043 *
044 * We have to store a DN data efficiently. Here is the structure :
045 *
046 * <li>upName</li> The User provided DN<p>
047 * <li>normName</li> May be null if the normName is equivalent to
048 * the upName<p>
049 * <li>rdns</li> The rdn's List.<p>
050 *
051 * for each rdn :
052 * <li>call the RDN write method</li>
053 *
054 * @param dn The DN to serialize
055 * @param out the stream in which the DN will be serialized
056 * @throws IOException If we can't write in this stream
057 */
058 public static void serialize( LdapDN dn, ObjectOutput out ) throws IOException
059 {
060 if ( dn.getUpName() == null )
061 {
062 String message = "Cannot serialize a NULL DN";
063 LOG.error( message );
064 throw new IOException( message );
065 }
066
067 // Write the UPName
068 out.writeUTF( dn.getUpName() );
069
070 // Write the NormName if different
071 if ( dn.isNormalized() )
072 {
073 if ( dn.getUpName().equals( dn.getNormName() ) )
074 {
075 out.writeUTF( "" );
076 }
077 else
078 {
079 out.writeUTF( dn.getNormName() );
080 }
081 }
082 else
083 {
084 String message = "The DN should have been normalized before being serialized " + dn;
085 LOG.error( message );
086 throw new IOException( message );
087 }
088
089 // Should we store the byte[] ???
090
091 // Write the RDNs.
092 // First the number of RDNs
093 out.writeInt( dn.size() );
094
095 // Loop on the RDNs
096 for ( Rdn rdn:dn.getRdns() )
097 {
098 RdnSerializer.serialize( rdn, out );
099 }
100 }
101
102
103 /**
104 * Deserialize a DN
105 *
106 * We read back the data to create a new LdapDN. The structure
107 * read is exposed in the {@link LdapDNSerializer#serialize(LdapDN, ObjectOutput)}
108 * method<p>
109 *
110 * @param in The input stream from which the DN is read
111 * @return a deserialized DN
112 * @throws IOException If the stream can't be read
113 */
114 public static LdapDN deserialize( ObjectInput in ) throws IOException
115 {
116 // Read the UPName
117 String upName = in.readUTF();
118
119 // Read the NormName
120 String normName = in.readUTF();
121
122 if ( normName.length() == 0 )
123 {
124 // As the normName is equal to the upName,
125 // we didn't saved the nbnormName on disk.
126 // restore it by copying the upName.
127 normName = upName;
128 }
129
130 // Should we read the byte[] ???
131 byte[] bytes = StringTools.getBytesUtf8( upName );
132
133 // Read the RDNs. Is it's null, the number will be -1.
134 int nbRdns = in.readInt();
135
136 LdapDN dn = new LdapDN( upName, normName, bytes );
137
138 for ( int i = 0; i < nbRdns; i++ )
139 {
140 Rdn rdn = RdnSerializer.deserialize( in );
141 dn.add( 0, rdn );
142 }
143
144 return dn;
145 }
146 }