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.message.extended;
021    
022    
023    import javax.naming.NamingException;
024    import javax.naming.ldap.ExtendedResponse;
025    
026    import org.apache.directory.shared.asn1.codec.DecoderException;
027    import org.apache.directory.shared.asn1.codec.EncoderException;
028    import org.apache.directory.shared.ldap.codec.extended.operations.cancel.Cancel;
029    import org.apache.directory.shared.ldap.codec.extended.operations.cancel.CancelDecoder;
030    import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
031    import org.apache.directory.shared.ldap.message.InternalResultResponse;
032    import org.slf4j.Logger;
033    import org.slf4j.LoggerFactory;
034    
035    
036    /**
037     * Implement the extended Cancel Request as described in RFC 3909.
038     * 
039     * It's grammar is :
040     * 
041     * cancelRequestValue ::= SEQUENCE {
042     *        cancelID        MessageID
043     *                        -- MessageID is as defined in [RFC2251]
044     * }
045     *
046     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047     * @version $Rev$, $Date$
048     */
049    public class CancelRequest extends ExtendedRequestImpl
050    {
051        /** The serial version UUID */
052        private static final long serialVersionUID = 1L;
053    
054        /** A logger for this class */
055        private static final Logger LOG = LoggerFactory.getLogger( CancelRequest.class );
056    
057        /** The cancelId of the request to be canceled */
058        private int cancelId;
059    
060        /** The requestName for this extended request */
061        public static final String EXTENSION_OID = "1.3.6.1.1.8";
062    
063        /**
064         * 
065         * Creates a new instance of CancelRequest.
066         *
067         * @param messageId the message id
068         * @param cancelId the message id of the request to cancel
069         */
070        public CancelRequest( int messageId, int cancelId )
071        {
072            super( messageId );
073            setOid( EXTENSION_OID );
074            
075            this.cancelId = cancelId;
076        }
077    
078        
079        /**
080         * Encode the request
081         */
082        private void encodePayload() throws EncoderException
083        {
084            Cancel cancel = new Cancel();
085            cancel.setCancelId( this.cancelId );
086    
087            payload = cancel.encode( null ).array();
088        }
089        
090        /**
091         * Gets the extended request's <b>requestValue</b> portion of the PDU. The
092         * form of the data is request specific and is determined by the extended
093         * request OID.
094         * 
095         * @return byte array of data
096         */
097        public byte[] getPayload()
098        {
099            if ( payload == null )
100            {
101                try
102                {
103                    encodePayload();
104                }
105                catch ( EncoderException e )
106                {
107                    LOG.error( "Failed to encode payload GracefulShutdownRequest", e );
108                    throw new RuntimeException( e );
109                }
110            }
111            
112            return super.getPayload();
113        }
114    
115    
116        /**
117         * Sets the extended request's <b>requestValue</b> portion of the PDU.
118         * 
119         * @param payload byte array of data encapsulating ext. req. parameters
120         */
121        public void setPayload( byte[] payload ) 
122        {
123            CancelDecoder decoder = new CancelDecoder();
124            
125            try
126            {
127                Cancel cancel = ( Cancel ) decoder.decode( payload );
128    
129                if ( payload != null )
130                {
131                    this.payload = new byte[ payload.length ];
132                    System.arraycopy( payload, 0, this.payload, 0, payload.length );
133                } else {
134                    this.payload = null;
135                }
136                this.cancelId = cancel.getCancelId();
137            }
138            catch ( DecoderException e )
139            {
140                LOG.error( "failed to decode payload", e );
141                throw new RuntimeException( e );
142            }
143        }
144    
145    
146        public ExtendedResponse createExtendedResponse( String id, byte[] berValue, int offset, int length )
147            throws NamingException
148        {
149            return ( ExtendedResponse ) getResultResponse();
150        }
151    
152    
153        public byte[] getEncodedValue()
154        {
155            return getPayload();
156        }
157    
158    
159        public InternalResultResponse getResultResponse()
160        {
161            if ( response == null )
162            {
163                response = new CancelResponse( cancelId );
164            }
165    
166            return response;
167        }
168    }
169