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; 024import java.util.ArrayList; 025import java.util.List; 026 027import org.apache.directory.api.asn1.Asn1Object; 028import org.apache.directory.api.asn1.DecoderException; 029import org.apache.directory.api.asn1.EncoderException; 030import org.apache.directory.api.asn1.ber.Asn1Decoder; 031import org.apache.directory.api.asn1.ber.tlv.BerValue; 032import org.apache.directory.api.asn1.ber.tlv.TLV; 033import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 034import org.apache.directory.api.asn1.util.Asn1StringUtils; 035import org.apache.directory.api.i18n.I18n; 036import org.apache.directory.api.ldap.codec.api.ControlDecorator; 037import org.apache.directory.api.ldap.codec.api.LdapApiService; 038import org.apache.directory.api.ldap.model.message.controls.SortKey; 039import org.apache.directory.api.ldap.model.message.controls.SortRequest; 040import org.apache.directory.api.ldap.model.message.controls.SortRequestControlImpl; 041import org.apache.directory.api.util.Strings; 042 043 044/** 045 * Decorator of SortRequestControl. 046 * 047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 048 */ 049public class SortRequestDecorator extends ControlDecorator<SortRequest> implements SortRequest 050{ 051 private static final Asn1Decoder DECODER = new Asn1Decoder(); 052 053 private int sortReqLen = 0; 054 055 private List<Integer> sortKeyLenList = new ArrayList<>(); 056 057 /** ASN.1 BER tag for the forward ordering rule */ 058 public static final int ORDERING_RULE_TAG = 0x80; 059 060 /** ASN.1 BER tag for the backward ordering rule */ 061 public static final int REVERSE_ORDER_TAG = 0x81; 062 063 064 /** 065 * Creates a new instance of SortRequestDecorator. 066 * 067 * @param codec the LDAP codec 068 */ 069 public SortRequestDecorator( LdapApiService codec ) 070 { 071 super( codec, new SortRequestControlImpl() ); 072 } 073 074 075 /** 076 * Creates a new instance of SortRequestDecorator. 077 * 078 * @param codec the LDAP codec 079 * @param control the control instance 080 */ 081 public SortRequestDecorator( LdapApiService codec, SortRequest control ) 082 { 083 super( codec, control ); 084 } 085 086 087 /** 088 * @return the control length. 089 */ 090 @Override 091 public int computeLength() 092 { 093 sortReqLen = 0; 094 sortKeyLenList.clear(); 095 valueLength = 0; 096 097 for ( SortKey sk : getSortKeys() ) 098 { 099 int skLen = 0; 100 101 byte[] atBytes = Strings.getBytesUtf8( sk.getAttributeTypeDesc() ); 102 skLen += 1 + TLV.getNbBytes( atBytes.length ) + atBytes.length; 103 104 if ( sk.getMatchingRuleId() != null ) 105 { 106 byte[] mrBytes = Strings.getBytesUtf8( sk.getMatchingRuleId() ); 107 skLen += 1 + TLV.getNbBytes( mrBytes.length ) + mrBytes.length; 108 } 109 110 if ( sk.isReverseOrder() ) 111 { 112 // reverse order flag 113 skLen += 1 + 1 + 1; 114 } 115 116 sortKeyLenList.add( skLen ); 117 118 // the sequence 119 sortReqLen += 1 + TLV.getNbBytes( skLen ) + skLen; 120 } 121 122 valueLength = 1 + TLV.getNbBytes( sortReqLen ) + sortReqLen; 123 124 return valueLength; 125 } 126 127 128 @Override 129 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 130 { 131 if ( buffer == null ) 132 { 133 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 134 } 135 136 buffer.put( UniversalTag.SEQUENCE.getValue() ); 137 buffer.put( TLV.getBytes( sortReqLen ) ); 138 139 List<SortKey> lst = getSortKeys(); 140 141 for ( int i = 0; i < lst.size(); i++ ) 142 { 143 SortKey sk = lst.get( i ); 144 int skLen = sortKeyLenList.get( i ); 145 146 buffer.put( UniversalTag.SEQUENCE.getValue() ); 147 buffer.put( TLV.getBytes( skLen ) ); 148 149 BerValue.encode( buffer, sk.getAttributeTypeDesc() ); 150 151 String mrId = sk.getMatchingRuleId(); 152 if ( mrId != null ) 153 { 154 buffer.put( ( byte ) ORDERING_RULE_TAG ); 155 byte[] value = Asn1StringUtils.getBytesUtf8( mrId ); 156 157 buffer.put( TLV.getBytes( value.length ) ); 158 buffer.put( value ); 159 } 160 161 if ( sk.isReverseOrder() ) 162 { 163 buffer.put( ( byte ) REVERSE_ORDER_TAG ); 164 buffer.put( ( byte ) 0x01 ); 165 buffer.put( BerValue.TRUE_VALUE ); 166 } 167 } 168 169 return buffer; 170 } 171 172 173 @Override 174 public Asn1Object decode( byte[] controlBytes ) throws DecoderException 175 { 176 ByteBuffer buffer = ByteBuffer.wrap( controlBytes ); 177 SortRequestContainer container = new SortRequestContainer( getCodecService(), this ); 178 DECODER.decode( buffer, container ); 179 return this; 180 } 181 182 183 /** 184 * {@inheritDoc} 185 */ 186 @Override 187 public byte[] getValue() 188 { 189 if ( value == null ) 190 { 191 try 192 { 193 computeLength(); 194 ByteBuffer buffer = ByteBuffer.allocate( valueLength ); 195 196 value = encode( buffer ).array(); 197 } 198 catch ( Exception e ) 199 { 200 return null; 201 } 202 } 203 204 return value; 205 } 206 207 208 @Override 209 public void setSortKeys( List<SortKey> sortKeys ) 210 { 211 getDecorated().setSortKeys( sortKeys ); 212 } 213 214 215 @Override 216 public List<SortKey> getSortKeys() 217 { 218 return getDecorated().getSortKeys(); 219 } 220 221 222 @Override 223 public void addSortKey( SortKey sortKey ) 224 { 225 getDecorated().addSortKey( sortKey ); 226 } 227 228}