View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    https://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.model.filter;
21  
22  
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.directory.api.i18n.I18n;
27  
28  
29  /**
30   * Abstract implementation of a expression node.
31   * 
32   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
33   */
34  public abstract class AbstractExprNode implements ExprNode
35  {
36      /** The map of annotations */
37      protected Map<String, Object> annotations;
38  
39      /** The node type */
40      protected final AssertionType assertionType;
41  
42  
43      /**
44       * Creates a node by setting abstract node type.
45       * 
46       * @param assertionType The node's type
47       */
48      protected AbstractExprNode( AssertionType assertionType )
49      {
50          this.assertionType = assertionType;
51      }
52  
53  
54      /**
55       * @see ExprNode#getAssertionType()
56       * 
57       * @return the node's type
58       */
59      @Override
60      public AssertionType getAssertionType()
61      {
62          return assertionType;
63      }
64  
65  
66      /**
67       * @see Object#equals(Object)
68       *@return <code>true</code> if both objects are equal 
69       */
70      @Override
71      public boolean equals( Object o )
72      {
73          // Shortcut for equals object
74          if ( this == o )
75          {
76              return true;
77          }
78  
79          if ( !( o instanceof AbstractExprNode ) )
80          {
81              return false;
82          }
83  
84          AbstractExprNode that = ( AbstractExprNode ) o;
85  
86          // Check the node type
87          if ( this.assertionType != that.assertionType )
88          {
89              return false;
90          }
91  
92          if ( annotations == null )
93          {
94              return that.annotations == null;
95          }
96          else if ( that.annotations == null )
97          {
98              return false;
99          }
100 
101         // Check all the annotation
102         for ( Map.Entry<String, Object> entry : annotations.entrySet() )
103         {
104             String key = entry.getKey();
105         
106             if ( !that.annotations.containsKey( key ) )
107             {
108                 return false;
109             }
110 
111             Object thisAnnotation = entry.getValue();
112             Object thatAnnotation = that.annotations.get( key );
113 
114             if ( thisAnnotation == null )
115             {
116                 if ( thatAnnotation != null )
117                 {
118                     return false;
119                 }
120             }
121             else
122             {
123                 if ( !thisAnnotation.equals( thatAnnotation ) )
124                 {
125                     return false;
126                 }
127             }
128         }
129 
130         return true;
131     }
132 
133 
134     /**
135      * @see Object#hashCode()
136      * @return the instance's hash code 
137      */
138     @Override
139     public int hashCode()
140     {
141         int h = 37;
142 
143         if ( annotations != null )
144         {
145             for ( Map.Entry<String, Object> entry : annotations.entrySet() )
146             {
147                 String key = entry.getKey();
148                 Object value = entry.getValue();
149 
150                 h = h * 17 + key.hashCode();
151                 h = h * 17 + ( value == null ? 0 : value.hashCode() );
152             }
153         }
154 
155         return h;
156     }
157 
158 
159     /**
160      * @see ExprNode#get(java.lang.Object)
161      * 
162      * @return the annotation value.
163      */
164     @Override
165     public Object get( Object key )
166     {
167         if ( null == annotations )
168         {
169             return null;
170         }
171 
172         return annotations.get( key );
173     }
174 
175 
176     /**
177      * @see ExprNode#set(String, Object)
178      */
179     @Override
180     public void set( String key, Object value )
181     {
182         if ( null == annotations )
183         {
184             annotations = new HashMap<>( 2 );
185         }
186 
187         annotations.put( key, value );
188     }
189 
190 
191     /**
192      * Gets the annotations as a Map.
193      * 
194      * @return the annotation map.
195      */
196     protected Map<String, Object> getAnnotations()
197     {
198         return annotations;
199     }
200 
201 
202     /**
203      * Default implementation for this method : just throw an exception.
204      * 
205      * @param buf the buffer to append to.
206      * @return The buffer in which the refinement has been appended
207      * @throws UnsupportedOperationException if this node isn't a part of a refinement.
208      */
209     @Override
210     public StringBuilder printRefinementToBuffer( StringBuilder buf )
211     {
212         throw new UnsupportedOperationException( I18n.err( I18n.ERR_13303_SCOPENODE_IN_REFINEMENT ) );
213     }
214 
215 
216     /**
217      * Clone the object
218      */
219     @Override
220     public ExprNode clone()
221     {
222         try
223         {
224             ExprNode clone = ( ExprNode ) super.clone();
225 
226             if ( annotations != null )
227             {
228                 for ( Map.Entry<String, Object> entry : annotations.entrySet() )
229                 {
230                     // Note : the value aren't cloned ! 
231                     ( ( AbstractExprNode ) clone ).annotations.put( entry.getKey(), entry.getValue() );
232                 }
233             }
234 
235             return clone;
236         }
237         catch ( CloneNotSupportedException cnse )
238         {
239             return null;
240         }
241     }
242 
243 
244     /**
245      * @see Object#toString()
246      */
247     @Override
248     public String toString()
249     {
250         if ( ( null != annotations ) && annotations.containsKey( "count" ) )
251         {
252             Long count = ( Long ) annotations.get( "count" );
253 
254             if ( count == Long.MAX_VALUE )
255             {
256                 return ":[\u221E]";
257             }
258 
259             return ":[" + count + "]";
260         }
261         else
262         {
263             return "";
264         }
265     }
266 }