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