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.entry.Value;
024import org.apache.directory.api.ldap.model.schema.AttributeType;
025
026
027/**
028 * Filter expression tree node for extensible assertions.
029 * 
030 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
031 */
032public class ExtensibleNode extends LeafNode
033{
034    /** The value of the attribute to match for */
035    private Value<?> value;
036
037    /** The matching rules id */
038    private String matchingRuleId;
039
040    /** The name of the dn attributes */
041    private boolean dnAttributes = false;
042
043
044    /**
045     * Creates a new emptyExtensibleNode object.
046     * 
047     * @param attributeType the attributeType associated with this node
048     */
049    public ExtensibleNode( AttributeType attributeType )
050    {
051        super( attributeType, AssertionType.EXTENSIBLE );
052
053        dnAttributes = false;
054    }
055
056
057    /**
058     * Creates a new emptyExtensibleNode object.
059     * 
060     * @param attribute the attribute associated with this node
061     */
062    public ExtensibleNode( String attribute )
063    {
064        super( attribute, AssertionType.EXTENSIBLE );
065
066        dnAttributes = false;
067    }
068
069
070    /**
071     * Creates a new ExtensibleNode object.
072     * 
073     * @param attributeType the attributeType used for the extensible assertion
074     * @param value the value to match for
075     * @param matchingRuleId the OID of the matching rule
076     * @param dnAttributes the dn attributes
077     */
078    public ExtensibleNode( AttributeType attributeType, Value<?> value, String matchingRuleId, boolean dnAttributes )
079    {
080        super( attributeType, AssertionType.EXTENSIBLE );
081
082        this.value = value;
083        this.matchingRuleId = matchingRuleId;
084        this.dnAttributes = dnAttributes;
085    }
086
087
088    /**
089     * Creates a new ExtensibleNode object.
090     * 
091     * @param attribute the attribute used for the extensible assertion
092     * @param value the value to match for
093     * @param matchingRuleId the OID of the matching rule
094     * @param dnAttributes the dn attributes
095     */
096    public ExtensibleNode( String attribute, Value<?> value, String matchingRuleId, boolean dnAttributes )
097    {
098        super( attribute, AssertionType.EXTENSIBLE );
099
100        this.value = value;
101        this.matchingRuleId = matchingRuleId;
102        this.dnAttributes = dnAttributes;
103    }
104
105
106    /**
107     * Makes a full clone in new memory space of the current node and children
108     * 
109     * @return the clone
110     */
111    @Override
112    public ExprNode clone()
113    {
114        ExprNode clone = super.clone();
115
116        // Copy the value
117        if ( value != null )
118        {
119            ( ( ExtensibleNode ) clone ).value = value.clone();
120        }
121
122        return clone;
123    }
124
125
126    /**
127     * Gets the Dn attributes.
128     * 
129     * @return the dn attributes
130     */
131    public boolean hasDnAttributes()
132    {
133        return dnAttributes;
134    }
135
136
137    /**
138     * Set the dnAttributes flag
139     *
140     * @param dnAttributes The flag to set
141     */
142    public void setDnAttributes( boolean dnAttributes )
143    {
144        this.dnAttributes = dnAttributes;
145    }
146
147
148    /**
149     * Gets the matching rule id as an OID string.
150     * 
151     * @return the OID
152     */
153    public String getMatchingRuleId()
154    {
155        return matchingRuleId;
156    }
157
158
159    /**
160     * Sets the matching rule id as an OID string.
161     * 
162     * @param matchingRuleId The maching rule ID
163     */
164    public void setMatchingRuleId( String matchingRuleId )
165    {
166        this.matchingRuleId = matchingRuleId;
167    }
168
169
170    /**
171     * Gets the value.
172     * 
173     * @return the value
174     */
175    public final Value<?> getValue()
176    {
177        return value;
178    }
179
180
181    /** 
182     * @return representation of value, escaped for use in a filter if required 
183     */
184    public Value<?> getEscapedValue()
185    {
186        if ( value.isHumanReadable() )
187        {
188            return escapeFilterValue( value );
189        }
190
191        return value;
192    }
193
194
195    /**
196     * Sets the value.
197     * 
198     * @param value the value
199     */
200    public final void setValue( Value<?> value )
201    {
202        this.value = value;
203    }
204
205
206    /**
207     * {@inheritDoc}
208     */
209    @Override
210    public boolean equals( Object obj )
211    {
212        if ( obj == this )
213        {
214            return true;
215        }
216
217        if ( ( obj == null ) || !( obj instanceof ExtensibleNode ) )
218        {
219            return false;
220        }
221        ExtensibleNode that = ( ExtensibleNode ) obj;
222
223        if ( dnAttributes != that.dnAttributes )
224        {
225            return false;
226        }
227        if ( !matchingRuleId.equals( that.matchingRuleId ) )
228        {
229            return false;
230        }
231        if ( !value.equals( that.value ) )
232        {
233            return false;
234        }
235
236        return super.equals( obj );
237    }
238
239
240    /**
241     * @see Object#hashCode()
242     * @return the instance's hash code 
243     */
244    @Override
245    public int hashCode()
246    {
247        int h = 37;
248
249        h = h * 17 + super.hashCode();
250        h = h * 17 + ( dnAttributes ? 1 : 0 );
251        h = h * 17 + matchingRuleId.hashCode();
252        h = h * 17 + value.hashCode();
253
254        return h;
255    }
256
257
258    /**
259     * @see java.lang.Object#toString()
260     * @return A string representing the AndNode
261     */
262    @Override
263    public String toString()
264    {
265        StringBuilder buf = new StringBuilder();
266
267        buf.append( '(' );
268
269        if ( attributeType != null )
270        {
271            buf.append( attributeType.getName() );
272        }
273        else
274        {
275            buf.append( attribute );
276        }
277
278        buf.append( "-" );
279        buf.append( dnAttributes );
280        buf.append( "-EXTENSIBLE-" );
281        buf.append( matchingRuleId );
282        buf.append( "-" );
283        buf.append( value );
284
285        buf.append( super.toString() );
286
287        buf.append( ')' );
288
289        return buf.toString();
290    }
291}