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.i18n.I18n;
027 import org.apache.directory.shared.ldap.util.StringTools;
028 import org.slf4j.Logger;
029 import org.slf4j.LoggerFactory;
030
031 /**
032 * A helper class which serialize and deserialize a DN
033 *
034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
035 * @version $Rev$, $Date$
036 */
037 public class DnSerializer
038 {
039 /** The LoggerFactory used by this class */
040 protected static final Logger LOG = LoggerFactory.getLogger( DnSerializer.class );
041
042 /**
043 * Serialize a DN
044 *
045 * We have to store a DN data efficiently. Here is the structure :
046 *
047 * <li>upName</li> The User provided DN<p>
048 * <li>normName</li> May be null if the normName is equivalent to
049 * the upName<p>
050 * <li>rdns</li> The rdn's List.<p>
051 *
052 * for each rdn :
053 * <li>call the RDN write method</li>
054 *
055 * @param dn The DN to serialize
056 * @param out the stream in which the DN will be serialized
057 * @throws IOException If we can't write in this stream
058 */
059 public static void serialize( DN dn, ObjectOutput out ) throws IOException
060 {
061 if ( dn.getName() == null )
062 {
063 String message = "Cannot serialize a NULL DN";
064 LOG.error( message );
065 throw new IOException( message );
066 }
067
068 // Write the UPName
069 out.writeUTF( dn.getName() );
070
071 // Write the NormName if different
072 if ( dn.isNormalized() )
073 {
074 if ( dn.getName().equals( dn.getNormName() ) )
075 {
076 out.writeUTF( "" );
077 }
078 else
079 {
080 out.writeUTF( dn.getNormName() );
081 }
082 }
083 else
084 {
085 String message = I18n.err( I18n.ERR_04212, dn );
086 LOG.error( message );
087 throw new IOException( message );
088 }
089
090 // Should we store the byte[] ???
091
092 // Write the RDNs.
093 // First the number of RDNs
094 out.writeInt( dn.size() );
095
096 // Loop on the RDNs
097 for ( RDN rdn:dn.getRdns() )
098 {
099 RdnSerializer.serialize( rdn, out );
100 }
101 }
102
103
104 /**
105 * Deserialize a DN
106 *
107 * We read back the data to create a new DN. The structure
108 * read is exposed in the {@link DnSerializer#serialize(DN, ObjectOutput)}
109 * method<p>
110 *
111 * @param in The input stream from which the DN is read
112 * @return a deserialized DN
113 * @throws IOException If the stream can't be read
114 */
115 public static DN deserialize( ObjectInput in ) throws IOException
116 {
117 // Read the UPName
118 String upName = in.readUTF();
119
120 // Read the NormName
121 String normName = in.readUTF();
122
123 if ( normName.length() == 0 )
124 {
125 // As the normName is equal to the upName,
126 // we didn't saved the nbnormName on disk.
127 // restore it by copying the upName.
128 normName = upName;
129 }
130
131 // Should we read the byte[] ???
132 byte[] bytes = StringTools.getBytesUtf8( upName );
133
134 // Read the RDNs. Is it's null, the number will be -1.
135 int nbRdns = in.readInt();
136
137 DN dn = new DN( upName, normName, bytes );
138
139 for ( int i = 0; i < nbRdns; i++ )
140 {
141 RDN rdn = RdnSerializer.deserialize( in );
142 dn.add( 0, rdn );
143 }
144
145 return dn;
146 }
147 }