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.Collection; 023import java.util.Iterator; 024 025import org.apache.directory.api.asn1.ber.tlv.BerValue; 026import org.apache.directory.api.asn1.util.Asn1Buffer; 027import org.apache.directory.api.ldap.codec.api.LdapApiService; 028import org.apache.directory.api.ldap.codec.api.LdapCodecConstants; 029import org.apache.directory.api.ldap.model.message.LdapResult; 030import org.apache.directory.api.ldap.model.message.Message; 031import org.apache.directory.api.ldap.model.message.Referral; 032import org.apache.directory.api.ldap.model.message.ResultResponse; 033 034/** 035 * The Response factory. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public abstract class ResponseFactory implements Messagefactory 040{ 041 // A default success bytes sequence 042 private static final byte[] DEFAULT_SUCCESS = new byte[] 043 { 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00 }; 044 045 private static final byte[] EMPTY_MATCHED_DN = new byte[] 046 { 0x04, 0x00 }; 047 048 /** 049 * Creates a new instance of ResponseFactory. 050 */ 051 protected ResponseFactory() 052 { 053 // Nothing to do 054 } 055 056 057 /** 058 * Encode referral's URLs recursively 059 * 060 * @param buffer The buffer that will contain the encoded urls 061 * @param urls The urls to encode 062 */ 063 protected void encodeReferralUrls( Asn1Buffer buffer, Iterator<String> urls ) 064 { 065 if ( urls.hasNext() ) 066 { 067 String url = urls.next(); 068 069 encodeReferralUrls( buffer, urls ); 070 071 BerValue.encodeOctetString( buffer, url ); 072 } 073 } 074 075 076 /** 077 * Encode the LdapResult element 078 * <br> 079 * LdapResult : 080 * <pre> 081 * 0x0A 01 resultCode (0..80) 082 * 0x04 L1 matchedDN (L1 = Length(matchedDN)) 083 * 0x04 L2 errorMessage (L2 = Length(errorMessage)) 084 * [0x83 L3] referrals 085 * | 086 * +--> 0x04 L4 referral 087 * +--> 0x04 L5 referral 088 * +--> ... 089 * +--> 0x04 Li referral 090 * +--> ... 091 * +--> 0x04 Ln referral 092 * </pre> 093 * 094 * @param buffer The buffer where to put the PDU 095 * @param ldapResult The LdapResult instance 096 */ 097 protected void encodeLdapResultReverse( Asn1Buffer buffer, LdapResult ldapResult ) 098 { 099 if ( ldapResult.isDefaultSuccess() ) 100 { 101 // The length of a default success PDU : 0xA0 0x01 0x00 0x04 0x00 0x04 0x00 102 buffer.put( DEFAULT_SUCCESS ); 103 104 return; 105 } 106 107 // Referrals, if any 108 Referral referral = ldapResult.getReferral(); 109 110 if ( referral != null ) 111 { 112 int start = buffer.getPos(); 113 Collection<String> urls = referral.getLdapUrls(); 114 115 if ( urls != null ) 116 { 117 encodeReferralUrls( buffer, urls.iterator() ); 118 } 119 120 // The referral tag 121 BerValue.encodeSequence( buffer, ( byte ) LdapCodecConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, start ); 122 } 123 124 // The errorMessage 125 BerValue.encodeOctetString( buffer, ldapResult.getDiagnosticMessage() ); 126 127 // The matchedDN 128 if ( ldapResult.getMatchedDn() != null ) 129 { 130 BerValue.encodeOctetString( buffer, ldapResult.getMatchedDn().getName() ); 131 } 132 else 133 { 134 buffer.put( EMPTY_MATCHED_DN ); 135 } 136 137 // The result code 138 BerValue.encodeEnumerated( buffer, ldapResult.getResultCode().getValue() ); 139 } 140 141 142 /** 143 * Encode the Response message to a PDU. 144 * <br> 145 * Response : 146 * <pre> 147 * 0x<tag> L1 148 * | 149 * +--> LdapResult 150 * </pre> 151 * 152 * @param codec The LdapApiService instance 153 * @param buffer The buffer where to put the PDU 154 * @param tag The message tag 155 * @param message the Response to encode 156 */ 157 protected void encodeReverse( LdapApiService codec, Asn1Buffer buffer, byte tag, Message message ) 158 { 159 int start = buffer.getPos(); 160 161 // The LDAPResult part 162 encodeLdapResultReverse( buffer, ( ( ResultResponse ) message ).getLdapResult() ); 163 164 // The BindResponse Tag 165 BerValue.encodeSequence( buffer, tag, start ); 166 } 167}