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 * https://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 */ 020package org.apache.directory.api.ldap.codec.factory; 021 022import java.util.Iterator; 023 024import org.apache.directory.api.asn1.ber.tlv.BerValue; 025import org.apache.directory.api.asn1.util.Asn1Buffer; 026import org.apache.directory.api.ldap.codec.api.LdapApiService; 027import org.apache.directory.api.ldap.codec.api.LdapCodecConstants; 028import org.apache.directory.api.ldap.model.entry.Attribute; 029import org.apache.directory.api.ldap.model.entry.Entry; 030import org.apache.directory.api.ldap.model.entry.Value; 031import org.apache.directory.api.ldap.model.message.Message; 032import org.apache.directory.api.ldap.model.message.SearchResultEntry; 033import org.apache.directory.api.util.CollectionUtils; 034 035/** 036 * The SearchResultEntry factory. 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 */ 040public final class SearchResultEntryFactory extends ResponseFactory 041{ 042 /** The static instance */ 043 public static final SearchResultEntryFactory INSTANCE = new SearchResultEntryFactory(); 044 045 private SearchResultEntryFactory() 046 { 047 super(); 048 } 049 050 051 /** 052 * Encode the values in reverse order. 053 * 054 * <pre> 055 * 0x04 LL attributeValue 056 * ... 057 * 0x04 LL attributeValue 058 * </pre> 059 * 060 * @param buffer The buffer where to put the PDU 061 * @param values The iterator on the values 062 */ 063 private void encodeValues( Asn1Buffer buffer, Iterator<Value> values ) 064 { 065 values = CollectionUtils.reverse( values ); 066 while ( values.hasNext() ) 067 { 068 Value value = values.next(); 069 070 // The value 071 if ( value.isHumanReadable() ) 072 { 073 BerValue.encodeOctetString( buffer, value.getString() ); 074 } 075 else 076 { 077 BerValue.encodeOctetString( buffer, value.getBytes() ); 078 } 079 } 080 } 081 082 083 /** 084 * Encode the attributes in reverse order. 085 * 086 * <pre> 087 * 0x30 LL partialAttributeList 088 * 0x04 LL type 089 * 0x31 LL vals 090 * 0x04 LL attributeValue 091 * ... 092 * 0x04 LL attributeValue 093 * </pre> 094 * 095 * @param buffer The buffer where to put the PDU 096 * @param attributes The iterator on the attributes 097 */ 098 private void encodeAttributes( Asn1Buffer buffer, Iterator<Attribute> attributes ) 099 { 100 attributes = CollectionUtils.reverse( attributes ); 101 while ( attributes.hasNext() ) 102 { 103 Attribute attribute = attributes.next(); 104 105 int start = buffer.getPos(); 106 107 // The values if any 108 if ( attribute.size() != 0 ) 109 { 110 encodeValues( buffer, attribute.iterator() ); 111 } 112 113 // The values set 114 BerValue.encodeSet( buffer, start ); 115 116 // The attribute type 117 BerValue.encodeOctetString( buffer, attribute.getUpId() ); 118 119 // Attribute sequence 120 BerValue.encodeSequence( buffer, start ); 121 } 122 } 123 124 125 /** 126 * Encode the SearchResultEntry message to a PDU. 127 * <br> 128 * SearchResultEntry : 129 * <pre> 130 * 0x64 LL 131 * 0x04 LL objectName 132 * 0x30 LL attributes 133 * 0x30 LL partialAttributeList 134 * 0x04 LL type 135 * 0x31 LL vals 136 * 0x04 LL attributeValue 137 * ... 138 * 0x04 LL attributeValue 139 * ... 140 * 0x30 LL partialAttributeList 141 * 0x04 LL type 142 * 0x31 LL vals 143 * 0x04 LL attributeValue 144 * ... 145 * 0x04 LL attributeValue 146 * </pre> 147 * 148 * @param buffer The buffer where to put the PDU 149 * @param message the SearchResultEntry to encode 150 */ 151 @Override 152 public void encodeReverse( LdapApiService codec, Asn1Buffer buffer, Message message ) 153 { 154 int start = buffer.getPos(); 155 156 SearchResultEntry searchResultEntry = ( SearchResultEntry ) message; 157 158 // The partial attribute list 159 Entry entry = searchResultEntry.getEntry(); 160 161 // The attributes, if we have any 162 if ( ( entry != null ) && ( entry.size() != 0 ) ) 163 { 164 encodeAttributes( buffer, entry.iterator() ); 165 } 166 167 // The attributes sequence 168 BerValue.encodeSequence( buffer, start ); 169 170 // The objectName 171 BerValue.encodeOctetString( buffer, searchResultEntry.getObjectName().getName() ); 172 173 // The SearchResultEntry tag 174 BerValue.encodeSequence( buffer, LdapCodecConstants.SEARCH_RESULT_ENTRY_TAG, start ); 175 } 176}