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            if ( requestValue != null )
078            {
079                passwordModifyRequest = decoder.decode( requestValue );
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    @Override
134    public byte[] getUserIdentity()
135    {
136        return passwordModifyRequest.getUserIdentity();
137    }
138
139
140    /**
141     * @param userIdentity the userIdentity to set
142     */
143    @Override
144    public void setUserIdentity( byte[] userIdentity )
145    {
146        passwordModifyRequest.setUserIdentity( userIdentity );
147    }
148
149
150    /**
151     * {@inheritDoc}
152     */
153    @Override
154    public byte[] getOldPassword()
155    {
156        return passwordModifyRequest.getOldPassword();
157    }
158
159
160    /**
161     * @param oldPassword the oldPassword to set
162     */
163    @Override
164    public void setOldPassword( byte[] oldPassword )
165    {
166        passwordModifyRequest.setOldPassword( oldPassword );
167    }
168
169
170    /**
171     * {@inheritDoc}
172     */
173    @Override
174    public byte[] getNewPassword()
175    {
176        return passwordModifyRequest.getNewPassword();
177    }
178
179
180    /**
181     * @param newPassword the newPassword to set
182     */
183    @Override
184    public void setNewPassword( byte[] newPassword )
185    {
186        passwordModifyRequest.setNewPassword( newPassword );
187    }
188
189
190    /**
191     * Compute the PasswordModifyRequest extended operation length
192     * <pre>
193     * 0x30 L1 
194     *   | 
195     *  [+-- 0x80 L2 userIdentity] 
196     *  [+-- 0x81 L3 oldPassword] 
197     *  [+-- 0x82 L4 newPassword] 
198     * </pre>
199     */
200    /* No qualifier */int computeLengthInternal()
201    {
202        requestLength = 0;
203
204        if ( passwordModifyRequest.getUserIdentity() != null )
205        {
206            int len = passwordModifyRequest.getUserIdentity().length;
207            requestLength = 1 + TLV.getNbBytes( len ) + len;
208        }
209
210        if ( passwordModifyRequest.getOldPassword() != null )
211        {
212            int len = passwordModifyRequest.getOldPassword().length;
213            requestLength += 1 + TLV.getNbBytes( len ) + len;
214        }
215
216        if ( passwordModifyRequest.getNewPassword() != null )
217        {
218            int len = passwordModifyRequest.getNewPassword().length;
219            requestLength += 1 + TLV.getNbBytes( len ) + len;
220        }
221
222        return 1 + TLV.getNbBytes( requestLength ) + requestLength;
223    }
224
225
226    /**
227     * Encodes the PasswordModifyRequest extended operation.
228     * 
229     * @return A ByteBuffer that contains the encoded PDU
230     * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong.
231     */
232    /* No qualifier */ByteBuffer encodeInternal() throws EncoderException
233    {
234        ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() );
235
236        bb.put( UniversalTag.SEQUENCE.getValue() );
237        bb.put( TLV.getBytes( requestLength ) );
238
239        if ( passwordModifyRequest.getUserIdentity() != null )
240        {
241            byte[] userIdentity = passwordModifyRequest.getUserIdentity();
242            bb.put( ( byte ) PasswordModifyRequestConstants.USER_IDENTITY_TAG );
243            bb.put( TLV.getBytes( userIdentity.length ) );
244            bb.put( userIdentity );
245        }
246
247        if ( passwordModifyRequest.getOldPassword() != null )
248        {
249            byte[] oldPassword = passwordModifyRequest.getOldPassword();
250            bb.put( ( byte ) PasswordModifyRequestConstants.OLD_PASSWORD_TAG );
251            bb.put( TLV.getBytes( oldPassword.length ) );
252            bb.put( oldPassword );
253        }
254
255        if ( passwordModifyRequest.getNewPassword() != null )
256        {
257            byte[] newPassword = passwordModifyRequest.getNewPassword();
258            bb.put( ( byte ) PasswordModifyRequestConstants.NEW_PASSWORD_TAG );
259            bb.put( TLV.getBytes( newPassword.length ) );
260            bb.put( newPassword );
261        }
262
263        return bb;
264    }
265}