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.xdbm.search.evaluator;
21  
22  
23  import java.util.Iterator;
24  
25  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
26  import org.apache.directory.api.ldap.model.entry.Attribute;
27  import org.apache.directory.api.ldap.model.entry.Entry;
28  import org.apache.directory.api.ldap.model.exception.LdapException;
29  import org.apache.directory.api.ldap.model.filter.PresenceNode;
30  import org.apache.directory.api.ldap.model.schema.AttributeType;
31  import org.apache.directory.api.ldap.model.schema.SchemaManager;
32  import org.apache.directory.server.core.api.partition.PartitionTxn;
33  import org.apache.directory.server.xdbm.IndexEntry;
34  import org.apache.directory.server.xdbm.Store;
35  import org.apache.directory.server.xdbm.search.Evaluator;
36  
37  
38  /**
39   * An Evaluator which determines if candidates are matched by GreaterEqNode
40   * assertions.
41   *
42   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
43   */
44  public class PresenceEvaluator implements Evaluator<PresenceNode>
45  {
46      /** The ExprNode to evaluate */
47      private final PresenceNode node;
48  
49      /** The backend */
50      private final Store db;
51  
52      /** The AttributeType we will use for the evaluation */
53      private final AttributeType attributeType;
54  
55      /** The SchemaManager instance */
56      private final SchemaManager schemaManager;
57  
58  
59      /**
60       * Creates a new PresenceEvaluator
61       * 
62       * @param node The PresenceNode
63       * @param db The Store
64       * @param schemaManager The SchemaManager
65       */
66      public PresenceEvaluator( PresenceNode node, Store db, SchemaManager schemaManager )
67      {
68          this.db = db;
69          this.node = node;
70          this.schemaManager = schemaManager;
71          this.attributeType = node.getAttributeType();
72      }
73  
74  
75      /**
76       * {@inheritDoc}
77       */
78      @Override
79      public PresenceNode getExpression()
80      {
81          return node;
82      }
83  
84  
85      /**
86       * @return the attributeType
87       */
88      public AttributeType getAttributeType()
89      {
90          return attributeType;
91      }
92  
93  
94      /**
95       * {@inheritDoc}
96       */
97      @Override
98      // TODO - determine if comparator and index entry should have the Value
99      // wrapper or the raw normalized value
100     public boolean evaluate( PartitionTxn partitionTxn, IndexEntry<?, String> indexEntry ) throws LdapException
101     {
102         Entry entry = indexEntry.getEntry();
103 
104         // resuscitate the entry if it has not been and set entry in IndexEntry
105         if ( null == entry )
106         {
107             entry = db.fetch( partitionTxn, indexEntry.getId() );
108 
109             if ( null == entry )
110             {
111                 // The entry is not anymore present : get out
112                 return false;
113             }
114 
115             indexEntry.setEntry( entry );
116         }
117 
118         return evaluate( entry );
119     }
120 
121 
122     /**
123      * {@inheritDoc}
124      */
125     @Override
126     // TODO - determine if comaparator and index entry should have the Value
127     // wrapper or the raw normalized value
128     public boolean evaluate( Entry entry ) throws LdapException
129     {
130         String attrOid = attributeType.getOid();
131 
132         if ( attrOid.equals( SchemaConstants.OBJECT_CLASS_AT_OID )
133             || attrOid.equals( SchemaConstants.ENTRY_CSN_AT_OID )
134             || attrOid.equals( SchemaConstants.ENTRY_UUID_AT_OID ) )
135         {
136             // we don't maintain a presence index for objectClass, entryUUID and entryCSN
137             // however as every entry has such an attribute this evaluator always evaluates to true
138             return true;
139         }
140 
141         // get the attribute
142         Attribute attr = entry.get( attributeType );
143 
144         // if the attribute exists just return true
145         if ( attr != null )
146         {
147             return true;
148         }
149 
150         // If we do not have the attribute, loop through the sub classes of
151         // the attributeType.  Perhaps the entry has an attribute value of a
152         // subtype (descendant) that will produce a match
153         if ( schemaManager.getAttributeTypeRegistry().hasDescendants( attributeType ) )
154         {
155             // TODO check to see if descendant handling is necessary for the
156             // index so we can match properly even when for example a name
157             // attribute is used instead of more specific commonName
158             Iterator<AttributeType> descendants = schemaManager.getAttributeTypeRegistry().descendants( attributeType );
159 
160             do
161             {
162                 AttributeType descendant = descendants.next();
163 
164                 attr = entry.get( descendant );
165 
166                 if ( attr != null )
167                 {
168                     return true;
169                 }
170             }
171             while ( descendants.hasNext() );
172         }
173 
174         // we fell through so a match was not found - assertion was false.
175         return false;
176     }
177 
178 
179     /**
180      * @see Object#toString()
181      */
182     public String toString( String tabs )
183     {
184         StringBuilder sb = new StringBuilder();
185 
186         sb.append( tabs ).append( "PresenceEvaluator : " ).append( node ).append( "\n" );
187 
188         return sb.toString();
189     }
190 
191 
192     /**
193      * @see Object#toString()
194      */
195     public String toString()
196     {
197         return toString( "" );
198     }
199 }