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        isSchemaAware = true;
058    }
059
060
061    /**
062     * Creates an AssertionNode using an arbitrary candidate assertion with a
063     * descriptions used for filter AST walker dumps.
064     * 
065     * @param assertion the arbitrary selection logic.
066     * @param desc the printout representation for filter prints.
067     */
068    public AssertionNode( Assertion assertion, String desc )
069    {
070        super( AssertionType.ASSERTION );
071        this.desc = desc;
072        this.assertion = assertion;
073
074        /*
075         * We never want this node to ever make it to the point of becoming a
076         * candidate for use in an enumeration so we set the scan count to the
077         * maximum value.
078         */
079        set( "count", Long.MAX_VALUE );
080    }
081
082
083    /**
084     * Gets the Assertion used by this assertion node.
085     * 
086     * @return the assertion used by this node
087     */
088    public Assertion getAssertion()
089    {
090        return assertion;
091    }
092
093
094    // ------------------------------------------------------------------------
095    // 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
096    // ------------------------------------------------------------------------
097
098    /**
099     * Always returns true since an AssertionNode has no children.
100     * 
101     * @see ExprNode#isLeaf()
102     * @return true if the node is a leaf,false otherwise
103     */
104    @Override
105    public boolean isLeaf()
106    {
107        return true;
108    }
109
110
111    /**
112     * @see ExprNode#printRefinementToBuffer(StringBuilder) 
113     */
114    @Override
115    public StringBuilder printRefinementToBuffer( StringBuilder buf )
116    {
117        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04145 ) );
118    }
119
120
121    /**
122     * {@inheritDoc}
123     */
124    @Override
125    public boolean equals( Object obj )
126    {
127        if ( obj == this )
128        {
129            return true;
130        }
131
132        if ( ( obj == null ) || !( obj instanceof AssertionNode ) )
133        {
134            return false;
135        }
136        AssertionNode that = ( AssertionNode ) obj;
137        if ( assertion == null )
138        {
139            if ( that.assertion != null )
140            {
141                return false;
142            }
143        }
144        else
145        {
146            if ( !assertion.equals( that.assertion ) )
147            {
148                return false;
149            }
150        }
151        if ( desc == null )
152        {
153            if ( that.desc != null )
154            {
155                return false;
156            }
157        }
158        else
159        {
160            if ( !desc.equals( that.desc ) )
161            {
162                return false;
163            }
164        }
165        return super.equals( obj );
166    }
167
168
169    /**
170     * @see Object#hashCode()
171     * @return the instance's hash code 
172     */
173    @Override
174    public int hashCode()
175    {
176        int h = 37;
177
178        h = h * 17 + super.hashCode();
179        h = h * 17 + ( assertion != null ? assertion.hashCode() : 0 );
180        h = h * 17 + ( desc != null ? desc.hashCode() : 0 );
181
182        return h;
183    }
184
185
186    /**
187     * @see ExprNode#accept(
188     *FilterVisitor)
189     */
190    @Override
191    public Object accept( FilterVisitor visitor )
192    {
193        return visitor.visit( this );
194    }
195
196
197    /**
198     * @see Object#toString
199     * @return A string representing the AndNode
200     */
201    @Override
202    public String toString()
203    {
204        StringBuilder buf = new StringBuilder();
205
206        buf.append( "(@" );
207        buf.append( desc );
208        buf.append( super.toString() );
209        buf.append( ')' );
210
211        return buf.toString();
212    }
213}