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.ExtendedRequestDecorator;
031import org.apache.directory.api.ldap.codec.api.LdapApiService;
032import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyRequest;
033import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyResponse;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036
037
038/**
039 * A Decorator for PasswordModifyRequest extended request.
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 */
043public class PasswordModifyRequestDecorator extends ExtendedRequestDecorator<PasswordModifyRequest> 
044    implements PasswordModifyRequest
045{
046    private static final Logger LOG = LoggerFactory.getLogger( PasswordModifyRequestDecorator.class );
047
048    /** The internal PasswordModifyRequest */
049    private PasswordModifyRequest passwordModifyRequest;
050
051    /** stores the length of the request*/
052    private int requestLength = 0;
053
054
055    /**
056     * Create a new decorator instance 
057     * @param codec The codec service
058     * @param decoratedMessage The decorated PwdModifyRequest
059     */
060    public PasswordModifyRequestDecorator( LdapApiService codec, PasswordModifyRequest decoratedMessage )
061    {
062        super( codec, decoratedMessage );
063        passwordModifyRequest = decoratedMessage;
064    }
065
066
067    /**
068     * {@inheritDoc}
069     */
070    @Override
071    public void setRequestValue( byte[] requestValue )
072    {
073        PasswordModifyRequestDecoder decoder = new PasswordModifyRequestDecoder();
074
075        try
076        {
077            passwordModifyRequest = decoder.decode( requestValue );
078            
079            if ( requestValue != null )
080            {
081                this.requestValue = new byte[requestValue.length];
082                System.arraycopy( requestValue, 0, this.requestValue, 0, requestValue.length );
083            }
084            else
085            {
086                this.requestValue = null;
087            }
088        }
089        catch ( DecoderException e )
090        {
091            LOG.error( I18n.err( I18n.ERR_04165 ), e );
092            throw new RuntimeException( e );
093        }
094    }
095
096
097    /**
098     * {@inheritDoc}
099     */
100    @Override
101    public byte[] getRequestValue()
102    {
103        if ( requestValue == null )
104        {
105            try
106            {
107                requestValue = encodeInternal().array();
108            }
109            catch ( EncoderException e )
110            {
111                LOG.error( I18n.err( I18n.ERR_04167 ), e );
112                throw new RuntimeException( e );
113            }
114        }
115
116        return requestValue;
117    }
118
119
120    /**
121     * {@inheritDoc}
122     */
123    @Override
124    public PasswordModifyResponse getResultResponse()
125    {
126        return ( PasswordModifyResponse ) passwordModifyRequest.getResultResponse();
127    }
128
129
130    /**
131     * {@inheritDoc}
132     */
133    public byte[] getUserIdentity()
134    {
135        return passwordModifyRequest.getUserIdentity();
136    }
137
138
139    /**
140     * @param userIdentity the userIdentity to set
141     */
142    public void setUserIdentity( byte[] userIdentity )
143    {
144        passwordModifyRequest.setUserIdentity( userIdentity );
145    }
146
147
148    /**
149     * {@inheritDoc}
150     */
151    public byte[] getOldPassword()
152    {
153        return passwordModifyRequest.getOldPassword();
154    }
155
156
157    /**
158     * @param oldPassword the oldPassword to set
159     */
160    public void setOldPassword( byte[] oldPassword )
161    {
162        passwordModifyRequest.setOldPassword( oldPassword );
163    }
164
165
166    /**
167     * {@inheritDoc}
168     */
169    public byte[] getNewPassword()
170    {
171        return passwordModifyRequest.getNewPassword();
172    }
173
174
175    /**
176     * @param newPassword the newPassword to set
177     */
178    public void setNewPassword( byte[] newPassword )
179    {
180        passwordModifyRequest.setNewPassword( newPassword );
181    }
182
183
184    /**
185     * Compute the PasswordModifyRequest extended operation length
186     * <pre>
187     * 0x30 L1 
188     *   | 
189     *  [+-- 0x80 L2 userIdentity] 
190     *  [+-- 0x81 L3 oldPassword] 
191     *  [+-- 0x82 L4 newPassword] 
192     * </pre>
193     */
194    /* No qualifier */ int computeLengthInternal()
195    {
196        requestLength = 0;
197
198        if ( passwordModifyRequest.getUserIdentity() != null )
199        {
200            int len = passwordModifyRequest.getUserIdentity().length;
201            requestLength = 1 + TLV.getNbBytes( len ) + len;
202        }
203
204        if ( passwordModifyRequest.getOldPassword() != null )
205        {
206            int len = passwordModifyRequest.getOldPassword().length;
207            requestLength += 1 + TLV.getNbBytes( len ) + len;
208        }
209
210        if ( passwordModifyRequest.getNewPassword() != null )
211        {
212            int len = passwordModifyRequest.getNewPassword().length;
213            requestLength += 1 + TLV.getNbBytes( len ) + len;
214        }
215
216        return 1 + TLV.getNbBytes( requestLength ) + requestLength;
217    }
218
219
220    /**
221     * Encodes the PasswordModifyRequest extended operation.
222     * 
223     * @return A ByteBuffer that contains the encoded PDU
224     * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.
225     */
226    /* No qualifier */ ByteBuffer encodeInternal() throws EncoderException
227    {
228        ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() );
229
230        bb.put( UniversalTag.SEQUENCE.getValue() );
231        bb.put( TLV.getBytes( requestLength ) );
232
233        if ( passwordModifyRequest.getUserIdentity() != null )
234        {
235            byte[] userIdentity = passwordModifyRequest.getUserIdentity();
236            bb.put( ( byte ) PasswordModifyRequestConstants.USER_IDENTITY_TAG );
237            bb.put( TLV.getBytes( userIdentity.length ) );
238            bb.put( userIdentity );
239        }
240
241        if ( passwordModifyRequest.getOldPassword() != null )
242        {
243            byte[] oldPassword = passwordModifyRequest.getOldPassword();
244            bb.put( ( byte ) PasswordModifyRequestConstants.OLD_PASSWORD_TAG );
245            bb.put( TLV.getBytes( oldPassword.length ) );
246            bb.put( oldPassword );
247        }
248
249        if ( passwordModifyRequest.getNewPassword() != null )
250        {
251            byte[] newPassword = passwordModifyRequest.getNewPassword();
252            bb.put( ( byte ) PasswordModifyRequestConstants.NEW_PASSWORD_TAG );
253            bb.put( TLV.getBytes( newPassword.length ) );
254            bb.put( newPassword );
255        }
256
257        return bb;
258    }
259}