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.pwdModify;
021
022
023import java.nio.ByteBuffer;
024
025import org.apache.directory.api.asn1.DecoderException;
026import org.apache.directory.api.asn1.EncoderException;
027import org.apache.directory.api.asn1.ber.tlv.TLV;
028import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
029import org.apache.directory.api.i18n.I18n;
030import org.apache.directory.api.ldap.codec.api.ExtendedResponseDecorator;
031import org.apache.directory.api.ldap.codec.api.LdapApiService;
032import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyResponse;
033import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyResponseImpl;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037
038/**
039 * A Decorator for PasswordModifyResponse extended response.
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 */
043public class PasswordModifyResponseDecorator extends ExtendedResponseDecorator<PasswordModifyResponse>
044    implements PasswordModifyResponse
045{
046    private static final Logger LOG = LoggerFactory.getLogger( PasswordModifyResponseDecorator.class );
047
048    private PasswordModifyResponse passwordModifyResponse;
049
050    /** stores the length of the response*/
051    private int responseLength = 0;
052
053
054    /**
055     * 
056     * Creates a new instance of PasswordModifyResponseDecorator.
057     *
058     * @param codec The LDAP service instance
059     * @param decoratedMessage The decorated message
060     */
061    public PasswordModifyResponseDecorator( LdapApiService codec, PasswordModifyResponse decoratedMessage )
062    {
063        super( codec, decoratedMessage );
064        passwordModifyResponse = decoratedMessage;
065    }
066
067
068    /**
069     * {@inheritDoc}
070     */
071    @Override
072    public void setResponseValue( byte[] responseValue )
073    {
074        PasswordModifyResponseDecoder decoder = new PasswordModifyResponseDecoder();
075
076        try
077        {
078            if ( responseValue != null )
079            {
080                passwordModifyResponse = decoder.decode( responseValue );
081
082                this.responseValue = new byte[responseValue.length];
083                System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
084            }
085            else
086            {
087                this.responseValue = null;
088            }
089        }
090        catch ( DecoderException e )
091        {
092            LOG.error( I18n.err( I18n.ERR_04165 ), e );
093            throw new RuntimeException( e );
094        }
095    }
096
097
098    /**
099     * {@inheritDoc}
100     */
101    @Override
102    public byte[] getResponseValue()
103    {
104        if ( responseValue == null )
105        {
106            try
107            {
108                responseValue = encodeInternal().array();
109            }
110            catch ( EncoderException e )
111            {
112                LOG.error( I18n.err( I18n.ERR_04167 ), e );
113                throw new RuntimeException( e );
114            }
115        }
116
117        return responseValue;
118    }
119
120
121    /**
122     * {@inheritDoc}
123     */
124    @Override
125    public byte[] getGenPassword()
126    {
127        return getDecorated().getGenPassword();
128    }
129
130
131    /**
132     * @param genPassword the genPassword to set
133     */
134    public void setGenPassword( byte[] genPassword )
135    {
136        ( ( PasswordModifyResponseImpl ) getDecorated() ).setGenPassword( genPassword );
137    }
138
139
140    /**
141     * Overload the parent's getResponseName method, as the pwdModify response should not
142     * contain the responseName.
143     */
144    @Override
145    public String getResponseName()
146    {
147        return null;
148    }
149
150
151    /**
152     * Compute the PasswordModifyResponse extended operation length
153     * <pre>
154     * 0x30 L1 
155     *   | 
156     *  [+-- 0x80 L2 genPassword] 
157     * </pre>
158     */
159    /* no qualifier */int computeLengthInternal()
160    {
161        responseLength = 0;
162
163        if ( passwordModifyResponse.getGenPassword() != null )
164        {
165            int len = passwordModifyResponse.getGenPassword().length;
166            responseLength = 1 + TLV.getNbBytes( len ) + len;
167        }
168
169        return 1 + TLV.getNbBytes( responseLength ) + responseLength;
170    }
171
172
173    /**
174     * Encodes the PasswordModifyResponse extended operation.
175     * 
176     * @return A ByteBuffer that contains the encoded PDU
177     * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.
178     */
179    /* no qualifier */ByteBuffer encodeInternal() throws EncoderException
180    {
181        // Allocate the bytes buffer.
182        ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() );
183
184        bb.put( UniversalTag.SEQUENCE.getValue() );
185        bb.put( TLV.getBytes( responseLength ) );
186
187        if ( passwordModifyResponse.getGenPassword() != null )
188        {
189            byte[] userIdentity = passwordModifyResponse.getGenPassword();
190            bb.put( ( byte ) PasswordModifyResponseConstants.GEN_PASSWORD_TAG );
191            bb.put( TLV.getBytes( userIdentity.length ) );
192            bb.put( userIdentity );
193        }
194
195        return bb;
196    }
197}