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.codec.controls.sort;
021
022
023import java.nio.ByteBuffer;
024
025import org.apache.directory.api.asn1.Asn1Object;
026import org.apache.directory.api.asn1.DecoderException;
027import org.apache.directory.api.asn1.EncoderException;
028import org.apache.directory.api.asn1.ber.Asn1Decoder;
029import org.apache.directory.api.asn1.ber.tlv.BerValue;
030import org.apache.directory.api.asn1.ber.tlv.TLV;
031import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
032import org.apache.directory.api.i18n.I18n;
033import org.apache.directory.api.ldap.codec.api.ControlDecorator;
034import org.apache.directory.api.ldap.codec.api.LdapApiService;
035import org.apache.directory.api.ldap.model.message.controls.SortResponse;
036import org.apache.directory.api.ldap.model.message.controls.SortResponseControlImpl;
037import org.apache.directory.api.ldap.model.message.controls.SortResultCode;
038import org.apache.directory.api.util.Strings;
039
040
041/**
042 * Decorator class for SortResponseControl.
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 */
046public class SortResponseDecorator extends ControlDecorator<SortResponse> implements SortResponse
047{
048    private static final Asn1Decoder DECODER = new Asn1Decoder();
049
050    private int sortRespLen = 0;
051
052
053    /**
054     * Creates a new instance of SortResponseDecorator.
055     *
056     * @param codec the LDAP codec
057     */
058    public SortResponseDecorator( LdapApiService codec )
059    {
060        super( codec, new SortResponseControlImpl() );
061    }
062
063
064    /**
065     * Creates a new instance of SortResponseDecorator.
066     *
067     * @param codec the LDAP codec
068     * @param control the sort response control
069     */
070    public SortResponseDecorator( LdapApiService codec, SortResponse control )
071    {
072        super( codec, control );
073    }
074
075
076    /**
077     * @return the control length.
078     */
079    @Override
080    public int computeLength()
081    {
082        sortRespLen = 0;
083        valueLength = 0;
084
085        // result code value
086        sortRespLen += 1 + 1 + 1;
087
088        if ( getAttributeName() != null )
089        {
090            byte[] data = Strings.getBytesUtf8( getAttributeName() );
091            sortRespLen += 1 + TLV.getNbBytes( data.length ) + data.length;
092        }
093
094        valueLength = 1 + TLV.getNbBytes( sortRespLen ) + sortRespLen;
095
096        return valueLength;
097    }
098
099
100    @Override
101    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
102    {
103        if ( buffer == null )
104        {
105            throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
106        }
107
108        buffer.put( UniversalTag.SEQUENCE.getValue() );
109        buffer.put( TLV.getBytes( sortRespLen ) );
110
111        BerValue.encodeEnumerated( buffer, getSortResult().getVal() );
112
113        if ( getAttributeName() != null )
114        {
115            BerValue.encode( buffer, getAttributeName() );
116        }
117
118        return buffer;
119    }
120
121
122    /**
123     * {@inheritDoc}
124     */
125    @Override
126    public Asn1Object decode( byte[] controlBytes ) throws DecoderException
127    {
128        ByteBuffer buffer = ByteBuffer.wrap( controlBytes );
129        SortResponseContainer container = new SortResponseContainer( getCodecService(), this );
130        DECODER.decode( buffer, container );
131        return this;
132    }
133
134
135    /**
136     * {@inheritDoc}
137     */
138    @Override
139    public byte[] getValue()
140    {
141        if ( value == null )
142        {
143            try
144            {
145                computeLength();
146                ByteBuffer buffer = ByteBuffer.allocate( valueLength );
147
148                value = encode( buffer ).array();
149            }
150            catch ( Exception e )
151            {
152                return null;
153            }
154        }
155
156        return value;
157    }
158
159
160    @Override
161    public void setSortResult( SortResultCode result )
162    {
163        getDecorated().setSortResult( result );
164    }
165
166
167    @Override
168    public SortResultCode getSortResult()
169    {
170        return getDecorated().getSortResult();
171    }
172
173
174    @Override
175    public void setAttributeName( String attributeName )
176    {
177        getDecorated().setAttributeName( attributeName );
178    }
179
180
181    @Override
182    public String getAttributeName()
183    {
184        return getDecorated().getAttributeName();
185    }
186
187}