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.entry.BinaryValue; 027 import org.apache.directory.shared.ldap.entry.StringValue; 028 import org.apache.directory.shared.ldap.entry.Value; 029 import org.apache.directory.shared.ldap.exception.LdapInvalidDnException; 030 import org.apache.directory.shared.ldap.util.StringTools; 031 import org.slf4j.Logger; 032 import org.slf4j.LoggerFactory; 033 034 /** 035 * A helper class which serialize and deserialize an AttributeTypeAndValue 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 * @version $Rev$, $Date$ 039 */ 040 public class AVASerializer 041 { 042 /** The LoggerFactory used by this class */ 043 protected static final Logger LOG = LoggerFactory.getLogger( AVASerializer.class ); 044 045 /** 046 * Serialize an AttributeTypeAndValue object. 047 * 048 * An AttributeTypeAndValue is composed of a type and a value. 049 * The data are stored following the structure : 050 * 051 * <li>upName</li> The User provided ATAV 052 * <li>start</li> The position of this ATAV in the DN 053 * <li>length</li> The ATAV length 054 * <li>upType</li> The user Provided Type 055 * <li>normType</li> The normalized AttributeType 056 * <li>isHR<li> Tells if the value is a String or not 057 * <p> 058 * if the value is a String : 059 * <li>upValue</li> The User Provided value. 060 * <li>value</li> The normalized value. 061 * <p> 062 * if the value is binary : 063 * <li>upValueLength</li> 064 * <li>upValue</li> The User Provided value. 065 * <li>valueLength</li> 066 * <li>value</li> The normalized value. 067 * 068 * @param atav the AttributeTypeAndValue to serialize 069 * @param out the OutputStream in which the atav will be serialized 070 * @throws IOException If we can't serialize the atav 071 */ 072 public static void serialize( AVA atav, ObjectOutput out ) throws IOException 073 { 074 if ( StringTools.isEmpty( atav.getUpName() ) || 075 StringTools.isEmpty( atav.getUpType() ) || 076 StringTools.isEmpty( atav.getNormType() ) || 077 ( atav.getStart() < 0 ) || 078 ( atav.getLength() < 2 ) || // At least a type and '=' 079 ( atav.getUpValue().isNull() ) || 080 ( atav.getNormValue().isNull() ) ) 081 { 082 String message = "Cannot serialize an wrong ATAV, "; 083 084 if ( StringTools.isEmpty( atav.getUpName() ) ) 085 { 086 message += "the upName should not be null or empty"; 087 } 088 else if ( StringTools.isEmpty( atav.getUpType() ) ) 089 { 090 message += "the upType should not be null or empty"; 091 } 092 else if ( StringTools.isEmpty( atav.getNormType() ) ) 093 { 094 message += "the normType should not be null or empty"; 095 } 096 else if ( atav.getStart() < 0 ) 097 { 098 message += "the start should not be < 0"; 099 } 100 else if ( atav.getLength() < 2 ) 101 { 102 message += "the length should not be < 2"; 103 } 104 else if ( atav.getUpValue().isNull() ) 105 { 106 message += "the upValue should not be null"; 107 } 108 else if ( atav.getNormValue().isNull() ) 109 { 110 message += "the value should not be null"; 111 } 112 113 LOG.error( message ); 114 throw new IOException( message ); 115 } 116 117 out.writeUTF( atav.getUpName() ); 118 out.writeInt( atav.getStart() ); 119 out.writeInt( atav.getLength() ); 120 out.writeUTF( atav.getUpType() ); 121 out.writeUTF( atav.getNormType() ); 122 123 boolean isHR = !atav.getNormValue().isBinary(); 124 125 out.writeBoolean( isHR ); 126 127 if ( isHR ) 128 { 129 out.writeUTF( atav.getUpValue().getString() ); 130 out.writeUTF( atav.getNormValue().getString() ); 131 } 132 else 133 { 134 out.writeInt( atav.getUpValue().length() ); 135 out.write( atav.getUpValue().getBytes() ); 136 out.writeInt( atav.getNormValue().length() ); 137 out.write( atav.getNormValue().getBytes() ); 138 } 139 } 140 141 142 /** 143 * Deserialize an AttributeTypeAndValue object 144 * 145 * We read back the data to create a new ATAV. The structure 146 * read is exposed in the {@link AVA#writeExternal(ObjectOutput)} 147 * method<p> 148 * 149 * @param in the input stream 150 * @throws IOException If the input stream can't be read 151 * @return The constructed AttributeTypeAndValue 152 */ 153 public static AVA deserialize( ObjectInput in ) throws IOException 154 { 155 String upName = in.readUTF(); 156 int start = in.readInt(); 157 int length = in.readInt(); 158 String upType = in.readUTF(); 159 String normType = in.readUTF(); 160 161 boolean isHR = in.readBoolean(); 162 163 try 164 { 165 if ( isHR ) 166 { 167 Value<String> upValue = new StringValue( in.readUTF() ); 168 Value<String> normValue = new StringValue( in.readUTF() ); 169 170 AVA atav = 171 new AVA( upType, normType, upValue, normValue, upName ); 172 173 return atav; 174 } 175 else 176 { 177 int upValueLength = in.readInt(); 178 byte[] upValue = new byte[upValueLength]; 179 in.readFully( upValue ); 180 181 int valueLength = in.readInt(); 182 byte[] normValue = new byte[valueLength]; 183 in.readFully( normValue ); 184 185 AVA atav = 186 new AVA( upType, normType, 187 new BinaryValue( upValue) , 188 new BinaryValue( normValue ), upName ); 189 190 return atav; 191 } 192 } 193 catch ( LdapInvalidDnException ine ) 194 { 195 throw new IOException( ine.getMessage() ); 196 } 197 } 198 }