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.codec.search; 021 022 023 import java.nio.BufferOverflowException; 024 import java.nio.ByteBuffer; 025 import java.util.ArrayList; 026 import java.util.List; 027 028 import org.apache.directory.shared.asn1.ber.tlv.TLV; 029 import org.apache.directory.shared.asn1.ber.tlv.Value; 030 import org.apache.directory.shared.asn1.codec.EncoderException; 031 import org.apache.directory.shared.i18n.I18n; 032 import org.apache.directory.shared.ldap.codec.LdapConstants; 033 import org.apache.directory.shared.ldap.codec.LdapMessageCodec; 034 import org.apache.directory.shared.ldap.codec.MessageTypeEnum; 035 import org.apache.directory.shared.ldap.util.LdapURL; 036 037 038 /** 039 * A SearchResultReference Message. Its syntax is : 040 * 041 * SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL 042 * 043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 044 * @version $Rev: 912399 $, $Date: 2010-02-21 21:52:31 +0100 (Sun, 21 Feb 2010) $, 045 */ 046 public class SearchResultReferenceCodec extends LdapMessageCodec 047 { 048 // ~ Instance fields 049 // ---------------------------------------------------------------------------- 050 051 /** The set of LdapURLs */ 052 private List<LdapURL> searchResultReferences = new ArrayList<LdapURL>(); 053 054 /** The search result reference length */ 055 private int searchResultReferenceLength; 056 057 058 // ~ Constructors 059 // ------------------------------------------------------------------------------- 060 061 /** 062 * Creates a new SearchResultEntry object. 063 */ 064 public SearchResultReferenceCodec() 065 { 066 super(); 067 } 068 069 070 // ~ Methods 071 // ------------------------------------------------------------------------------------ 072 073 /** 074 * Get the message type 075 * 076 * @return Returns the type. 077 */ 078 public MessageTypeEnum getMessageType() 079 { 080 return MessageTypeEnum.SEARCH_RESULT_REFERENCE; 081 } 082 083 084 /** 085 * {@inheritDoc} 086 */ 087 public String getMessageTypeName() 088 { 089 return "SEARCH_RESULT_REFERENCE"; 090 } 091 092 093 /** 094 * Add a new reference to the list. 095 * 096 * @param searchResultReference The search result reference 097 */ 098 public void addSearchResultReference( LdapURL searchResultReference ) 099 { 100 searchResultReferences.add( searchResultReference ); 101 } 102 103 104 /** 105 * Get the list of references 106 * 107 * @return An ArrayList of SearchResultReferences 108 */ 109 public List<LdapURL> getSearchResultReferences() 110 { 111 return searchResultReferences; 112 } 113 114 115 /** 116 * Compute the SearchResultReference length 117 * 118 * SearchResultReference : 119 * <pre> 120 * 0x73 L1 121 * | 122 * +--> 0x04 L2 reference 123 * +--> 0x04 L3 reference 124 * +--> ... 125 * +--> 0x04 Li reference 126 * +--> ... 127 * +--> 0x04 Ln reference 128 * 129 * L1 = n*Length(0x04) + sum(Length(Li)) + sum(Length(reference[i])) 130 * 131 * Length(SearchResultReference) = Length(0x73 + Length(L1) + L1 132 * </pre> 133 */ 134 protected int computeLengthProtocolOp() 135 { 136 searchResultReferenceLength = 0; 137 138 // We may have more than one reference. 139 for ( LdapURL url:searchResultReferences ) 140 { 141 int ldapUrlLength = url.getNbBytes(); 142 searchResultReferenceLength += 1 + TLV.getNbBytes( ldapUrlLength ) + ldapUrlLength; 143 } 144 145 return 1 + TLV.getNbBytes( searchResultReferenceLength ) + searchResultReferenceLength; 146 } 147 148 149 /** 150 * Encode the SearchResultReference message to a PDU. 151 * 152 * SearchResultReference : 153 * <pre> 154 * 0x73 LL 155 * 0x04 LL reference 156 * [0x04 LL reference]* 157 * </pre> 158 * @param buffer The buffer where to put the PDU 159 * @return The PDU. 160 */ 161 protected void encodeProtocolOp( ByteBuffer buffer ) throws EncoderException 162 { 163 try 164 { 165 // The SearchResultReference Tag 166 buffer.put( LdapConstants.SEARCH_RESULT_REFERENCE_TAG ); 167 buffer.put( TLV.getBytes( searchResultReferenceLength ) ); 168 169 // The references. We must at least have one reference 170 for ( LdapURL reference:searchResultReferences ) 171 { 172 // Encode the reference 173 Value.encode( buffer, reference.getString() ); 174 } 175 } 176 catch ( BufferOverflowException boe ) 177 { 178 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 179 } 180 } 181 182 183 /** 184 * Returns the Search Result Reference string 185 * 186 * @return The Search Result Reference string 187 */ 188 public String toString() 189 { 190 191 StringBuffer sb = new StringBuffer(); 192 193 sb.append( " Search Result Reference\n" ); 194 195 if ( ( searchResultReferences == null ) || ( searchResultReferences.size() == 0 ) ) 196 { 197 sb.append( " No Reference\n" ); 198 } 199 else 200 { 201 sb.append( " References\n" ); 202 203 for ( LdapURL url:searchResultReferences ) 204 { 205 sb.append( " '" ).append( url ).append( 206 "'\n" ); 207 } 208 } 209 210 return sb.toString(); 211 } 212 }