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.shared.ldap.codec.search;
021
022
023import java.nio.ByteBuffer;
024import java.util.ArrayList;
025import java.util.List;
026
027import org.apache.directory.shared.asn1.DecoderException;
028import org.apache.directory.shared.asn1.EncoderException;
029import org.apache.directory.shared.i18n.I18n;
030
031
032/**
033 * This Filter abstract class is used to store a set of filters used by
034 * OR/AND/NOT filters.
035 * 
036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037 */
038public abstract class ConnectorFilter extends Filter
039{
040    // ~ Instance fields
041    // ----------------------------------------------------------------------------
042
043    /** The set of filters used by And/Or filters */
044    protected List<Filter> filterSet;
045
046    /** The filters length */
047    protected int filtersLength;
048
049
050    // ~ Constructors
051    // -------------------------------------------------------------------------------
052
053    /**
054     * The constructor. We wont initialize the ArrayList as it may not be used.
055     */
056    public ConnectorFilter( int tlvId )
057    {
058        super( tlvId );
059    }
060
061
062    /**
063     * The constructor. We wont initialize the ArrayList as it may not be used.
064     */
065    public ConnectorFilter()
066    {
067        super();
068    }
069
070
071    // ~ Methods
072    // ------------------------------------------------------------------------------------
073
074    /**
075     * Add a new Filter to the list.
076     * 
077     * @param filter The filter to add
078     */
079    public void addFilter( Filter filter ) throws DecoderException
080    {
081
082        if ( filterSet == null )
083        {
084            filterSet = new ArrayList<Filter>();
085        }
086
087        filterSet.add( filter );
088    }
089
090
091    /**
092     * Get the list of filters stored in the composite filter
093     * 
094     * @return And array of filters
095     */
096    public List<Filter> getFilterSet()
097    {
098        return filterSet;
099    }
100
101
102    /**
103     * Compute the ConnectorFilter length Length(ConnectorFilter) =
104     * sum(filterSet.computeLength())
105     */
106    public int computeLength()
107    {
108        int connectorFilterLength = 0;
109
110        if ( ( filterSet != null ) && ( filterSet.size() != 0 ) )
111        {
112            for ( Filter filter:filterSet )
113            {
114                connectorFilterLength += filter.computeLength();
115            }
116        }
117
118        return connectorFilterLength;
119    }
120
121
122    /**
123     * Encode the ConnectorFilter message to a PDU. 
124     * 
125     * ConnectorFilter :
126     * filter.encode() ... filter.encode()
127     * 
128     * @param buffer The buffer where to put the PDU
129     * @return The PDU.
130     */
131    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
132    {
133        if ( buffer == null )
134        {
135            throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
136        }
137
138        // encode each filter
139        if ( ( filterSet != null ) && ( filterSet.size() != 0 ) )
140        {
141            for ( Filter filter:filterSet )
142            {
143                filter.encode( buffer );
144            }
145        }
146
147        return buffer;
148    }
149
150
151    /**
152     * Return a string compliant with RFC 2254 representing a composite filter,
153     * one of AND, OR and NOT
154     * 
155     * @return The composite filter string
156     */
157    public String toString()
158    {
159        StringBuffer sb = new StringBuffer();
160
161        if ( ( filterSet != null ) && ( filterSet.size() != 0 ) )
162        {
163            for ( Filter filter : filterSet )
164            {
165                sb.append( '(' ).append( filter ).append( ')' );
166            }
167        }
168
169        return sb.toString();
170    }
171}