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 *    https://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    }
065
066
067    /**
068     * Always returns true since a scope node has no children.
069     * 
070     * @see ExprNode#isLeaf()
071     * @return <code>true</code>
072     */
073    @Override
074    public boolean isLeaf()
075    {
076        return true;
077    }
078
079
080    /**
081     * Gets the search scope.
082     * 
083     * @return the search scope 
084     */
085    public SearchScope getScope()
086    {
087        return scope;
088    }
089
090
091    /**
092     * Gets the base dn.
093     * 
094     * @return the base dn
095     */
096    public Dn getBaseDn()
097    {
098        return baseDn;
099    }
100
101
102    /**
103     * Gets the base ID.
104     * 
105     * @return the base ID
106     */
107    public String getBaseId()
108    {
109        return baseId;
110    }
111
112
113    /**
114     * Gets the alias dereferencing mode type safe enumeration.
115     * 
116     * @return the alias dereferencing enumeration constant.
117     */
118    public AliasDerefMode getDerefAliases()
119    {
120        return aliasDerefAliases;
121    }
122
123
124    /**
125     * @see ExprNode#accept(
126     *FilterVisitor)
127     * 
128     * @param visitor the filter expression tree structure visitor
129     * @return The modified element
130     */
131    @Override
132    public Object accept( FilterVisitor visitor )
133    {
134        if ( visitor.canVisit( this ) )
135        {
136            return visitor.visit( this );
137        }
138        else
139        {
140            return null;
141        }
142    }
143
144
145    /**
146     * Tells if this Node is Schema aware.
147     * 
148     * @return true if the Node is SchemaAware
149     */
150    @Override
151    public boolean isSchemaAware()
152    {
153        return true;
154    }
155
156
157    /**
158     * {@inheritDoc}
159     */
160    @Override
161    public boolean equals( Object obj )
162    {
163        if ( obj == this )
164        {
165            return true;
166        }
167
168        if ( !( obj instanceof ScopeNode ) )
169        {
170            return false;
171        }
172        ScopeNode that = ( ScopeNode ) obj;
173        if ( aliasDerefAliases == null )
174        {
175            if ( that.aliasDerefAliases != null )
176            {
177                return false;
178            }
179        }
180        else
181        {
182            if ( !aliasDerefAliases.equals( that.aliasDerefAliases ) )
183            {
184                return false;
185            }
186        }
187        if ( baseDn == null )
188        {
189            if ( that.baseDn != null )
190            {
191                return false;
192            }
193        }
194        else
195        {
196            if ( !baseDn.equals( that.baseDn ) )
197            {
198                return false;
199            }
200        }
201        if ( scope.getScope() != that.scope.getScope() )
202        {
203            return false;
204        }
205        return super.equals( obj );
206    }
207
208
209    /**
210     * @see Object#hashCode()
211     * @return the instance's hash code 
212     */
213    @Override
214    public int hashCode()
215    {
216        int h = 37;
217
218        h = h * 17 + super.hashCode();
219        h = h * 17 + ( aliasDerefAliases != null ? aliasDerefAliases.hashCode() : 0 );
220        h = h * 17 + ( baseDn != null ? baseDn.hashCode() : 0 );
221        h = h * 17 + scope.getScope();
222
223        return h;
224    }
225
226
227    /**
228     * @see Object#toString()
229     * @return A string representing the AndNode
230     */
231    @Override
232    public String toString()
233    {
234        StringBuilder buf = new StringBuilder();
235
236        buf.append( "(#{" );
237
238        switch ( scope )
239        {
240            case OBJECT:
241                buf.append( "OBJECT_SCOPE" );
242
243                break;
244
245            case ONELEVEL:
246                buf.append( "ONE_LEVEL_SCOPE" );
247
248                break;
249
250            case SUBTREE:
251                buf.append( "SUBTREE_SCOPE (Estimated)" );
252
253                break;
254
255            default:
256                buf.append( "UNKNOWN" );
257                break;
258        }
259
260        buf.append( ", '" );
261        buf.append( baseDn );
262        buf.append( "', " );
263        buf.append( aliasDerefAliases );
264        buf.append( "}" );
265        buf.append( super.toString() );
266        buf.append( ')' );
267
268        return buf.toString();
269    }
270}