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 */ 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; 033 034/** 035 * The SearchResultEntry factory. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public final class SearchResultEntryFactory extends ResponseFactory 040{ 041 /** The static instance */ 042 public static final SearchResultEntryFactory INSTANCE = new SearchResultEntryFactory(); 043 044 private SearchResultEntryFactory() 045 { 046 super(); 047 } 048 049 050 /** 051 * Encode the values recursively 052 * 053 * <pre> 054 * 0x04 LL attributeValue 055 * ... 056 * 0x04 LL attributeValue 057 * </pre> 058 * 059 * @param buffer The buffer where to put the PDU 060 * @param values The iterator on the values 061 */ 062 private void encodeValues( Asn1Buffer buffer, Iterator<Value> values ) 063 { 064 if ( values.hasNext() ) 065 { 066 Value value = values.next(); 067 068 encodeValues( buffer, values ); 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 recursively 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 if ( attributes.hasNext() ) 101 { 102 Attribute attribute = attributes.next(); 103 104 // Recursive call 105 encodeAttributes( buffer, attributes ); 106 107 int start = buffer.getPos(); 108 109 // The values, recursively, if any 110 if ( attribute.size() != 0 ) 111 { 112 encodeValues( buffer, attribute.iterator() ); 113 } 114 115 // The values set 116 BerValue.encodeSet( buffer, start ); 117 118 // The attribute type 119 BerValue.encodeOctetString( buffer, attribute.getUpId() ); 120 121 // Attribute sequence 122 BerValue.encodeSequence( buffer, start ); 123 } 124 } 125 126 127 /** 128 * Encode the SearchResultEntry message to a PDU. 129 * <br> 130 * SearchResultEntry : 131 * <pre> 132 * 0x64 LL 133 * 0x04 LL objectName 134 * 0x30 LL attributes 135 * 0x30 LL partialAttributeList 136 * 0x04 LL type 137 * 0x31 LL vals 138 * 0x04 LL attributeValue 139 * ... 140 * 0x04 LL attributeValue 141 * ... 142 * 0x30 LL partialAttributeList 143 * 0x04 LL type 144 * 0x31 LL vals 145 * 0x04 LL attributeValue 146 * ... 147 * 0x04 LL attributeValue 148 * </pre> 149 * 150 * @param buffer The buffer where to put the PDU 151 * @param message the SearchResultEntry to encode 152 */ 153 @Override 154 public void encodeReverse( LdapApiService codec, Asn1Buffer buffer, Message message ) 155 { 156 int start = buffer.getPos(); 157 158 SearchResultEntry searchResultEntry = ( SearchResultEntry ) message; 159 160 // The partial attribute list 161 Entry entry = searchResultEntry.getEntry(); 162 163 // The attributes, recursively, if we have any 164 if ( ( entry != null ) && ( entry.size() != 0 ) ) 165 { 166 encodeAttributes( buffer, entry.iterator() ); 167 } 168 169 // The attributes sequence 170 BerValue.encodeSequence( buffer, start ); 171 172 // The objectName 173 BerValue.encodeOctetString( buffer, searchResultEntry.getObjectName().getName() ); 174 175 // The SearchResultEntry tag 176 BerValue.encodeSequence( buffer, LdapCodecConstants.SEARCH_RESULT_ENTRY_TAG, start ); 177 } 178}