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     */
020    package org.apache.directory.shared.ldap.codec.search;
021    
022    
023    import java.nio.BufferOverflowException;
024    import java.nio.ByteBuffer;
025    
026    import org.apache.directory.shared.asn1.ber.tlv.TLV;
027    import org.apache.directory.shared.asn1.ber.tlv.Value;
028    import org.apache.directory.shared.asn1.codec.EncoderException;
029    import org.apache.directory.shared.ldap.codec.AttributeValueAssertion;
030    import org.apache.directory.shared.ldap.codec.LdapConstants;
031    
032    
033    /**
034     * Object to store the filter. A filter is seen as a tree with a root.
035     * 
036     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037     * @version $Rev: 798550 $, $Date: 2009-07-28 16:54:01 +0200 (Mar, 28 jul 2009) $, 
038     */
039    public class AttributeValueAssertionFilter extends Filter
040    {
041        // ~ Instance fields
042        // ----------------------------------------------------------------------------
043    
044        /** The assertion. */
045        private AttributeValueAssertion assertion;
046    
047        /** The filter type */
048        private int filterType;
049    
050        /** The attributeValueAssertion length */
051        private int avaLength;
052    
053    
054        // ~ Constructors
055        // -------------------------------------------------------------------------------
056    
057        /**
058         * The constructor.
059         * 
060         * @param filterType The filter type
061         */
062        public AttributeValueAssertionFilter( int tlvId, int filterType )
063        {
064            super( tlvId );
065            this.filterType = filterType;
066        }
067    
068    
069        /**
070         * The constructor.
071         * 
072         * @param filterType The filter type
073         */
074        public AttributeValueAssertionFilter( int filterType )
075        {
076            super();
077            this.filterType = filterType;
078        }
079    
080    
081        // ~ Methods
082        // ------------------------------------------------------------------------------------
083    
084        /**
085         * Get the assertion
086         * 
087         * @return Returns the assertion.
088         */
089        public AttributeValueAssertion getAssertion()
090        {
091            return assertion;
092        }
093    
094    
095        /**
096         * Set the assertion
097         * 
098         * @param assertion The assertion to set.
099         */
100        public void setAssertion( AttributeValueAssertion assertion )
101        {
102            this.assertion = assertion;
103        }
104    
105    
106        /**
107         * Get the filter type
108         * 
109         * @return Returns the filterType.
110         */
111        public int getFilterType()
112        {
113            return filterType;
114        }
115    
116    
117        /**
118         * Set the filter type
119         * 
120         * @param filterType The filterType to set.
121         */
122        public void setFilterType( int filterType )
123        {
124            this.filterType = filterType;
125        }
126    
127    
128        /**
129         * Compute the AttributeValueFilter length
130         * 
131         * AttributeValueFilter :
132         * 
133         * 0xA(3, 5, 6, 8) L1
134         *  |
135         *  +--> 0x04 L2 attributeDesc
136         *  +--> 0x04 L3 assertionValue
137         *  
138         * 
139         * L2 = Length(attributeDesc)
140         * L3 = Length(assertionValue)
141         * L1 = 1 + Length(L2) + L2 
142         *      + 1 + Length(L3) + L3
143         * 
144         * Length(AttributeValueFilter) = Length(0xA?) + Length(L1)
145         *                                + 1 + Length(L2) + L2 
146         *                                + 1 + Length(L3) + L3 
147         */
148        public int computeLength()
149        {
150            avaLength = 0;
151            int attributeDescLength = assertion.getAttributeDesc().length();
152    
153            avaLength = 1 + TLV.getNbBytes( attributeDescLength ) + attributeDescLength;
154    
155            org.apache.directory.shared.ldap.entry.Value<?> assertionValue = assertion.getAssertionValue();
156    
157            int assertionValueLength = 0;
158    
159            assertionValueLength = assertionValue.getBytes().length;
160    
161            avaLength += 1 + TLV.getNbBytes( assertionValueLength ) + assertionValueLength;
162    
163            return 1 + TLV.getNbBytes( avaLength ) + avaLength;
164        }
165    
166    
167        /**
168         * Encode the AttributeValueAssertion Filters to a PDU. The 
169         * following filters are to be encoded :
170         *  - equality match 
171         *  - greater or equal
172         *  - less or equal
173         *  - approx match 
174         * 
175         * AttributeValueAssertion filters :
176         * 
177         * 0xA[3, 5, 6, 8] LL 
178         * 0x04 LL attributeDesc
179         * 0x04 LL assertionValue
180         * 
181         * @param buffer The buffer where to put the PDU
182         * @return The PDU.
183         */
184        public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
185        {
186            if ( buffer == null )
187            {
188                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
189            }
190    
191            try
192            {
193                // The AttributeValueAssertion Tag
194                switch ( filterType )
195                {
196                    case LdapConstants.EQUALITY_MATCH_FILTER:
197                        buffer.put( ( byte ) LdapConstants.EQUALITY_MATCH_FILTER_TAG );
198                        break;
199    
200                    case LdapConstants.LESS_OR_EQUAL_FILTER:
201                        buffer.put( ( byte ) LdapConstants.LESS_OR_EQUAL_FILTER_TAG );
202                        break;
203    
204                    case LdapConstants.GREATER_OR_EQUAL_FILTER:
205                        buffer.put( ( byte ) LdapConstants.GREATER_OR_EQUAL_FILTER_TAG );
206                        break;
207    
208                    case LdapConstants.APPROX_MATCH_FILTER:
209                        buffer.put( ( byte ) LdapConstants.APPROX_MATCH_FILTER_TAG );
210                        break;
211                }
212    
213                buffer.put( TLV.getBytes( avaLength ) );
214            }
215            catch ( BufferOverflowException boe )
216            {
217                throw new EncoderException( "The PDU buffer size is too small !" );
218            }
219    
220            // The attribute desc
221            Value.encode( buffer, assertion.getAttributeDesc() );
222    
223            // The assertion desc
224            if ( assertion.getAssertionValue().isBinary() )
225            {
226                Value.encode( buffer, assertion.getAssertionValue().getString() );
227            }
228            else
229            {
230                Value.encode( buffer, assertion.getAssertionValue().getBytes() );
231            }
232    
233            return buffer;
234        }
235    
236    
237        /**
238         * Return a string compliant with RFC 2254 representing an item filter
239         * 
240         * @return The item filter string
241         */
242        public String toString()
243        {
244            return assertion != null ? assertion.toStringRFC2254( filterType ) : "";
245        }
246    }