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.extras.extended.ads_impl.endTransaction; 021 022 023import java.nio.ByteBuffer; 024import java.util.Iterator; 025 026import org.apache.directory.api.asn1.DecoderException; 027import org.apache.directory.api.asn1.ber.Asn1Decoder; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.asn1.util.Asn1Buffer; 031import org.apache.directory.api.ldap.codec.api.AbstractExtendedOperationFactory; 032import org.apache.directory.api.ldap.codec.api.ControlFactory; 033import org.apache.directory.api.ldap.codec.api.ExtendedOperationFactory; 034import org.apache.directory.api.ldap.codec.api.LdapApiService; 035import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequest; 036import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionRequestImpl; 037import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponse; 038import org.apache.directory.api.ldap.extras.extended.endTransaction.EndTransactionResponseImpl; 039import org.apache.directory.api.ldap.extras.extended.endTransaction.UpdateControls; 040import org.apache.directory.api.ldap.model.message.Control; 041import org.apache.directory.api.ldap.model.message.ExtendedRequest; 042import org.apache.directory.api.ldap.model.message.ExtendedResponse; 043 044 045/** 046 * An {@link ExtendedOperationFactory} for creating EndTransaction extended request response 047 * pairs. 048 * 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 */ 051public class EndTransactionFactory extends AbstractExtendedOperationFactory 052{ 053 /** 054 * Creates a new instance of EndTransactionFactory. 055 * 056 * @param codec The codec for this factory. 057 */ 058 public EndTransactionFactory( LdapApiService codec ) 059 { 060 super( codec, EndTransactionRequest.EXTENSION_OID ); 061 } 062 063 064 /** 065 * {@inheritDoc} 066 */ 067 @Override 068 public EndTransactionRequest newRequest() 069 { 070 EndTransactionRequest endTransactionRequest = new EndTransactionRequestImpl(); 071 072 return endTransactionRequest; 073 074 } 075 076 077 /** 078 * {@inheritDoc} 079 */ 080 @Override 081 public EndTransactionRequest newRequest( byte[] encodedValue ) throws DecoderException 082 { 083 EndTransactionRequest endTransactionRequest = new EndTransactionRequestImpl(); 084 decodeValue( endTransactionRequest, encodedValue ); 085 086 return endTransactionRequest; 087 088 } 089 090 091 /** 092 * {@inheritDoc} 093 */ 094 @Override 095 public EndTransactionResponse newResponse() 096 { 097 EndTransactionResponse endTransactionResponse = new EndTransactionResponseImpl(); 098 099 return endTransactionResponse; 100 } 101 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public EndTransactionResponse newResponse( byte[] encodedValue ) throws DecoderException 108 { 109 EndTransactionResponse endTransactionResponse = new EndTransactionResponseImpl(); 110 decodeValue( endTransactionResponse, encodedValue ); 111 112 return endTransactionResponse; 113 } 114 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public void decodeValue( ExtendedRequest extendedRequest, byte[] requestValue ) throws DecoderException 121 { 122 ByteBuffer bb = ByteBuffer.wrap( requestValue ); 123 EndTransactionRequestContainer container = new EndTransactionRequestContainer(); 124 container.setEndTransactionRequest( ( EndTransactionRequest ) extendedRequest ); 125 Asn1Decoder.decode( bb, container ); 126 } 127 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override 133 public void decodeValue( ExtendedResponse extendedResponse, byte[] requestValue ) throws DecoderException 134 { 135 ByteBuffer bb = ByteBuffer.wrap( requestValue ); 136 EndTransactionResponseContainer container = new EndTransactionResponseContainer(); 137 container.setEndTransactionResponse( ( EndTransactionResponse ) extendedResponse ); 138 Asn1Decoder.decode( bb, container ); 139 } 140 141 142 /** 143 * {@inheritDoc} 144 */ 145 @Override 146 public void encodeValue( Asn1Buffer buffer, ExtendedRequest extendedRequest ) 147 { 148 int start = buffer.getPos(); 149 EndTransactionRequest transactionRequest = ( EndTransactionRequest ) extendedRequest; 150 151 // The identifier 152 BerValue.encodeOctetString( buffer, transactionRequest.getTransactionId() ); 153 154 // The commit flag, if false 155 if ( !transactionRequest.getCommit() ) 156 { 157 BerValue.encodeBoolean( buffer, false ); 158 } 159 160 // The sequence 161 BerValue.encodeSequence( buffer, start ); 162 } 163 164 165 private void encodeControls( Asn1Buffer buffer, Iterator<Control> controls ) 166 { 167 if ( controls.hasNext() ) 168 { 169 Control control = controls.next(); 170 171 encodeControls( buffer, controls ); 172 173 int start = buffer.getPos(); 174 175 // The control value, if any 176 ControlFactory<?> controlFactory = codec.getResponseControlFactories().get( control.getOid() ); 177 178 if ( controlFactory != null ) 179 { 180 controlFactory.encodeValue( buffer, control ); 181 182 // The value sequence 183 BerValue.encodeSequence( buffer, UniversalTag.OCTET_STRING.getValue(), start ); 184 } 185 186 // The control criticality of TRUE 187 if ( control.isCritical() ) 188 { 189 BerValue.encodeBoolean( buffer, true ); 190 } 191 192 // The control oid 193 BerValue.encodeOctetString( buffer, control.getOid() ); 194 195 // The control sequence 196 BerValue.encodeSequence( buffer, start ); 197 } 198 } 199 200 201 private void encodeUpdatedControls( Asn1Buffer buffer, Iterator<UpdateControls> updateControls ) 202 { 203 if ( updateControls.hasNext() ) 204 { 205 UpdateControls updateControl = updateControls.next(); 206 207 encodeUpdatedControls( buffer, updateControls ); 208 209 int start = buffer.getPos(); 210 211 // The controls 212 encodeControls( buffer, updateControl.getControls().iterator() ); 213 214 // The controls sequence 215 BerValue.encodeSequence( buffer, start ); 216 217 // The messageID 218 BerValue.encodeInteger( buffer, updateControl.getMessageId() ); 219 220 // The sequence 221 BerValue.encodeSequence( buffer, start ); 222 } 223 } 224 225 226 /** 227 * {@inheritDoc} 228 */ 229 @Override 230 public void encodeValue( Asn1Buffer buffer, ExtendedResponse extendedResponse ) 231 { 232 // This is a hack !!! We remove the response name from the response 233 // because it has only be added to find the factory, but we don't want it 234 // top be injected in the encoded PDU... 235 extendedResponse.setResponseName( null ); 236 237 int start = buffer.getPos(); 238 EndTransactionResponse endTransactionResponse = ( EndTransactionResponse ) extendedResponse; 239 240 // The controls 241 if ( endTransactionResponse.getUpdateControls().size() > 0 ) 242 { 243 encodeUpdatedControls( buffer, endTransactionResponse.getUpdateControls().iterator() ); 244 245 BerValue.encodeSequence( buffer, start ); 246 } 247 248 // The messageID flag, if false 249 if ( endTransactionResponse.getFailedMessageId() >= 0 ) 250 { 251 BerValue.encodeInteger( buffer, endTransactionResponse.getFailedMessageId() ); 252 } 253 254 // The sequence 255 BerValue.encodeSequence( buffer, start ); 256 } 257}