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.core.event;
021    
022    
023    import org.apache.directory.server.i18n.I18n;
024    import org.apache.directory.shared.ldap.entry.ServerEntry;
025    import org.apache.directory.shared.ldap.exception.LdapException;
026    import org.apache.directory.shared.ldap.exception.LdapInvalidSearchFilterException;
027    import org.apache.directory.shared.ldap.filter.AndNode;
028    import org.apache.directory.shared.ldap.filter.BranchNode;
029    import org.apache.directory.shared.ldap.filter.ExprNode;
030    import org.apache.directory.shared.ldap.filter.NotNode;
031    import org.apache.directory.shared.ldap.filter.OrNode;
032    import org.apache.directory.shared.ldap.schema.SchemaManager;
033    import org.apache.directory.shared.ldap.schema.registries.OidRegistry;
034    
035    
036    
037    /**
038     * Top level filter expression evaluator implemenation.
039     * 
040     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041     * @version $Rev: 927146 $
042     */
043    public class ExpressionEvaluator implements Evaluator
044    {
045        /** Leaf Evaluator flyweight use for leaf filter assertions */
046        private LeafEvaluator leafEvaluator;
047    
048    
049        // ------------------------------------------------------------------------
050        // C O N S T R U C T O R S
051        // ------------------------------------------------------------------------
052    
053        /**
054         * Creates a top level Evaluator where leaves are delegated to a leaf node
055         * evaluator which is already provided.
056         *
057         * @param leafEvaluator handles leaf node evaluation.
058         */
059        public ExpressionEvaluator( LeafEvaluator leafEvaluator )
060        {
061            this.leafEvaluator = leafEvaluator;
062        }
063    
064    
065        /**
066         * Creates a top level Evaluator where leaves are delegated to a leaf node
067         * evaluator which will be created.
068         *
069         * @param oidRegistry the oid reg used for attrID to oid resolution
070         * @param attributeTypeRegistry the attribtype reg used for value comparison
071         */
072        public ExpressionEvaluator( OidRegistry oidRegistry, SchemaManager schemaManager )
073        {
074            SubstringEvaluator substringEvaluator = null;
075            substringEvaluator = new SubstringEvaluator( schemaManager );
076            leafEvaluator = new LeafEvaluator( schemaManager, substringEvaluator );
077        }
078    
079    
080        /**
081         * Gets the leaf evaluator used by this top level expression evaluator.
082         *
083         * @return the leaf evaluator used by this top level expression evaluator
084         */
085        public LeafEvaluator getLeafEvaluator()
086        {
087            return leafEvaluator;
088        }
089    
090    
091        // ------------------------------------------------------------------------
092        // Evaluator.evaluate() implementation
093        // ------------------------------------------------------------------------
094    
095        /**
096         * @see Evaluator#evaluate(ExprNode, String, ServerEntry)
097         */
098        public boolean evaluate( ExprNode node, String dn, ServerEntry entry ) throws LdapException
099        {
100            if ( node.isLeaf() )
101            {
102                return leafEvaluator.evaluate( node, dn, entry );
103            }
104    
105            BranchNode bnode = ( BranchNode ) node;
106    
107            if ( bnode instanceof OrNode )
108            {
109                for ( ExprNode child: bnode.getChildren() )
110                {
111                    if ( evaluate( child, dn, entry ) )
112                    {
113                        return true;
114                    }
115                }
116    
117                return false;
118            }
119            else if ( bnode instanceof AndNode )
120            {
121                for ( ExprNode child: bnode.getChildren() )
122                {
123                    boolean res = evaluate( child, dn, entry );
124                    
125                    if ( !res )
126                    {
127                        return false;
128                    }
129                }
130    
131                return true;
132            }
133            else if ( bnode instanceof NotNode )
134            {
135                if ( null != bnode.getFirstChild() )
136                {
137                    return !evaluate( bnode.getFirstChild(), dn, entry );
138                }
139    
140                throw new LdapInvalidSearchFilterException( I18n.err( I18n.ERR_243, node ) );
141            }
142            else
143            {
144                    throw new LdapInvalidSearchFilterException( I18n.err( I18n.ERR_244, bnode ) );
145            }
146        }
147    }