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