1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.directory.api.ldap.codec.search;
21
22
23 import java.nio.BufferOverflowException;
24 import java.nio.ByteBuffer;
25
26 import org.apache.directory.api.asn1.EncoderException;
27 import org.apache.directory.api.asn1.ber.tlv.BerValue;
28 import org.apache.directory.api.asn1.ber.tlv.TLV;
29 import org.apache.directory.api.i18n.I18n;
30 import org.apache.directory.api.ldap.codec.AttributeValueAssertion;
31 import org.apache.directory.api.ldap.codec.api.LdapCodecConstants;
32
33
34 /**
35 * Object to store the filter. A filter is seen as a tree with a root.
36 *
37 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38 */
39 public class AttributeValueAssertionFilter extends Filter
40 {
41 /** The assertion. */
42 private AttributeValueAssertion assertion;
43
44 /** The filter type */
45 private int filterType;
46
47 /** The attributeValueAssertion length */
48 private int avaLength;
49
50
51 /**
52 * The constructor.
53 *
54 * @param tlvId The TLV identifier
55 * @param filterType The filter type
56 */
57 public AttributeValueAssertionFilter( int tlvId, int filterType )
58 {
59 super( tlvId );
60 this.filterType = filterType;
61 }
62
63
64 /**
65 * The constructor.
66 *
67 * @param filterType The filter type
68 */
69 public AttributeValueAssertionFilter( int filterType )
70 {
71 super();
72 this.filterType = filterType;
73 }
74
75
76 /**
77 * Get the assertion
78 *
79 * @return Returns the assertion.
80 */
81 public AttributeValueAssertion getAssertion()
82 {
83 return assertion;
84 }
85
86
87 /**
88 * Set the assertion
89 *
90 * @param assertion The assertion to set.
91 */
92 public void setAssertion( AttributeValueAssertion assertion )
93 {
94 this.assertion = assertion;
95 }
96
97
98 /**
99 * Get the filter type
100 *
101 * @return Returns the filterType.
102 */
103 public int getFilterType()
104 {
105 return filterType;
106 }
107
108
109 /**
110 * Set the filter type
111 *
112 * @param filterType The filterType to set.
113 */
114 public void setFilterType( int filterType )
115 {
116 this.filterType = filterType;
117 }
118
119
120 /**
121 * Compute the AttributeValueFilter length
122 * <br>
123 * AttributeValueFilter :
124 * <pre>
125 * 0xA(3, 5, 6, 8) L1
126 * |
127 * +--> 0x04 L2 attributeDesc
128 * +--> 0x04 L3 assertionValue
129 *
130 *
131 * L2 = Length(attributeDesc)
132 * L3 = Length(assertionValue)
133 * L1 = 1 + Length(L2) + L2
134 * + 1 + Length(L3) + L3
135 *
136 * Length(AttributeValueFilter) = Length(0xA?) + Length(L1)
137 * + 1 + Length(L2) + L2
138 * + 1 + Length(L3) + L3
139 * </pre>
140 *
141 * @return The encoded length
142 */
143 @Override
144 public int computeLength()
145 {
146 avaLength = 0;
147 int attributeDescLength = assertion.getAttributeDesc().length();
148
149 avaLength = 1 + TLV.getNbBytes( attributeDescLength ) + attributeDescLength;
150
151 byte[] assertionBytes = assertion.getAssertion();
152
153 int assertionValueLength;
154
155 assertionValueLength = assertionBytes.length;
156
157 avaLength += 1 + TLV.getNbBytes( assertionValueLength ) + assertionValueLength;
158
159 return 1 + TLV.getNbBytes( avaLength ) + avaLength;
160 }
161
162
163 /**
164 * Encode the AttributeValueAssertion Filters to a PDU. The
165 * following filters are to be encoded :
166 * <ul>
167 * <li>equality match</li>
168 * <li>greater or equal</li>
169 * <li>less or equal</li>
170 * <li>approx match</li>
171 * </ul>
172 *
173 * AttributeValueAssertion filters :
174 * <br>
175 * <pre>
176 * 0xA[3, 5, 6, 8] LL
177 * 0x04 LL attributeDesc
178 * 0x04 LL assertionValue
179 * </pre>
180 *
181 * @param buffer The buffer where to put the PDU
182 * @return The PDU.
183 */
184 @Override
185 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
186 {
187 if ( buffer == null )
188 {
189 throw new EncoderException( I18n.err( I18n.ERR_08000_CANNOT_PUT_A_PDU_IN_NULL_BUFFER ) );
190 }
191
192 try
193 {
194 // The AttributeValueAssertion Tag
195 switch ( filterType )
196 {
197 case LdapCodecConstants.EQUALITY_MATCH_FILTER:
198 buffer.put( ( byte ) LdapCodecConstants.EQUALITY_MATCH_FILTER_TAG );
199 break;
200
201 case LdapCodecConstants.LESS_OR_EQUAL_FILTER:
202 buffer.put( ( byte ) LdapCodecConstants.LESS_OR_EQUAL_FILTER_TAG );
203 break;
204
205 case LdapCodecConstants.GREATER_OR_EQUAL_FILTER:
206 buffer.put( ( byte ) LdapCodecConstants.GREATER_OR_EQUAL_FILTER_TAG );
207 break;
208
209 case LdapCodecConstants.APPROX_MATCH_FILTER:
210 buffer.put( ( byte ) LdapCodecConstants.APPROX_MATCH_FILTER_TAG );
211 break;
212
213 default:
214 throw new IllegalArgumentException( I18n.err( I18n.ERR_05503_UNEXPECTED_FILTER_TYPE, filterType ) );
215 }
216
217 buffer.put( TLV.getBytes( avaLength ) );
218 }
219 catch ( BufferOverflowException boe )
220 {
221 throw new EncoderException( I18n.err( I18n.ERR_08212_PDU_BUFFER_TOO_SMALL ), boe );
222 }
223
224 // The attribute desc
225 BerValue.encode( buffer, assertion.getAttributeDesc() );
226
227 // The assertion desc
228 BerValue.encode( buffer, assertion.getAssertion() );
229
230 return buffer;
231 }
232
233
234 /**
235 * Return a string compliant with RFC 2254 representing an item filter
236 *
237 * @return The item filter string
238 */
239 @Override
240 public String toString()
241 {
242 return assertion != null ? assertion.toStringRFC2254( filterType ) : "";
243 }
244 }