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   *    http://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.server.core.subtree;
21  
22  
23  import org.apache.directory.server.core.entry.ServerAttribute;
24  import org.apache.directory.server.schema.registries.OidRegistry;
25  import org.apache.directory.shared.ldap.constants.SchemaConstants;
26  import org.apache.directory.shared.ldap.entry.EntryAttribute;
27  import org.apache.directory.shared.ldap.entry.client.ClientBinaryValue;
28  import org.apache.directory.shared.ldap.entry.client.ClientStringValue;
29  import org.apache.directory.shared.ldap.filter.EqualityNode;
30  import org.apache.directory.shared.ldap.filter.SimpleNode;
31  import org.apache.directory.shared.ldap.util.StringTools;
32  
33  import javax.naming.NamingException;
34  import java.util.Iterator;
35  
36  
37  /**
38   * A refinement leaf node evaluator.  This evaluator checks to see if the
39   * objectClass attribute of a candidate entry is matched by a leaf node in
40   * a refinement filter expression tree.
41   *
42   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
43   * @version $Rev: 655126 $
44   */
45  public class RefinementLeafEvaluator
46  {
47      /** an OID to name and vice versa registry */
48      private final OidRegistry registry;
49  
50  
51      /**
52       * Creates a refinement filter's leaf node evaluator.
53       *
54       * @param registry the OID registry used to lookup names for objectClass OIDs
55       */
56      public RefinementLeafEvaluator(OidRegistry registry)
57      {
58          this.registry = registry;
59      }
60  
61  
62      /**
63       * Evaluates whether or not a simple leaf node of a refinement filter selects an
64       * entry based on the entry's objectClass attribute values.
65       *
66       * @param node the leaf node of the refinement filter
67       * @param objectClasses the objectClass attribute's values
68       * @return true if the leaf node selects the entry based on objectClass values, false
69       * if it rejects the entry
70       * @throws NamingException
71       */
72      public boolean evaluate( SimpleNode node, EntryAttribute objectClasses ) throws NamingException
73      {
74          if ( node == null )
75          {
76              throw new IllegalArgumentException( "node cannot be null" );
77          }
78          
79          if ( !( node instanceof EqualityNode ) )
80          {
81              throw new NamingException( "Unrecognized assertion type for refinement node: " + node );
82          }
83          
84          if ( !node.getAttribute().equalsIgnoreCase( SchemaConstants.OBJECT_CLASS_AT ) )
85          {
86              throw new NamingException( "Refinement leaf node attribute was " + node.getAttribute() );
87          }
88  
89          if ( null == objectClasses )
90          {
91              throw new IllegalArgumentException( "objectClasses argument cannot be null" );
92          }
93          
94          if ( !((ServerAttribute)objectClasses).instanceOf( SchemaConstants.OBJECT_CLASS_AT ) )
95          {
96              throw new IllegalArgumentException( "objectClasses attribute must be for ID 'objectClass'" );
97          }
98  
99          // check if AVA value exists in attribute
100         if ( objectClasses.contains( node.getValue() ) )
101         {
102             return true;
103         }
104 
105         // If the filter value for the objectClass is an OID we need to resolve a name
106         String value = null;
107         if ( node.getValue() instanceof ClientStringValue )
108         {
109             value = ( String ) node.getValue().get();
110         }
111         else if ( node.getValue() instanceof ClientBinaryValue )
112         {
113             value = "#" + StringTools.toHexString( ( byte[] ) node.getValue().get() );
114         }
115         else
116         {
117             value = node.getValue().toString();
118         }
119         
120         if ( Character.isDigit( value.charAt( 0 ) ) )
121         {
122             Iterator<String> list = registry.getNameSet( value ).iterator();
123             
124             while ( list.hasNext() )
125             {
126                 String objectClass = ( String ) list.next();
127                 if ( objectClasses.contains( objectClass ) )
128                 {
129                     return true;
130                 }
131             }
132         }
133 
134         // no match so return false
135         return false;
136     }
137 }