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 request.
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 request*/
051    private int requestLength = 0;
052
053
054    public PasswordModifyResponseDecorator( LdapApiService codec, PasswordModifyResponse decoratedMessage )
055    {
056        super( codec, decoratedMessage );
057        passwordModifyResponse = decoratedMessage;
058    }
059
060
061    /**
062     * {@inheritDoc}
063     */
064    @Override
065    public void setResponseValue( byte[] responseValue )
066    {
067        PasswordModifyResponseDecoder decoder = new PasswordModifyResponseDecoder();
068
069        try
070        {
071            passwordModifyResponse = decoder.decode( responseValue );
072
073            if ( responseValue != null )
074            {
075                this.responseValue = new byte[responseValue.length];
076                System.arraycopy( responseValue, 0, this.responseValue, 0, responseValue.length );
077            }
078            else
079            {
080                this.responseValue = null;
081            }
082        }
083        catch ( DecoderException e )
084        {
085            LOG.error( I18n.err( I18n.ERR_04165 ), e );
086            throw new RuntimeException( e );
087        }
088    }
089
090
091    /**
092     * {@inheritDoc}
093     */
094    @Override
095    public byte[] getResponseValue()
096    {
097        if ( responseValue == null )
098        {
099            try
100            {
101                responseValue = encodeInternal().array();
102
103                if ( responseValue == null )
104                {
105                    return null;
106                }
107            }
108            catch ( EncoderException e )
109            {
110                LOG.error( I18n.err( I18n.ERR_04167 ), e );
111                throw new RuntimeException( e );
112            }
113        }
114
115        return responseValue;
116    }
117
118
119    /**
120     * {@inheritDoc}
121     */
122    public byte[] getGenPassword()
123    {
124        return getDecorated().getGenPassword();
125    }
126
127
128    /**
129     * @param genPassword the genPassword to set
130     */
131    public void setGenPassword( byte[] genPassword )
132    {
133        ( ( PasswordModifyResponseImpl ) getDecorated() ).setGenPassword( genPassword );
134    }
135
136
137    /**
138     * Overload the parent's getResponseName method, as the pwdModify response should not
139     * contain the responseName.
140     */
141    public String getResponseName()
142    {
143        return null;
144    }
145
146
147    /**
148     * Compute the PasswordModifyResponse extended operation length
149     * <pre>
150     * 0x30 L1 
151     *   | 
152     *  [+-- 0x80 L2 genPassword] 
153     * </pre>
154     */
155    /* no qualifier */ int computeLengthInternal()
156    {
157        requestLength = 0;
158
159        if ( passwordModifyResponse.getGenPassword() != null )
160        {
161            int len = passwordModifyResponse.getGenPassword().length;
162            requestLength = 1 + TLV.getNbBytes( len ) + len;
163        }
164
165        return 1 + TLV.getNbBytes( requestLength ) + requestLength;
166    }
167
168
169    /**
170     * Encodes the PasswordModifyResponse extended operation.
171     * 
172     * @return A ByteBuffer that contains the encoded PDU
173     * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.
174     */
175    /* no qualifier */ ByteBuffer encodeInternal() throws EncoderException
176    {
177        // Allocate the bytes buffer.
178        ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() );
179        
180        bb.put( UniversalTag.SEQUENCE.getValue() );
181        bb.put( TLV.getBytes( requestLength ) );
182
183        if ( passwordModifyResponse.getGenPassword() != null )
184        {
185            byte[] userIdentity = passwordModifyResponse.getGenPassword();
186            bb.put( ( byte ) PasswordModifyResponseConstants.GEN_PASSWORD_TAG );
187            bb.put( TLV.getBytes( userIdentity.length ) );
188            bb.put( userIdentity );
189        }
190
191        return bb;
192    }
193}