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 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     * 
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    public byte[] getValue()
139    {
140        if ( value == null )
141        {
142            try
143            {
144                computeLength();
145                ByteBuffer buffer = ByteBuffer.allocate( valueLength );
146
147                value = encode( buffer ).array();
148            }
149            catch ( Exception e )
150            {
151                return null;
152            }
153        }
154
155        return value;
156    }
157
158
159    @Override
160    public void setSortResult( SortResultCode result )
161    {
162        getDecorated().setSortResult( result );
163    }
164
165
166    @Override
167    public SortResultCode getSortResult()
168    {
169        return getDecorated().getSortResult();
170    }
171
172
173    @Override
174    public void setAttributeName( String attributeName )
175    {
176        getDecorated().setAttributeName( attributeName );
177    }
178
179
180    @Override
181    public String getAttributeName()
182    {
183        return getDecorated().getAttributeName();
184    }
185
186}