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 */
020 package org.apache.directory.server.xdbm.search.impl;
021
022
023 import java.util.ArrayList;
024 import java.util.List;
025
026 import org.apache.directory.server.i18n.I18n;
027 import org.apache.directory.server.xdbm.Store;
028 import org.apache.directory.server.xdbm.search.Evaluator;
029 import org.apache.directory.shared.ldap.NotImplementedException;
030 import org.apache.directory.shared.ldap.entry.ServerEntry;
031 import org.apache.directory.shared.ldap.filter.AndNode;
032 import org.apache.directory.shared.ldap.filter.ApproximateNode;
033 import org.apache.directory.shared.ldap.filter.EqualityNode;
034 import org.apache.directory.shared.ldap.filter.ExprNode;
035 import org.apache.directory.shared.ldap.filter.GreaterEqNode;
036 import org.apache.directory.shared.ldap.filter.LessEqNode;
037 import org.apache.directory.shared.ldap.filter.NotNode;
038 import org.apache.directory.shared.ldap.filter.OrNode;
039 import org.apache.directory.shared.ldap.filter.PresenceNode;
040 import org.apache.directory.shared.ldap.filter.ScopeNode;
041 import org.apache.directory.shared.ldap.filter.SearchScope;
042 import org.apache.directory.shared.ldap.filter.SubstringNode;
043 import org.apache.directory.shared.ldap.schema.SchemaManager;
044
045
046 /**
047 * Top level filter expression evaluator builder implemenation.
048 *
049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
050 * @version $Rev: 927146 $
051 */
052 public class EvaluatorBuilder<ID>
053 {
054 private final Store<ServerEntry, ID> db;
055 private final SchemaManager schemaManager;
056
057
058 /**
059 * Creates a top level Evaluator where leaves are delegated to a leaf node
060 * evaluator which will be created.
061 *
062 * @param db the database this evaluator operates upon
063 * @param registries the schema registries
064 * @throws Exception failure to access db or lookup schema in registries
065 */
066 public EvaluatorBuilder( Store<ServerEntry, ID> db, SchemaManager schemaManager ) throws Exception
067 {
068 this.db = db;
069 this.schemaManager = schemaManager;
070 }
071
072
073 public <T> Evaluator<? extends ExprNode, ServerEntry, ID> build( ExprNode node ) throws Exception
074 {
075 switch ( node.getAssertionType() )
076 {
077 /* ---------- LEAF NODE HANDLING ---------- */
078
079 case APPROXIMATE:
080 return new ApproximateEvaluator<T, ID>( ( ApproximateNode<T> ) node, db, schemaManager );
081
082 case EQUALITY:
083 return new EqualityEvaluator<T, ID>( ( EqualityNode<T> ) node, db, schemaManager );
084
085 case GREATEREQ:
086 return new GreaterEqEvaluator<T, ID>( ( GreaterEqNode<T> ) node, db, schemaManager );
087
088 case LESSEQ:
089 return new LessEqEvaluator<T, ID>( ( LessEqNode<T> ) node, db, schemaManager );
090
091 case PRESENCE:
092 return new PresenceEvaluator<ID>( ( PresenceNode ) node, db, schemaManager );
093
094 case SCOPE:
095 if ( ( ( ScopeNode ) node ).getScope() == SearchScope.ONELEVEL )
096 {
097 return new OneLevelScopeEvaluator<ServerEntry, ID>( db, ( ScopeNode ) node );
098 }
099 else
100 {
101 return new SubtreeScopeEvaluator<ServerEntry, ID>( db, ( ScopeNode ) node );
102 }
103
104 case SUBSTRING:
105 return new SubstringEvaluator<ID>( ( SubstringNode ) node, db, schemaManager );
106
107 /* ---------- LOGICAL OPERATORS ---------- */
108
109 case AND:
110 return buildAndEvaluator( ( AndNode ) node );
111
112 case NOT:
113 return new NotEvaluator<ID>( ( NotNode ) node, build( ( ( NotNode ) node ).getFirstChild() ) );
114
115 case OR:
116 return buildOrEvaluator( ( OrNode ) node );
117
118 /* ---------- NOT IMPLEMENTED ---------- */
119
120 case ASSERTION:
121 case EXTENSIBLE:
122 throw new NotImplementedException();
123
124 default:
125 throw new IllegalStateException( I18n.err( I18n.ERR_260, node.getAssertionType() ) );
126 }
127 }
128
129
130 AndEvaluator<ID> buildAndEvaluator( AndNode node ) throws Exception
131 {
132 List<ExprNode> children = node.getChildren();
133 List<Evaluator<? extends ExprNode, ServerEntry, ID>> evaluators = new ArrayList<Evaluator<? extends ExprNode, ServerEntry, ID>>(
134 children.size() );
135 for ( ExprNode child : children )
136 {
137 evaluators.add( build( child ) );
138 }
139 return new AndEvaluator<ID>( node, evaluators );
140 }
141
142
143 OrEvaluator<ID> buildOrEvaluator( OrNode node ) throws Exception
144 {
145 List<ExprNode> children = node.getChildren();
146 List<Evaluator<? extends ExprNode, ServerEntry, ID>> evaluators = new ArrayList<Evaluator<? extends ExprNode, ServerEntry, ID>>(
147 children.size() );
148 for ( ExprNode child : children )
149 {
150 evaluators.add( build( child ) );
151 }
152 return new OrEvaluator<ID>( node, evaluators );
153 }
154 }