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.i18n.I18n;
024
025
026/**
027 * Node used for the application of arbitrary predicates on return candidates.
028 * Applies dynamic and programatic criteria for the selection of candidates for
029 * return. Nodes of this type may be introduced into the filter expression to
030 * provided the opportunity to constrain the search further without altering the
031 * search algorithm.
032 * 
033 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
034 */
035public abstract class AssertionNode extends AbstractExprNode
036{
037    /** The assertion or predicate to apply */
038    private final Assertion assertion;
039
040    /** Description of assertion for polish printouts */
041    private final String desc;
042
043
044    // ------------------------------------------------------------------------
045    // C O N S T R U C T O R S
046    // ------------------------------------------------------------------------
047
048    /**
049     * Creates an AssertionNode using an arbitrary candidate assertion.
050     * 
051     * @param assertion the arbitrary selection logic.
052     */
053    public AssertionNode( Assertion assertion )
054    {
055        this( assertion, "ASSERTION" );
056    }
057
058
059    /**
060     * Creates an AssertionNode using an arbitrary candidate assertion with a
061     * descriptions used for filter AST walker dumps.
062     * 
063     * @param assertion the arbitrary selection logic.
064     * @param desc the printout representation for filter prints.
065     */
066    public AssertionNode( Assertion assertion, String desc )
067    {
068        super( AssertionType.ASSERTION );
069        this.desc = desc;
070        this.assertion = assertion;
071
072        /*
073         * We never want this node to ever make it to the point of becoming a
074         * candidate for use in an enumeration so we set the scan count to the
075         * maximum value.
076         */
077        set( "count", Long.MAX_VALUE );
078    }
079
080
081    /**
082     * Gets the Assertion used by this assertion node.
083     * 
084     * @return the assertion used by this node
085     */
086    public Assertion getAssertion()
087    {
088        return assertion;
089    }
090
091
092    // ------------------------------------------------------------------------
093    // A B S T R A C T M E T H O D I M P L E M E N T A T I O N S
094    // ------------------------------------------------------------------------
095
096    /**
097     * Always returns true since an AssertionNode has no children.
098     * 
099     * @see ExprNode#isLeaf()
100     * @return true if the node is a leaf,false otherwise
101     */
102    @Override
103    public boolean isLeaf()
104    {
105        return true;
106    }
107
108
109    /**
110     * @see ExprNode#printRefinementToBuffer(StringBuilder) 
111     */
112    @Override
113    public StringBuilder printRefinementToBuffer( StringBuilder buf )
114    {
115        throw new UnsupportedOperationException( I18n.err( I18n.ERR_13304_ASSERTIONNODE_IN_REFINEMENT ) );
116    }
117
118
119    /**
120     * Tells if this Node is Schema aware.
121     * 
122     * @return true if the Node is SchemaAware
123     */
124    @Override
125    public boolean isSchemaAware()
126    {
127        return true;
128    }
129
130
131    /**
132     * {@inheritDoc}
133     */
134    @Override
135    public boolean equals( Object obj )
136    {
137        if ( obj == this )
138        {
139            return true;
140        }
141
142        if ( !( obj instanceof AssertionNode ) )
143        {
144            return false;
145        }
146        AssertionNode that = ( AssertionNode ) obj;
147        if ( assertion == null )
148        {
149            if ( that.assertion != null )
150            {
151                return false;
152            }
153        }
154        else
155        {
156            if ( !assertion.equals( that.assertion ) )
157            {
158                return false;
159            }
160        }
161        if ( desc == null )
162        {
163            if ( that.desc != null )
164            {
165                return false;
166            }
167        }
168        else
169        {
170            if ( !desc.equals( that.desc ) )
171            {
172                return false;
173            }
174        }
175        return super.equals( obj );
176    }
177
178
179    /**
180     * @see Object#hashCode()
181     * @return the instance's hash code 
182     */
183    @Override
184    public int hashCode()
185    {
186        int h = 37;
187
188        h = h * 17 + super.hashCode();
189        h = h * 17 + ( assertion != null ? assertion.hashCode() : 0 );
190        h = h * 17 + ( desc != null ? desc.hashCode() : 0 );
191
192        return h;
193    }
194
195
196    /**
197     * @see ExprNode#accept(
198     *FilterVisitor)
199     */
200    @Override
201    public Object accept( FilterVisitor visitor )
202    {
203        return visitor.visit( this );
204    }
205
206
207    /**
208     * @see Object#toString
209     * @return A string representing the AndNode
210     */
211    @Override
212    public String toString()
213    {
214        StringBuilder buf = new StringBuilder();
215
216        buf.append( "(@" );
217        buf.append( desc );
218        buf.append( super.toString() );
219        buf.append( ')' );
220
221        return buf.toString();
222    }
223}