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.shared.ldap.extras.extended.ads_impl.gracefulDisconnect;
021
022
023import java.nio.ByteBuffer;
024import java.util.List;
025
026import org.apache.directory.shared.asn1.DecoderException;
027import org.apache.directory.shared.asn1.EncoderException;
028import org.apache.directory.shared.asn1.ber.Asn1Decoder;
029import org.apache.directory.shared.i18n.I18n;
030import org.apache.directory.shared.ldap.codec.api.ExtendedResponseDecorator;
031import org.apache.directory.shared.ldap.codec.api.LdapApiService;
032import org.apache.directory.shared.ldap.extras.extended.GracefulDisconnectResponse;
033import org.apache.directory.shared.ldap.extras.extended.GracefulDisconnectResponseImpl;
034import org.apache.directory.shared.ldap.model.exception.LdapURLEncodingException;
035import org.apache.directory.shared.ldap.model.message.Referral;
036import org.apache.directory.shared.ldap.model.message.ReferralImpl;
037import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
038import org.apache.directory.shared.ldap.model.url.LdapUrl;
039import org.slf4j.Logger;
040import org.slf4j.LoggerFactory;
041
042
043/**
044 * A Decorator for CancelResponses.
045 *
046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047 */
048public class GracefulDisconnectResponseDecorator extends ExtendedResponseDecorator<GracefulDisconnectResponse> implements GracefulDisconnectResponse
049{
050    /** The logger. */
051    private static final Logger LOG = LoggerFactory.getLogger( GracefulDisconnectResponseDecorator.class );
052
053    
054    /**
055     * Creates a new instance of CancelResponseDecorator.
056     *
057     * @param codec
058     * @param decoratedMessage
059     */
060    public GracefulDisconnectResponseDecorator( LdapApiService codec, GracefulDisconnectResponse decoratedMessage )
061    {
062        super( codec, decoratedMessage );
063        responseValue = null;
064        encodeResponse();
065    }
066    
067    
068    /**
069     * Creates a new instance of CancelResponseDecorator.
070     *
071     * @param codec
072     * @param responseValue
073     */
074    public GracefulDisconnectResponseDecorator( LdapApiService codec, byte[] responseValue ) throws DecoderException
075    {
076        super( codec, new GracefulDisconnectResponseImpl() );
077        this.responseValue = responseValue;
078        decodeValue();
079    }
080    
081    
082    private void decodeValue() throws DecoderException
083    {
084        GracefulDisconnectDecoder decoder = new GracefulDisconnectDecoder();
085        org.apache.directory.shared.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnect codec = null;
086
087        try
088        {
089            codec = (org.apache.directory.shared.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnect) decoder
090                .decode( responseValue );
091            getDecorated().setTimeOffline( codec.getTimeOffline() );
092            getDecorated().setDelay( codec.getDelay() );
093            getDecorated().getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
094            List<LdapUrl> contexts = codec.getReplicatedContexts();
095
096            for ( LdapUrl ldapUrl : contexts )
097            {
098                getDecorated().getLdapResult().getReferral().addLdapUrl( ldapUrl.toString() );
099            }
100        }
101        catch ( DecoderException e )
102        {
103            LOG.error( I18n.err( I18n.ERR_04169 ), e );
104            throw e;
105        }
106    }
107
108
109    private void encodeResponse()
110    {
111        org.apache.directory.shared.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnect codec = 
112            new org.apache.directory.shared.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnect();
113        codec.setTimeOffline( getDecorated().getTimeOffline() );
114        codec.setDelay( getDecorated().getDelay() );
115
116        for ( String ldapUrlStr : getDecorated().getLdapResult().getReferral().getLdapUrls() )
117        {
118            LdapUrl ldapUrl = null;
119
120            try
121            {
122                ldapUrl = new LdapUrl( ldapUrlStr );
123            }
124            catch ( LdapURLEncodingException e )
125            {
126                LOG.error( I18n.err( I18n.ERR_04170, ldapUrlStr ), e );
127                continue;
128            }
129
130            codec.addReplicatedContexts( ldapUrl );
131        }
132
133        try
134        {
135            super.responseValue = codec.encode().array();
136        }
137        catch ( EncoderException e )
138        {
139            LOG.error( I18n.err( I18n.ERR_04171 ), e );
140            throw new RuntimeException( e );
141        }
142    }
143
144
145    // ------------------------------------------------------------------------
146    // ExtendedResponse Interface Method Implementations
147    // ------------------------------------------------------------------------
148
149    
150    /**
151     * Gets the response OID specific encoded response values.
152     * 
153     * @return the response specific encoded response values.
154     */
155    public byte[] getResponseValue()
156    {
157        if ( responseValue == null )
158        {
159            encodeResponse();
160        }
161
162        final byte[] copy = new byte[responseValue.length];
163        System.arraycopy( responseValue, 0, copy, 0, responseValue.length );
164        return copy;
165    }
166
167
168    /**
169     * Sets the response OID specific encoded response values.
170     * 
171     * @param responseValue the response specific encoded response values.
172     */
173    public void setResponseValue( byte[] responseValue )
174    {
175        if ( responseValue == null )
176        {
177            this.responseValue = null;
178            getDecorated().setDelay( 0 );
179            getDecorated().setTimeOffline( 0 );
180            getDecorated().getLdapResult().setReferral( new ReferralImpl() );
181            return;
182        }
183        
184        ByteBuffer bb = ByteBuffer.wrap( responseValue );
185        GracefulDisconnectContainer container = new GracefulDisconnectContainer();
186        Asn1Decoder decoder = new Asn1Decoder();
187
188        try
189        {
190            decoder.decode( bb, container );
191        }
192        catch ( DecoderException e )
193        {
194            LOG.error( I18n.err( I18n.ERR_04172 ), e );
195        }
196
197        org.apache.directory.shared.ldap.extras.extended.ads_impl.gracefulDisconnect.GracefulDisconnect codec = container
198            .getGracefulDisconnect();
199        
200        getDecorated().setDelay( codec.getDelay() );
201        getDecorated().setTimeOffline( codec.getTimeOffline() );
202
203        for ( LdapUrl ldapUrl : codec.getReplicatedContexts() )
204        {
205            getDecorated().getLdapResult().getReferral().addLdapUrl( ldapUrl.toString() );
206        }
207
208        this.responseValue = new byte[responseValue.length];
209        System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
210    }
211    
212
213    /**
214     * {@inheritDoc}
215     */
216    public int getDelay()
217    {
218        return getDecorated().getDelay();
219    }
220
221    
222    /**
223     * {@inheritDoc}
224     */
225    public void setDelay( int delay )
226    {
227        getDecorated().setDelay( delay );
228    }
229
230    
231    /**
232     * {@inheritDoc}
233     */
234    public int getTimeOffline()
235    {
236        return getDecorated().getTimeOffline();
237    }
238    
239
240    /**
241     * {@inheritDoc}
242     */
243    public void setTimeOffline( int timeOffline )
244    {
245        getDecorated().setTimeOffline( timeOffline );
246    }
247
248    
249    /**
250     * {@inheritDoc}
251     */
252    public Referral getReplicatedContexts()
253    {
254        return getDecorated().getReplicatedContexts();
255    }
256}