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     * Makes a full clone in new memory space of the current node and children
085     * 
086     * @return the clone
087     */
088    @Override
089    public ExprNode clone()
090    {
091        return ( ExprNode ) super.clone();
092    }
093
094
095    /**
096     * Gets the Assertion used by this assertion node.
097     * 
098     * @return the assertion used by this node
099     */
100    public Assertion getAssertion()
101    {
102        return assertion;
103    }
104
105
106    // ------------------------------------------------------------------------
107    // 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
108    // ------------------------------------------------------------------------
109
110    /**
111     * Always returns true since an AssertionNode has no children.
112     * 
113     * @see ExprNode#isLeaf()
114     * @return true if the node is a leaf,false otherwise
115     */
116    public boolean isLeaf()
117    {
118        return true;
119    }
120
121
122    /**
123     * @see ExprNode#printRefinementToBuffer(StringBuilder) 
124     */
125    public StringBuilder printRefinementToBuffer( StringBuilder buf ) throws UnsupportedOperationException
126    {
127        throw new UnsupportedOperationException( I18n.err( I18n.ERR_04145 ) );
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 == null ) || !( 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    public Object accept( FilterVisitor visitor )
201    {
202        return visitor.visit( this );
203    }
204
205
206    /**
207     * @see Object#toString
208     * @return A string representing the AndNode
209     */
210    public String toString()
211    {
212        StringBuilder buf = new StringBuilder();
213
214        buf.append( "(@" );
215        buf.append( desc );
216        buf.append( super.toString() );
217        buf.append( ')' );
218
219        return buf.toString();
220    }
221}