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.schema.AttributeType;
024
025
026/**
027 * Abstract base class for leaf nodes within the expression filter tree.
028 * 
029 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
030 */
031public abstract class LeafNode extends AbstractExprNode
032{
033    /** attributeType on which this leaf is based */
034    protected AttributeType attributeType;
035
036    /** attribute on which this leaf is based */
037    protected String attribute;
038
039
040    /**
041     * Creates a leaf node.
042     * 
043     * @param attributeType the attribute this node is based on
044     * @param assertionType the type of this leaf node
045     */
046    protected LeafNode( AttributeType attributeType, AssertionType assertionType )
047    {
048        super( assertionType );
049        this.attributeType = attributeType;
050
051        if ( attributeType != null )
052        {
053            this.attribute = attributeType.getName();
054            isSchemaAware = true;
055        }
056        else
057        {
058            throw new NullPointerException( "Cannot create a Node with a null Attribute" );
059        }
060    }
061
062
063    /**
064     * Creates a leaf node.
065     * 
066     * @param attribute the attribute this node is based on
067     * @param assertionType the type of this leaf node
068     */
069    protected LeafNode( String attribute, AssertionType assertionType )
070    {
071        super( assertionType );
072        this.attributeType = null;
073        this.attribute = attribute;
074        isSchemaAware = false;
075    }
076
077
078    /**
079     * Gets whether this node is a leaf - the answer is always true here.
080     * 
081     * @return true always
082     */
083    public final boolean isLeaf()
084    {
085        return true;
086    }
087
088
089    /**
090     * Gets the attributeType this leaf node is based on.
091     * 
092     * @return the attributeType asserted
093     */
094    public final AttributeType getAttributeType()
095    {
096        return attributeType;
097    }
098
099
100    /**
101     * Gets the attribute this leaf node is based on.
102     * 
103     * @return the attribute asserted
104     */
105    public final String getAttribute()
106    {
107        return attribute;
108    }
109
110
111    /**
112     * Sets the attributeType this leaf node is based on.
113     * 
114     * @param attributeType the attributeType that is asserted by this filter node
115     */
116    public void setAttributeType( AttributeType attributeType )
117    {
118        this.attributeType = attributeType;
119
120        if ( attributeType != null )
121        {
122            attribute = attributeType.getName();
123            isSchemaAware = true;
124        }
125    }
126
127
128    /**
129     * Sets the attribute this leaf node is based on.
130     * 
131     * @param attribute the attribute that is asserted by this filter node
132     */
133    public void setAttribute( String attribute )
134    {
135        this.attribute = attribute;
136        isSchemaAware = false;
137    }
138
139
140    /**
141     * @see ExprNode#accept(
142     *FilterVisitor)
143     * 
144     * @param visitor the filter expression tree structure visitor
145     * @return The modified element
146     */
147    public final Object accept( FilterVisitor visitor )
148    {
149        if ( visitor.canVisit( this ) )
150        {
151            return visitor.visit( this );
152        }
153        else
154        {
155            return null;
156        }
157    }
158
159
160    /**
161     * @see Object#hashCode()
162     * @return the instance's hash code 
163     */
164    public int hashCode()
165    {
166        int h = 37;
167
168        h = h * 17 + super.hashCode();
169
170        if ( attributeType != null )
171        {
172            h = h * 17 + attributeType.hashCode();
173        }
174        else
175        {
176            h = h * 17 + attribute.hashCode();
177        }
178
179        return h;
180    }
181
182
183    /**
184     * @see java.lang.Object#equals(java.lang.Object)
185     */
186    public boolean equals( Object other )
187    {
188        if ( this == other )
189        {
190            return true;
191        }
192
193        if ( !( other instanceof LeafNode ) )
194        {
195            return false;
196        }
197
198        LeafNode otherNode = ( LeafNode ) other;
199
200        if ( other.getClass() != this.getClass() )
201        {
202            return false;
203        }
204
205        if ( attributeType != null )
206        {
207            return attributeType.equals( otherNode.getAttributeType() );
208        }
209        else
210        {
211            return attribute.equalsIgnoreCase( otherNode.getAttribute() );
212        }
213    }
214}