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.model.filter;
021
022
023import org.apache.directory.api.ldap.model.message.AliasDerefMode;
024import org.apache.directory.api.ldap.model.message.SearchScope;
025import org.apache.directory.api.ldap.model.name.Dn;
026
027
028/**
029 * Node used not to represent a published assertion but an assertion on the
030 * scope of the search.
031 * 
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 */
034public class ScopeNode extends AbstractExprNode
035{
036    /** the scope of this node */
037    private final SearchScope scope;
038
039    /** the search base */
040    private final Dn baseDn;
041
042    /** the search ID */
043    private final String baseId;
044
045    /** the alias dereferencing mode */
046    private final AliasDerefMode aliasDerefAliases;
047
048
049    /**
050     * Creates a new ScopeNode object.
051     * 
052     * @param aliasDerefAliases the alias dereferencing mode
053     * @param baseDn the search base
054     * @param baseId the search ID
055     * @param scope the search scope
056     */
057    public ScopeNode( AliasDerefMode aliasDerefAliases, Dn baseDn, String baseId, SearchScope scope )
058    {
059        super( AssertionType.SCOPE );
060        this.scope = scope;
061        this.baseDn = baseDn;
062        this.aliasDerefAliases = aliasDerefAliases;
063        this.baseId = baseId;
064        isSchemaAware = true;
065    }
066
067
068    /**
069     * Always returns true since a scope node has no children.
070     * 
071     * @see ExprNode#isLeaf()
072     * @return <code>true</code>
073     */
074    @Override
075    public boolean isLeaf()
076    {
077        return true;
078    }
079
080
081    /**
082     * Gets the search scope.
083     * 
084     * @return the search scope 
085     */
086    public SearchScope getScope()
087    {
088        return scope;
089    }
090
091
092    /**
093     * Gets the base dn.
094     * 
095     * @return the base dn
096     */
097    public Dn getBaseDn()
098    {
099        return baseDn;
100    }
101
102
103    /**
104     * Gets the base ID.
105     * 
106     * @return the base ID
107     */
108    public String getBaseId()
109    {
110        return baseId;
111    }
112
113
114    /**
115     * Gets the alias dereferencing mode type safe enumeration.
116     * 
117     * @return the alias dereferencing enumeration constant.
118     */
119    public AliasDerefMode getDerefAliases()
120    {
121        return aliasDerefAliases;
122    }
123
124
125    /**
126     * @see ExprNode#accept(
127     *FilterVisitor)
128     * 
129     * @param visitor the filter expression tree structure visitor
130     * @return The modified element
131     */
132    @Override
133    public Object accept( FilterVisitor visitor )
134    {
135        if ( visitor.canVisit( this ) )
136        {
137            return visitor.visit( this );
138        }
139        else
140        {
141            return null;
142        }
143    }
144
145
146    /**
147     * {@inheritDoc}
148     */
149    @Override
150    public boolean equals( Object obj )
151    {
152        if ( obj == this )
153        {
154            return true;
155        }
156
157        if ( ( obj == null ) || !( obj instanceof ScopeNode ) )
158        {
159            return false;
160        }
161        ScopeNode that = ( ScopeNode ) obj;
162        if ( aliasDerefAliases == null )
163        {
164            if ( that.aliasDerefAliases != null )
165            {
166                return false;
167            }
168        }
169        else
170        {
171            if ( !aliasDerefAliases.equals( that.aliasDerefAliases ) )
172            {
173                return false;
174            }
175        }
176        if ( baseDn == null )
177        {
178            if ( that.baseDn != null )
179            {
180                return false;
181            }
182        }
183        else
184        {
185            if ( !baseDn.equals( that.baseDn ) )
186            {
187                return false;
188            }
189        }
190        if ( scope.getScope() != that.scope.getScope() )
191        {
192            return false;
193        }
194        return super.equals( obj );
195    }
196
197
198    /**
199     * @see Object#hashCode()
200     * @return the instance's hash code 
201     */
202    @Override
203    public int hashCode()
204    {
205        int h = 37;
206
207        h = h * 17 + super.hashCode();
208        h = h * 17 + ( aliasDerefAliases != null ? aliasDerefAliases.hashCode() : 0 );
209        h = h * 17 + ( baseDn != null ? baseDn.hashCode() : 0 );
210        h = h * 17 + scope.getScope();
211
212        return h;
213    }
214
215
216    /**
217     * @see Object#toString()
218     * @return A string representing the AndNode
219     */
220    @Override
221    public String toString()
222    {
223        StringBuilder buf = new StringBuilder();
224
225        buf.append( "(#{" );
226
227        switch ( scope )
228        {
229            case OBJECT:
230                buf.append( "OBJECT_SCOPE" );
231
232                break;
233
234            case ONELEVEL:
235                buf.append( "ONE_LEVEL_SCOPE" );
236
237                break;
238
239            case SUBTREE:
240                buf.append( "SUBTREE_SCOPE (Estimated)" );
241
242                break;
243
244            default:
245                buf.append( "UNKNOWN" );
246                break;
247        }
248
249        buf.append( ", '" );
250        buf.append( baseDn );
251        buf.append( "', " );
252        buf.append( aliasDerefAliases );
253        buf.append( "}" );
254        buf.append( super.toString() );
255        buf.append( ')' );
256
257        return buf.toString();
258    }
259}